所以我遇到了一个特殊的问题。
我的界面只是一个标签和一个JSlider。
我的代码(已剥离):
import javax.swing.*;
import java.awt.*;
public class Broken {
JLabel value = new JLabel();
JSlider slider = new JSlider(0, 255, 0);
public Broken() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new Broken();
}
}
标签没有显示的情况会发生什么。如果我将屏幕从右侧调整到尽可能小的尺寸,突然显示文本,如果我重新调整它的大小,它将保持在那里。我不知道发生了什么,这对我来说真的好像是个错误。
调整屏幕截图之前和之后:
答案 0 :(得分:2)
尽管您付出了努力,但在您创建JLabel(或JSlider)时,您还没有EventDispatchThread
。为了测试,我将JLabel子类化,看看代码是否在EDT上调用它的构造函数时:
import java.awt.*;
import javax.swing.*;
public class Broken {
JLabel value = new XLabel(); // called before constructor, so not on EDT
JSlider slider = new JSlider(0, 255, 0); // same here
public Broken() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new Broken();
}
class XLabel extends JLabel {
public XLabel() {
super();
System.out.println("EDT? " + SwingUtilities.isEventDispatchThread());
}
}
}
要修复,请将invokeLater
调用放在main中,以便将整个类的结构包装到EDT中:
import java.awt.*;
import javax.swing.*;
public class Broken2 {
JLabel value = new JLabel();
JSlider slider = new JSlider(0, 255, 0);
public Broken2() {
JPanel panel = new JPanel();
value.setText("Some Value");
panel.add(value);
JFrame frame = new JFrame("Frame Name2");
frame.setLayout(new GridLayout(2, 1));
frame.add(panel);
frame.add(slider);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Generally the proper way. Create Whole app on EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Broken2();
}
});
}
}