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

标签 java swing user-interface event-handling jpanel

我对 Java 编程相当陌生,尤其是就 GUI 而言。

我正在尝试创建一个类似于“不要踩到白色瓷砖”的游戏,为此我需要 4 行,每行有 4 个矩形,其中一个是黑色的。为此,我创建了 JPanel 的子类(称为 MyImagePanel),在其中重写了 PaintComponent 方法。这种类型的对象代表 4 行中的一行。我的想法是将 4 个 MyImagePanel 类型的对象添加到 Box 中,并为每个对象注册一个 mouseListener。如果用户单击底行中的黑色图 block ,则顶部应出现一个新行,而底部行应消失(就像用户向前迈出一样)。否则用户就输了(目前,这只打印出一 strip 有“Lose”的消息)。

然而,实际发生的情况是,顶部生成了一个新行,而底部的行只是消失,没有被替换。我不明白为什么会发生这种情况。

这是测试类的代码:

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。这个相关的 Action 监听器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++));
    }
}

更灵活的方法是使用 MVC 模式,如下所示 here 。每次更新模型时,监听 View 都会自行更新作为响应。您无需替换组件,而是更新就地组件,例如通过改变它的颜色。

关于java - 触发事件时面板从 Box 中消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25728363/

相关文章:

java - JUnit 测试无法从另一个模块类中读取属性文件

java - 多个 Swing 工作器,用于具有各种按钮的应用

java - UIManager 和 JCheckBox 图标

java - 获取AsyncTask的结果而不阻塞线程

java - SWT ExpandListener 在 Linux 上发生崩溃之前执行

Java 相当于 python 的 getattr?

java - 如何获取屏幕的宽度和高度-Android

java - 如何在第二个 Activity 的 Texview 中显示来自 Mainactivity 的变量

java - JButton 上的 ActionPerformed 调用不止一次?

java - GUI/ActionListener 问题