我对Java编程很新,特别是就GUI而言。
我正在尝试创建一个类似于“不要踩在白色瓷砖上”的游戏,为此我需要4行,每行有4个矩形,其中一个是黑色的。为此,我创建了一个JPanel的子类(称为MyImagePanel),其中我已经覆盖了paintComponent方法。这种类型的对象表示4行中的一行。我的想法是将4个类型为MyImagePanel的obbject添加到Box中,并为每个对象注册一个mouseListener。如果用户点击底行中的黑色图块,则顶部应显示一个新行,而底部一行应该消失(就好像用户正在向前走)。否则用户输了(目前,这只会打印出“丢失”的消息)。
然而,实际发生的是在顶部生成一个新行,底部的行只是消失,而不是被替换。我不明白为什么会这样。
这是Test类的代码:
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();
}
}
答案 0 :(得分:2)
由于布局正在发生变化,您必须(重新)验证并可能重新绘制封闭的mainPanel
。此相关example中的动作侦听器替换了可能已移动的所有组件。
private void createPane() {
this.removeAll();
for (JLabel label : list) add(label);
this.validate();
}
相比之下,此example会更新每个按钮的图标。
private void update() {
Collections.shuffle(list);
int index = 0;
for (JToggleButton b : buttons) {
b.setIcon(list.get(index++));
}
}
更灵活的方法是使用如here所示的MVC模式。每次更新模型时,监听视图都会自动更新。您可以更新组件,而不是替换组件,例如通过改变它的颜色。