gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 07:00:05 24 4
gpt4 key购买 nike

我正在使用 Java,并且 JFrame 中有一个 JPanel。在该 JPanel 中,除其他外,我有一个 JLabel,我想让它随意出现和消失。我尝试将可见性设置为 true/false,在 JFrame 和 JPanel 中添加和删除它,并且在网上查看后,我尝试了无限次的 validate() 和 revalidate() 。这里可以做什么来解决这个问题?

最佳答案

一般来说,调用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)上可能不会立即影响显示,因此我在初始化 JLabelJButton 后添加了以下内容。

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

随着新的Thread运行,它每100毫秒更改一次JLabel的可见性,并且这也没有问题。

event dispatch thread (EDT) 调用 Swing 组件这是一件坏事,因为 Swing 不是线程安全的。我有点惊讶它能起作用,它起作用的事实可能只是侥幸

重新绘制JPanel

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

要尝试的一件事是调用 JPanelrepaint方法来查看 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();

如果 GUI 的更改确实发生在单独的线程上,那么我建议阅读 Lesson: Concurrency in Swing来自The Java Tutorials了解有关如何使用 Swing 编写性能良好的多线程代码的更多信息。

关于java - (Java) JPanel 中出现/消失的 JLabel 仅在调整大小时消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/942883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com