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