(Java)出现/消失JPanel中的JLabel仅在调整大小时消失
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编写良好的多线程代码的更多信息。
更多相关文章
- Java Executor多线程框架
- “不是抽象的,也不重写抽象的方法”错误
- Android高手进阶教程(二十)之---Android与JavaScript方法相互调
- java线程--volatile实现可见性
- 手低眼高 初学者学习Hibernate的方法
- Java常用类及其常用方法
- 本地方法中printf如何传给java--java系统级命名管道
- Maven:主线程中的NoClassDefFoundError
- java线程池使用场景和使用方法较详细文摘