触发事件时,面板从Box中消失

时间:2014-09-08 16:02:21

标签: java swing user-interface event-handling jpanel

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

}

1 个答案:

答案 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模式。每次更新模型时,监听视图都会自动更新。您可以更新组件,而不是替换组件,例如通过改变它的颜色。

相关问题