Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在执行某个按钮的操作期间移除该按钮_Java_Swing - Fatal编程技术网

Java 在执行某个按钮的操作期间移除该按钮

Java 在执行某个按钮的操作期间移除该按钮,java,swing,Java,Swing,我试图找出我的程序冻结的原因,我能够用一个小脚本复制它,这样我就可以把它放在这里。基本上,在这个脚本中,当您单击按钮Test1时,应该将其删除并添加新的按钮Test2。程序冻结。为什么?我怎么能过来 final JFrame frame = new JFrame("FrameDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferred

我试图找出我的程序冻结的原因,我能够用一个小脚本复制它,这样我就可以把它放在这里。基本上,在这个脚本中,当您单击按钮Test1时,应该将其删除并添加新的按钮Test2。程序冻结。为什么?我怎么能过来

final JFrame frame = new JFrame("FrameDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setPreferredSize(new Dimension(800, 600));

                final JPanel panel = new JPanel();
                final JButton bTest1 = new JButton("test1");
                bTest1.addActionListener(new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent e) {
                      panel.remove(bTest1);
                      panel.add(new JButton("test2"));
                    }

                });
                panel.add(bTest1);
                frame.getContentPane().add(panel);

                frame.pack();
                frame.setVisible(true);
当然,在实际程序中,单击按钮,删除面板的所有内容并重新添加一组新组件

期待你的帮助

当然,在实际程序中,单击按钮,删除面板的所有内容并重新添加一组新组件

那么您可能应该使用
卡片布局
CardLayout
设计用于交换面板

有关更多信息和工作示例,请阅读上Swing教程的部分

程序冻结。为什么?我怎么能过来

final JFrame frame = new JFrame("FrameDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setPreferredSize(new Dimension(800, 600));

                final JPanel panel = new JPanel();
                final JButton bTest1 = new JButton("test1");
                bTest1.addActionListener(new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent e) {
                      panel.remove(bTest1);
                      panel.add(new JButton("test2"));
                    }

                });
                panel.add(bTest1);
                frame.getContentPane().add(panel);

                frame.pack();
                frame.setVisible(true);
它没有冻结,只是面板不够聪明,无法重新喷漆。如果调整框架的大小,您将看到新按钮

问题是您删除了按钮并添加了一个新按钮,但是面板从不重新绘制自己,因为面板不知道这些更改。您需要调用布局管理器,以便为新按钮指定适当的大小

在可见GUI上添加/删除组件的基本代码是:

panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint(); // sometimes needed
当然,在实际程序中,单击按钮,删除面板的所有内容并重新添加一组新组件

那么您可能应该使用
卡片布局
CardLayout
设计用于交换面板

有关更多信息和工作示例,请阅读上Swing教程的部分

程序冻结。为什么?我怎么能过来

final JFrame frame = new JFrame("FrameDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setPreferredSize(new Dimension(800, 600));

                final JPanel panel = new JPanel();
                final JButton bTest1 = new JButton("test1");
                bTest1.addActionListener(new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent e) {
                      panel.remove(bTest1);
                      panel.add(new JButton("test2"));
                    }

                });
                panel.add(bTest1);
                frame.getContentPane().add(panel);

                frame.pack();
                frame.setVisible(true);
它没有冻结,只是面板不够聪明,无法重新喷漆。如果调整框架的大小,您将看到新按钮

问题是您删除了按钮并添加了一个新按钮,但是面板从不重新绘制自己,因为面板不知道这些更改。您需要调用布局管理器,以便为新按钮指定适当的大小

在可见GUI上添加/删除组件的基本代码是:

panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint(); // sometimes needed

JButton的操作执行方法将在AWT线程中执行。当您从容器中移除按钮时,将启动应该在同一线程中执行的事件。所以一个在等待另一个,所以程序冻结。为了解决这种情况,请使用

SwingUtilities.invokeLater


方法来执行按钮的删除操作,JButton的操作执行方法将在AWT线程中执行。当您从容器中移除按钮时,将启动应该在同一线程中执行的事件。所以一个在等待另一个,所以程序冻结。为了解决这种情况,请使用

SwingUtilities.invokeLater


方法执行按钮的删除操作

当您向可见面板添加新组件(或删除组件)时,需要重新验证面板:
panel.revalidate()
。但是,使用CardLayout是您应该做的。当您向可见面板添加新组件(或删除组件)时,您需要重新验证面板:
panel.revalidate()
。然而,使用卡片布局是你应该做的。很有趣。嗯,谢谢你的解释。卡片布局不是我的选择,因为我不仅仅是交换。我没有把这么多细节放在不让人困惑的地方。但是,重新验证(和调整大小)已修复。我仍然不确定的是,即使我有一个面板,后来我添加了按钮,它仍然会显示(并且知道变化)。为什么在执行删除/添加操作时它不知道?当您单击按钮时,按钮被绘制为“按下”状态。释放鼠标时,将调用ActionListener,并从面板中移除按钮。这就是所发生的一切。面板本身不重新绘制(),因此其背景不会被清除,因此按下按钮的图像将保留。从配电盘中添加或删除零部件不会导致重新绘制配电盘。假设您将添加/删除多个组件。应用程序负责告知专家组其已完成更改。您可以使用revalidate()方法处理此问题。但假设您向面板添加了一个按钮,该按钮被添加到框架中。将其设置为“不可见”,然后删除按钮。面板似乎意识到了这一点,因为按钮实际上已被移除。为什么只有当您在操作过程中删除侦听器时,它才知道?我感到困惑的是,当您更改组件的属性时,如果面板在action Listener之外,为什么它有时会重新验证新添加的内容revalidate()和repaint()会自动在组件上调用。因此,导致事情发生的是setVisible()方法,而不是移除按钮。谢谢。这是有道理的。但在上面的代码中,我添加了panel.add(newjbutton(“test3”);在frame.setVisible(true)之后,它显示了新按钮。它是怎么知道的?很有趣。嗯,谢谢你的解释。卡片布局不是我的选择,因为我不仅仅是交换。我没有把这么多细节放在不让人困惑的地方。但是,重新验证(和调整大小)已修复。我仍然不确定的是,即使我有一个面板,后来我添加了按钮,它仍然会显示(并且知道变化)。为什么在执行删除/添加操作时它不知道?当您单击按钮时,按钮被绘制为“按下”状态。释放鼠标时,将调用ActionListener,并从面板中移除按钮。这就是所发生的一切。面板本身不重新绘制(),因此其背景不会被清除,因此按下按钮的图像将保留。从配电盘中添加或删除零部件不会导致重新绘制配电盘。这个