我想听一下JSpinner的SpinnerNumberModel值的变化 我创建了一个PropertyChangeSupport并将模型放入其中。
我需要propertyChangeListener,因为它显示了属性的旧值和新值。
该代码段不起作用:当我点击JSpinner时,propertyChange
方法不打印任何内容。
一个简单的ChangeListener只提供新值,但我还需要旧值,我该怎么做呢?
package de.unikassel.jung;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
public class PropertyChangeTest implements PropertyChangeListener {
public static void main(String[] args) {
new PropertyChangeTest();
}
public PropertyChangeTest() {
JFrame frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int value = 1;
int min = 0;
int max = 10;
int step = 1;
SpinnerNumberModel spinnerModel = new SpinnerNumberModel(value, min, max, step);
PropertyChangeSupport pcs = new PropertyChangeSupport(spinnerModel);
pcs.addPropertyChangeListener("value", this);
JSpinner spinner = new JSpinner(spinnerModel);
frame.getContentPane().add(spinner);
frame.setVisible(true);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt);
System.out.println(evt.getSource());
}
}
答案 0 :(得分:6)
不要听模型,而是听取编辑的JFormattedTextField
,如下所示。
JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 0, 10, 1));
JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) spinner.getEditor();
editor.getTextField().addPropertyChangeListener("value", this);
答案 1 :(得分:5)
星期一早上......不反对几条评论的经典时间: - )
@timaschew
@Hovercraft
@trashgod
哈哈 - 你已经猜到我不喜欢解决方案:它打破了封装,因为它依赖于实现细节,所以不要除了完全控制JSpinner创建并且绝对确定它的编辑器永远不会改变
答案 2 :(得分:4)
要使PropertyChangeSupport工作,您需要调用其firePropertyChange
方法,但更重要的是,支持对象需要访问它正在侦听的属性的setXXX方法,并且在该方法中它需要调用PropertyChangeSupport的firePropertyChange方法。所以我认为你的想法可以工作,你需要扩展模型的类,给它一个PropertyChangeSupport对象,给它添加和删除监听器方法,并确保听取模型的setValue方法所做的更改,这是键。在我的示例中,该方法如下所示:
@Override
public void setValue(Object newValue) {
// store old value and set the new one
Object oldValue = getValue();
super.setValue(newValue);
// construct the event object using these saved values
PropertyChangeEvent evt = new PropertyChangeEvent(this, VALUE, oldValue,
newValue);
// notify all of the listeners
pcs.firePropertyChange(evt);
}
这是我使用PropertyChangeSupport的示例模型类:
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
@SuppressWarnings("serial")
class MySpinnerNumberModel extends SpinnerNumberModel {
public static final String VALUE = "value";
private SwingPropertyChangeSupport pcs = new SwingPropertyChangeSupport(this);
// you will likely need to create multiple constructors to match
// the ones available to the SpinnerNumberModel class
public MySpinnerNumberModel(int value, int min, int max, int step) {
super(value, min, max, step);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
@Override
public void setValue(Object newValue) {
// store old value and set the new one
Object oldValue = getValue();
super.setValue(newValue);
// construct the event object using these saved values
PropertyChangeEvent evt = new PropertyChangeEvent(this, VALUE, oldValue,
newValue);
// notify all of the listeners
pcs.firePropertyChange(evt);
}
}
最后测试类测试上面的类,看它是否正常工作:
import java.beans.*;
import javax.swing.*;
public class TestSpinnerPropChange {
private static void createAndShowUI() {
final MySpinnerNumberModel myModel = new MySpinnerNumberModel(1, 0, 10, 1);
final JSpinner spinner = new JSpinner(myModel);
final JTextField oldValueField = new JTextField(10);
final JTextField newValueField = new JTextField(10);
JPanel panel = new JPanel();
panel.add(spinner);
panel.add(new JLabel("old value:"));
panel.add(oldValueField);
panel.add(new JLabel("new value:"));
panel.add(newValueField);
myModel.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
// checking the property name is overkill here, but is a good habit
// to get into, especially if listening to more than one property.
if (evt.getPropertyName().equals(MySpinnerNumberModel.VALUE)) {
oldValueField.setText(evt.getOldValue().toString());
newValueField.setText(evt.getNewValue().toString());
}
}
});
JFrame frame = new JFrame("TestSpinnerPropChange");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
答案 3 :(得分:1)
http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html#bound 你必须在setter中激活ThePropertyChange。