Java p> 好的,为什么我不想在paintComponent中设置JLabel的文本
Java p> 好的,为什么我不想在paintComponent中设置JLabel的文本,java,swing,paintcomponent,Java,Swing,Paintcomponent,paintComponent方法仅用于绘制和绘制。不应使用它来设置程序或组件的状态,原因有几个,包括您无法完全控制何时或是否调用此方法(如您所发现的),因此代码的状态不应取决于其被调用 我应该如何让JLabel在调用repaint时更新 同样,您不应该使用重新绘制来触发此操作。JLabel应该显示什么?为什么你觉得它必须在重新油漆时改变 编辑2 我以为这是个好地方。“我的显示器”由许多嵌套组件组成,这些组件的标签和背景不断变化。我应该从主处理循环中检索组件并在那里设置值,而不是使用paintC
paintComponent
方法仅用于绘制和绘制。不应使用它来设置程序或组件的状态,原因有几个,包括您无法完全控制何时或是否调用此方法(如您所发现的),因此代码的状态不应取决于其被调用
我应该如何让JLabel在调用repaint时更新
同样,您不应该使用重新绘制来触发此操作。JLabel应该显示什么?为什么你觉得它必须在重新油漆时改变
编辑2 我以为这是个好地方。“我的显示器”由许多嵌套组件组成,这些组件的标签和背景不断变化。我应该从主处理循环中检索组件并在那里设置值,而不是使用paintComponent吗 不,不允许外部类像这样直接操纵视图。相反,将您的模型和视图分开,并使用诸如PropertyChangeListener之类的侦听器以及公共方法来为您执行此操作 例如,通过将TestObject的值字段设置为“绑定属性”,可以轻松地更新JLabel文本。这可以通过给类一个PropertyChangeSupport对象(实际上,因为这是Swing,一个SwingPropertyChangeSupport对象)并允许外部类监听值的更改来轻松实现,如下所示:
class DisplayJPanel extends javax.swing.JPanel {
private TestObject to = null;
public DisplayJPanel() {
initComponents();
}
public TestObject getTo() {
return to;
}
public void setTo(final TestObject to) {
this.to = to;
// add listener to listen and react to changes in to value's state
to.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (TestObject.VALUE.equals(evt.getPropertyName())) {
setLabel2Text(String.valueOf(to.getValue()));
}
}
});
}
private void initComponents() {
// etc...
}
public void setLabel2Text(String text) {
jLabel2.setText(text);
}
private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
}
class TestObject {
public static final String VALUE = "value";
private int value = 0;
private SwingPropertyChangeSupport propChangeSupport = new SwingPropertyChangeSupport(this);
public int getValue() {
return value;
}
public void setValue(int value) {
int oldValue = this.value;
int newValue = value;
this.value = newValue;
propChangeSupport.firePropertyChange(VALUE, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.removePropertyChangeListener(listener);
}
}
请澄清——您到底希望这段代码做什么,它没有做什么?也是不相关的问题,但
super.paintComponents(g)
不是paintComponent(g)
方法的超级选项。这是paintComponents的结尾,它会把你搞得一团糟。我的主要问题是,如果我删除jLabel1,那么paintComponent永远不会被调用。你几乎永远不会强烈建议删除“几乎”并注释以下几行;-)好的,为什么我不想在paintComponent中设置JLabel的文本?每当调用“重新绘制”时,我应该如何使JLabel更新?@充满鳗鱼的气垫船:我想显示一个在我的主程序中不断更新的值,以及更改背景颜色的值。@充满鳗鱼的气垫船:我以为是在paintComponent中进行此操作的。“我的显示器”由许多嵌套组件组成,这些组件的标签和背景不断变化。我应该从我的主处理循环中检索组件并在那里设置值,而不是使用paintComponent吗?@user2408629:请参见编辑2来回答。
for (int i = 10; i < 20; i++) {
to.setValue(i);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(DisplayJFrame.class.getName()).log(
Level.SEVERE, null, ex);
}
df.draw();
}
public void run() {
final DisplayJFrame df = new DisplayJFrame();
df.setVisible(true);
final TestObject to = new TestObject();
df.setTO(to);
int timerDelay = 100;
final int maxCount = 20;
new Timer(timerDelay, new ActionListener() {
private int count = 0;
@Override
public void actionPerformed(ActionEvent evt) {
if (count < maxCount) {
df.repaint();
to.setValue(count);
count++;
} else {
((Timer) evt.getSource()).stop();
}
}
}).start();
// for (int i = 10; i < 20; i++) {
// to.setValue(i);
// try {
// Thread.sleep(100);
// } catch (InterruptedException ex) {
// Logger.getLogger(DisplayJFrame.class.getName()).log(
// Level.SEVERE, null, ex);
// }
//
// df.draw();
// }
}
// TODO: delete this method
public void paintComponent(Graphics g) {
System.out.println("paintComponent");
// super.paintComponents(g); // *** !! No -- this is not the super method ***
super.paintComponent(g);
if (to != null) {
int i = to.getValue();
System.out.println("paintComponent " + i);
// of course you'll never set a JLabel's text from within this method
jLabel1.setText(String.valueOf(i));
jLabel2.setText(String.valueOf(i + 1));
}
}
class DisplayJPanel extends javax.swing.JPanel {
private TestObject to = null;
public DisplayJPanel() {
initComponents();
}
public TestObject getTo() {
return to;
}
public void setTo(final TestObject to) {
this.to = to;
// add listener to listen and react to changes in to value's state
to.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (TestObject.VALUE.equals(evt.getPropertyName())) {
setLabel2Text(String.valueOf(to.getValue()));
}
}
});
}
private void initComponents() {
// etc...
}
public void setLabel2Text(String text) {
jLabel2.setText(text);
}
private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
}
class TestObject {
public static final String VALUE = "value";
private int value = 0;
private SwingPropertyChangeSupport propChangeSupport = new SwingPropertyChangeSupport(this);
public int getValue() {
return value;
}
public void setValue(int value) {
int oldValue = this.value;
int newValue = value;
this.value = newValue;
propChangeSupport.firePropertyChange(VALUE, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.removePropertyChangeListener(listener);
}
}