现在我有一个程序可以左右移动一个矩形。我想制作一个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改变形状,我需要在CanvasDrawArea类(内部类)中为JComboBox放置ActionListener。但是如果我这样做,我就无法在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
这是我当前的Rectangle Class
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
课程相同。但是当我运行应用程序时,只显示矩形并且不再能够移动。
答案 0 :(得分:4)
CanvasDrawArea
以允许其接受此“形状”的不同实例并重新绘制。JComboBox
并将其放在与CanvasDrawArea
相同的容器中,但不在其中。当用户更改选择时,告诉CanvasDrawArea
的实例相应地更改形状... 核心概念是,CanvasDrawArea
负责绘制形状,就是这样。您可以通过一系列设置器和吸气剂来改变形状,这提供了灵活性,但不会将您绑定到给定的机制中(因此仅通过触发{{1}来改变形状}),但允许您更改形状更改机制的工作方式(例如通过随机选择,单选按钮或列表)
例如......
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
是一个非常糟糕的主意。这将安排另一个重绘,这可能导致重绘管理器重复重新绘制您的组件,消耗您的CPU。相反,你应该事先设置这个值,也许在构造函数中...... 首先定义“形状”的概念并定义它的要求,例如......
setBackground(CANVAS_BACKGROUND);
创建实际的实现,例如......
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());
}
}
,这意味着当您创建更多形状时,将更容易整合它们
答案 1 :(得分:0)
现在,您似乎只是在绘制和移动整个画布而不是移动形状。为了从矩形更改形状,您需要将形状放入画布中。此时,您可以通过交换不同的形状实例来更改形状。
使用工厂模式,只需传入一个字符串即可获得新形状的实例:http://www.oodesign.com/factory-pattern.html
然后您还需要跟踪当前的形状"对象,因为实例将发生变化。这将需要代理模式将移动和颜色更改操作委派给:http://java.dzone.com/articles/design-patterns-proxy
答案 2 :(得分:0)
首先,它取决于您是希望它自动更改形状还是动作发生时。如果它为该位置自动设置了一个TimerTask循环并将一个var作为x或y并添加到它
int xLoc = 0
然后 xLoc = xLoc + 1;
要更改图形中的颜色,请使用int color = 1;如果它是1设置为绿色,如果它是2蓝色等,则有if语句。进行此更新的方法是在TimerTask中重新绘制()
Timer timer = new Timer();