I'm working in Java, and I have a JPanel in a JFrame. In that JPanel, among other things, I have a JLabel that I want to make appear and disappear at will. I've tried setting visibility to true/false, adding and removing it from the JFrame and JPanel, and, having looked online, I tried validate()ing and revalidate()ing ad infinitum. What can be done here to solve this problem?

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

2 个解决方案

#1


In general, calling the setVisible method is sufficient to make a Swing component to be shown or hidden.

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

Just to be sure that it works, I tried the following:

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

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

The above program is able to affect the visibility by clicking on a JButton.

通过单击JButton,上述程序可以影响可见性。

Could it be a Threading Issue?

这可能是线程问题吗?

My next suspicion was that perhaps a Thread that is not on the event dispatch thread (EDT) may not be affecting the display immediately, so I added the following after initializing the JLabel and JButton.

我的下一个怀疑是,可能不在事件派发线程(EDT)上的线程可能不会立即影响显示,所以我在初始化JLabel和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();

With the new Thread running, it changed the toggled the visibility of the JLabel every 100 ms, and this also worked without a problem.

随着新的Thread运行,它改变了每100毫秒切换JLabel的可见性,这也没有问题。

Calling a Swing component off the event dispatch thread (EDT) is a bad thing, as Swing is not thread-safe. I was a little surprised it worked, and the fact that it works may just be a fluke.

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

Repaint the JPanel?

重绘JPanel?

If the JLabel's visibility is only being affected on resizing, it probably means that the JLabel is being drawn only when the JPanel is being repainted.

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

One thing to try is to call the JPanel's repaint method to see if the visibility of the JLabel will change.

要尝试的一件事是调用JPanel的重绘方法来查看JLabel的可见性是否会发生变化。

But this method seems to be just a band-aid to a situation, if the main cause is due to a thread off the EDT is attempting to make changes to the GUI. (Just as a note, the repaint method is thread-safe, so it can be called by off-EDT threads, but relying on repaint is a workaround than a solution.)

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

Try using SwingUtilities.invokeLater

尝试使用SwingUtilities.invokeLater

Finally, probably the thing I would try is the SwingUtilities.invokeLater method, which can be called (and should only be called) from a thread running separate from the EDT, if it wants to affect the GUI.

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

So, the earlier Thread example should be written as:

所以,早期的Thread示例应该写成:

Thread t = new Thread(new Runnable() {
  public void run() {
    while (true) {
      try {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            b.setVisible(!b.isVisible());
          }
        });
      } catch (Exception e1) { /* Handle exception */ }

      try  {
        Thread.sleep(100);
      } catch (InterruptedException e) { /* Handle exception */ }
    }
  }
});

t.start();

If the change to the GUI is indeed occurring on a separate thread, then I would recommend reading Lesson: Concurrency in Swing from The Java Tutorials in order to find out more information on how to write well-behaving multi-threaded code using Swing.

如果对GUI的更改确实发生在单独的线程上,那么我建议阅读Lesson:Swing中的并发来自Java教程,以便找到有关如何使用Swing编写良好的多线程代码的更多信息。

更多相关文章

  1. Java Executor多线程框架
  2. “不是抽象的,也不重写抽象的方法”错误
  3. Android高手进阶教程(二十)之---Android与JavaScript方法相互调
  4. java线程--volatile实现可见性
  5. 手低眼高 初学者学习Hibernate的方法
  6. Java常用类及其常用方法
  7. 本地方法中printf如何传给java--java系统级命名管道
  8. Maven:主线程中的NoClassDefFoundError
  9. java线程池使用场景和使用方法较详细文摘

随机推荐

  1. Android中 ToggleButton【状态切换按钮】
  2. Android(安卓)开发四大天王 四大组件 (很
  3. Android UI之TextView实现跑马灯效果
  4. 第16天android:看android的书籍
  5. FAQ_15_android Imageview ImageButton B
  6. [Android] ExpandableListView 子目录点
  7. android shape用法
  8. Android内存管理机制
  9. Android 4.0.3 CTS 测试
  10. android系统工具之 draw9patch超详细教程