(Java)出现/消失JPanel中的JLabel仅在调整大小时消失

时间:2009-06-03 03:04:42

标签: java resize jframe jpanel repaint

我在Java工作,我在JFrame中有一个JPanel。在那个JPanel中,除其他外,我有一个JLabel,我想让它出现并随意消失。我已经尝试将可见性设置为true / false,在JFrame和JPanel中添加和删除它,并且在线查看后,我尝试了验证()和无效地重新生成()无限广告。在这里可以做些什么来解决这个问题?

2 个答案:

答案 0 :(得分:7)

通常,调用setVisible方法足以使Swing组件显示或隐藏。

为了确保它有效,我尝试了以下方法:

public class Visibility {
  private void makeGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JLabel l = new JLabel("Hello");
    final JButton b = new JButton("Hide Label");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        l.setVisible(false);
      }
    });

    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(l, BorderLayout.CENTER);
    f.getContentPane().add(b, BorderLayout.SOUTH);
    f.setSize(200, 200);
    f.setLocation(200, 200);
    f.validate();
    f.setVisible(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Visibility().makeGUI();
      }
    }); 
  }
}

上述程序可以通过点击JButton来影响可见性。

可能是线程问题吗?

我的下一个怀疑是,event dispatch thread (EDT)上没有的Thread可能不会立即影响显示,所以我在初始化JLabel和{{1}后添加了以下内容}}

JButton

新的Thread t = new Thread(new Runnable() { public void run() { while (true) { b.setVisible(!b.isVisible()); try { Thread.sleep(100); } catch (InterruptedException e) { /* Handle exception /* } } } }); t.start(); 正在运行,它每隔100毫秒更改了Thread的可见性,这也没有问题。

event dispatch thread (EDT)调用Swing组件是一件坏事,因为Swing不是线程安全的。我觉得它有点惊讶,而且它的工作原理可能只是一个侥幸

重新绘制JLabel

如果JPanel的可见度仅在调整大小时受到影响,则可能意味着仅在重新绘制JLabel时才会绘制JLabel

要尝试的一件事是调用JPanel的{​​{3}}方法来查看JPanel的可见性是否会发生变化。

但是这种方法似乎只是一种情况的创可贴,如果主要原因是由于EDT的一个线程试图对GUI进行更改。 (正如注意,JLabel方法是线程安全的,因此它可以由非EDT线程调用,但依赖repaint是一种解决方法而不是解决方案。)

尝试使用repaint

最后,我可能尝试的是repaint方法,如果它想影响GUI,可以从与EDT分开运行的线程调用(并且只应该调用)。

因此,早期的SwingUtilities.invokeLater示例应写为:

Thread

如果对GUI的更改确实发生在单独的线程上,那么我建议从SwingUtilities.invokeLater阅读Lesson: Concurrency in Swing,以便找到有关如何编写良好的多线程的更多信息代码使用Swing。

答案 1 :(得分:2)

setVisible()或删除它应该工作正常,但请确保您从事件派发线程执行此操作。 EventQueue中有一些实用程序方法用于在该线程中运行块。

http://helpdesk.objects.com.au/java/how-do-i-update-my-gui-from-any-thread

如果需要重新布局其组件,则需要在父JPanel上调用revalidate()。

如果您可以发布一个演示问题的示例,我可以为您查看。