通常,调用该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();
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
上述程序可以通过单击a来影响可见性JButton.
它可能是线程问题吗?
我的下一个怀疑的是,也许Thread这不是在事件调度线程(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();
Run Code Online (Sandbox Code Playgroud)
随着新的Thread运行,它改变了切换JLabel每100毫秒的可见性,这也没有问题.
从事件调度线程(EDT)调用Swing组件是一件坏事,因为Swing不是线程安全的.我有点意外的工作,它的工作原理可能只是一个侥幸.
重绘JPanel?
如果JLabel仅在调整大小时影响可见性,则可能意味着JLabel仅在JPanel重新绘制时才绘制.
有一件事是尝试调用JPanel的repaint方法,看看的能见度JLabel会有所改变.
但是这种方法似乎只是一种情况的创可贴,如果主要原因是由于EDT的一个线程试图对GUI进行更改.(正如请注意,该repaint方法是线程安全的,因此可以通过非EDT线程调用,但依赖于repaint解决方法而不是解决方案.)
尝试使用 SwingUtilities.invokeLater
最后,我可能会尝试的是SwingUtilities.invokeLater方法,如果它想影响GUI,可以从与EDT分开运行的线程调用(并且只应该调用).
所以,前面的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();
Run Code Online (Sandbox Code Playgroud)
如果对GUI的更改确实发生在单独的线程上,那么我建议阅读Lesson:Swing中的并发来自Java教程,以便找到有关如何使用Swing编写良好的多线程代码的更多信息.