我对Java编程相当陌生,尤其是在GUI方面。
我正在尝试创建一个类似于"不要踩白色瓷砖"的游戏,为此我需要4行,每行有4个矩形,其中一个是黑色的。为此,我创建了JPanel的一个子类(称为MyImagePanel),在其中我覆盖了方法paintComponent。这种类型的对象表示4个对象中的一行。我的想法是将MyImagePanel类型的4个对象添加到一个Box中,并向每个对象注册一个mouseListener。如果用户单击底部一行的黑色平铺,则顶部会出现一个新行,底部一行会消失(就好像用户在向前走一样)。否则用户会丢失(目前,这只会打印出一条带有"丢失"的消息)。
然而,实际发生的情况是,在顶部生成一个新行,而底部的行只是消失了,而没有被替换。我不明白为什么会发生这种情况。
这是测试类的代码:
public class Test {
ArrayList<MyImagePanel> rows;
JFrame frame;
Box mainPanel;
public Test(){
rows=new ArrayList<MyImagePanel>();
mainPanel=new Box(BoxLayout.Y_AXIS);
}
public void go(){
frame=new JFrame();
for(int i=0;i<4;i++){
MyImagePanel panel=createPanel();
rows.add(panel);
mainPanel.add(panel);
}
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(240, 440);
frame.setResizable(false);
frame.setVisible(true);
}
class MyMouseListener extends MouseAdapter{
public void mouseClicked(MouseEvent ev){
int x=ev.getX();
System.out.println("X coord "+x);
MyImagePanel panel=(MyImagePanel)ev.getComponent();
Color c=panel.getColor(x);
if(panel.equals(rows.get(3)) && c.equals(Color.BLACK)){
System.out.println("Ok");
rows.remove(3);
rows.add(0,createPanel());
System.out.println("List length "+rows.size());
mainPanel.remove(3);
mainPanel.add(rows.get(0), 0);
System.out.println("Components in box "+mainPanel.getComponentCount());
mainPanel.repaint();
}
else{
System.out.println("Lose");
}
}
}
private MyImagePanel createPanel(){
MyImagePanel panel=new MyImagePanel();
panel.setSize(240,100);
panel.addMouseListener(new MyMouseListener());
return panel;
}
public static void main(String[] args){
Test t=new Test();
t.go();
}
}
由于布局正在更改,您将不得不(重新)验证并可能重新绘制封闭的mainPanel
。此相关示例中的动作侦听器将替换可能已移动的所有组件。
private void createPane() {
this.removeAll();
for (JLabel label : list) add(label);
this.validate();
}
与此相反,此示例会在适当的位置更新每个按钮的图标。
private void update() {
Collections.shuffle(list);
int index = 0;
for (JToggleButton b : buttons) {
b.setIcon(list.get(index++));
}
}
一种更灵活的方法是使用MVC模式,如下所示。每次更新模型时,侦听视图都会相应地更新自己。您不是替换组件,而是更新组件,例如更改其颜色。