Java JComboBox更改形状和颜色

Java JComboBox更改形状和颜色,java,swing,jcombobox,Java,Swing,Jcombobox,现在我有一个程序可以左右移动一个矩形。我想制作一个JComboBox来更改对象的形状和颜色 public class DrawShapes extends JFrame{ //code private CanvasDrawArea canvas; // the custom drawing canvas (extends JPanel) /** Constructor to set up the GUI */ public DrawShapes() { /

现在我有一个程序可以左右移动一个矩形。我想制作一个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。那么,我该如何改变正在移动的对象的形状和颜色呢

是写这个问题的完整代码,以防有人想看

编辑: 这是我当前的按钮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());
}

我的
圆形
类与我的
矩形
类相同。但当我运行应用程序时,只会显示矩形,无法再移动。

现在,你似乎只是在绘制和移动整个画布,而不是移动形状。为了改变矩形的形状,你需要在画布上放置一个形状。此时,可以通过在不同形状实例中交换来更改形状

使用factory模式,只需传入字符串即可获得新形状的实例:


然后还需要跟踪“当前形状”对象,因为实例将发生更改。这将需要代理模式将移动和颜色更改操作委托给:

现在看起来您只是在绘制和移动整个画布,而不是移动形状。为了改变矩形的形状,你需要在画布上放置一个形状。此时,可以通过在不同形状实例中交换来更改形状

使用factory模式,只需传入字符串即可获得新形状的实例:

然后还需要跟踪“当前形状”对象,因为实例将发生更改。这将需要代理模式将移动和颜色更改操作委托给:

  • 首先创建一个“形状”的概念,它知道如何在指定的位置用指定的颜色自行绘制
  • 更改您的
    CanvasDrawArea
    以允许它接受此“形状”的不同实例并重新绘制自身
  • 创建您的
    JComboBox
    ,并将其放置在与
    CanvasDrawArea
    相同的容器中,但不在其中。当用户更改选择时,请告诉
    CanvasDrawArea
    的实例相应地更改形状
核心概念是,
CanvasDrawArea
负责绘制形状,就是这样。通过一系列setter和getter,您可以通过某种方式更改形状,这提供了灵活性,但不会将您束缚在给定的机制中(因此,更改形状的唯一方法是触发
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);
        }
    }
}
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());
    }

}
  • 不要从任何
    paint
    方法中更新组件(或任何其他组件)的状态,例如;
    setBackground(CANVAS\u BACKGROUND);
    这是一个非常糟糕的主意。这将安排另一次重新绘制,这可能会导致重新绘制管理器重复重新绘制组件,消耗您的CPU。相反,您应该事先在构造函数中设置此值
首先定义“形状”的概念并定义其要求,例如

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);
        }
    }
}
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());
    }

}
创建实际的实现,例如

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);
        }
    }
}
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());
    }

}
在可能的情况下,始终处理
界面
,这意味着当您创建更多形状时,将更容易集成它们

  • 首先创建一个“形状”的概念,它知道如何在指定的位置用指定的颜色自行绘制
  • 更改您的
    CanvasDrawArea
    以允许它接受此“形状”的不同实例并重新绘制自身
  • 创建您的
    JComboBox
    并将其放置在与
    CanvasDrawArea
    相同的容器中,但不在其中。当用户更改选择时,请告诉
    CanvasDrawArea
    的实例相应地更改形状
核心概念是,
CanvasDrawArea
负责绘制形状,就是这样。通过一系列setter和getter,您可以通过某种方式更改形状,这提供了灵活性,但不会将您束缚在给定的机制中(因此,更改形状的唯一方法是触发
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);
        }
    }
}
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());
    }

}
  • 不要从任何
    paint
    方法中更新组件(或任何其他组件)的状态,例如;
    setBackground(CANVAS\u BACKGROUND);
    这是一个非常糟糕的主意。这将安排另一次重新绘制,这可能会导致重新绘制管理器重复重新绘制组件,消耗您的CPU。相反,您应该事先在构造函数中设置此值
首先定义“形状”的概念并定义其要求,例如

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);
        }
    }
}
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());
    }

}
创建实际的实现,例如

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);
        }
    }
}
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());
    }

}

在可能的情况下,始终处理
界面
,这意味着当您创建更多形状时,将更容易集成它们

首先,这取决于您是否希望它自动更改形状或何时发生动作。如果位置自动,则设置TimerTask循环,并将var作为