现在我有一个可以左右移动矩形的程序。我想制作一个 JComboBox 来更改对象的形状和颜色。
public class DrawShapes extends JFrame{
//code
private CanvasDrawArea canvas; // the custom drawing canvas (extends JPanel)
/** Constructor to set up the GUI */
public DrawShapes() {
// Panel for JComboBox and buttons
JPanel btnPanel = new JPanel(new FlowLayout());
JComboBox shapes = new JComboBox(shapeName);
btnPanel.add(shapes);
//code for left/right buttons
}
}
上面是包含所有内容的类以及设置 GUI 的构造函数。我还有一个创建形状的内部类
class CanvasDrawArea extends JPanel {
public void paintComponent(Graphics rect) {
super.paintComponent(rect);
setBackground(CANVAS_BACKGROUND);
rect.setColor(Color.BLUE);
rect.fillRect(x1, y1, rectWidth, rectHeight); //these int are defined earlier
}
}
我想如果我想用 JComboBox 改变形状,我需要将 JComboBox 的 ActionListener 放在 CanvasDrawArea 类(内部类)中。但如果我这样做,我无法在 btnPanel 中添加形状 JComboBox。那么我该如何改变正在移动的对象的形状和颜色呢?
Here是撰写此问题时的完整代码,以防有人想查看它。
编辑: 这是我当前的按钮 JPanel。我只复制了组合框的代码。
JPanel btnPanel = new JPanel(new FlowLayout());
JComboBox shapes = new JComboBox(shapeName);
shapes.setSelectedIndex(1);
btnPanel.add(shapes);
shapes.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox)e.getSource(); //copies shapes combo box
String msg = (String)cb.getSelectedItem();
switch(msg){
case "Rectangle":
Rectangle blueRect = new Rectangle(x1, y1, rectWidth, rectHeight, blue);
canvas.add(blueRect);
repaint();
case "Circle":
Circle blueCirc = new Circle(x2, y2, circWidth, circHeight, blue);
canvas.add(blueCirc);
repaint();
}//switch end
}//method end
}); //action listener end
这是我当前的矩形类
public Rectangle(int x, int y, int width, int height, Color color) {
setLocation(x, y);
setSize(width, height);
setColor(color);
}
@Override
public void paint(Graphics g) {
g.setColor(getColor());
g.fillRect(getX(), getY(), getWidth(), getHeight());
}
我的Circle
类与我的Rectangle
类相同。但是当我运行该应用程序时,只显示矩形并且无法再移动。
最佳答案
- 首先创建一个“形状”的概念,它知道如何在指定位置并使用指定颜色自行绘制
- 更改您的
CanvasDrawArea
允许它接受这个“形状”的不同实例并重新绘制自己。 - 创建您的
JComboBox
并将其放在与CanvasDrawArea
相同的容器中,但不在其中。当用户更改选择时,告诉CanvasDrawArea
的实例相应地改变形状...
核心概念是CanvasDrawArea
负责绘制形状,仅此而已。您允许通过某种方式(通过一系列 setter 和 getter)更改形状,这提供了灵 active ,但不会将您束缚在给定的机制中(因此改变形状的唯一方法是触发 ActionEvent
) ,但允许您更改形状更改机制的工作方式(例如通过随机选择、单选按钮或列表)
例如...
class CanvasDrawArea extends JPanel {
//...
private MyShape shape;
//..
public void setShape(MyShape shape) {
this.shape = shape;
repaint();
}
public MyShape getShape() {
return shape;
}
//...
public void paintComponent(Graphics rect) {
super.paintComponent(rect);
MyShape shape = getShape();
if (shape != null) {
shape.paint(rect);
}
}
}
- 请勿从任何
paint
内更新组件(或任何其他组件)的状态方法,例如;setBackground(CANVAS_BACKGROUND);
这是一个非常糟糕的主意。这将安排另一次重绘,这可能会导致重绘管理器重复重绘您的组件,从而消耗您的 CPU。相反,您应该事先设置此值,也许在构造函数中...
首先定义“形状”的概念并定义它的要求,例如......
public interface MyShape {
public void setLocation(int x, int y);
public void setSize(int width, int height);
public void setColor(Color color);
public int getX();
public int getY();
public int getWidth();
public int getHeight();
public Color getColor();
public void paint(Graphics g);
}
创建实际的实现,例如......
public abstract class AbstractShape implements MyShape {
private int x, y;
private int width, height;
private Color color;
@Override
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public void setColor(Color color) {
this.color = color;
}
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return y;
}
@Override
public Color getColor() {
return color;
}
}
public class Rectangle extends AbstractShape {
public Rectangle() {
}
public Rectangle(int x, int y, int width, int height, Color color) {
setLocation(x, y);
setSize(width, height);
setColor(color);
}
@Override
public void paint(Graphics g) {
g.setColor(getColor());
g.drawRect(getX(), getY(), getWidth(), getHeight());
}
}
如果可能,请始终处理 interface
,这意味着当您创建更多形状时,将更容易集成它们
关于java - JComboBox 改变形状和颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25373449/