我尝试实现自己的 JSpinner
模型来接受 枚举
(包括 I18N
),所以我确实这样做了:
searchSpinner.setModel(new AbstractSpinnerModel() {
int index = 0;
int minIndex = 0;
int maxIndex = MY_ENUM.values().length - 1;
Object selected = MY_ENUM.values()[index];
@Override
public Object getValue() {
return selected;
}
@Override
public void setValue(Object value) {
selected = value;
fireStateChanged();
}
@Override
public Object getNextValue() {
if (index < maxIndex) {
index++;
}
fireStateChanged();
return MY_ENUM.values()[index];
}
@Override
public Object getPreviousValue() {
if (index > minIndex) {
index--;
}
fireStateChanged();
return MY_ENUM.values()[index];
}
@Override
public void addChangeListener(ChangeListener l) {
}
@Override
public void removeChangeListener(ChangeListener l) {
}
});
问题是不起作用,甚至微调器列表看起来也像禁用。我做错了什么?
更新:基于第一个答案
最佳答案
您应该从 AbstractSpinnerModel 开始扩展(对于刚接触他的问题的人请注意 - 请注意他最初的问题有实现 SpinnerModel 接口(interface)的类。他后来更改了代码以反射(reflect)我的建议)并确保调用 fireStateChanged()
方法当适当的时候。此外,您还没有考虑边缘情况和超出边缘情况的情况。
例如,
import javax.swing.*;
import javax.swing.JSpinner.DefaultEditor;
public class MySpinnerPanel extends JPanel {
public static void main(String[] args) {
JSpinner spinner = new JSpinner(new MyEnumSpinnerModel());
JSpinner.DefaultEditor editor = (DefaultEditor) spinner.getEditor();
editor.getTextField().setColumns(5);
JPanel panel = new JPanel();
panel.add(spinner);
JOptionPane.showMessageDialog(null, panel);
}
}
enum MyEnum {
FE, FI, FO, FUM, FOO, FUBAR, SPAM
}
class MyEnumSpinnerModel extends AbstractSpinnerModel {
private int index = 0;
@Override
public Object getValue() {
return MyEnum.values()[index];
}
@Override
public void setValue(Object value) {
if (value instanceof MyEnum) {
index = ((MyEnum) value).ordinal();
fireStateChanged();
} else {
String text = value.toString() + " is not a valid enum item";
throw new IllegalArgumentException(text);
}
}
@Override
public Object getNextValue() {
if (index >= MyEnum.values().length - 1) {
return null;
} else {
return MyEnum.values()[index + 1];
}
}
@Override
public Object getPreviousValue() {
if (index <= 0) {
return null;
} else {
return MyEnum.values()[index - 1 ];
}
}
}
编辑
请注意,模型本身不应该需要监听器来通知 View (根据此问题的其他答案),因为这就是 AbstractSpinnerModel 内部所做的事情。它的 fireStateChange()
方法是模型本身应该调用的方法来触发此通知,与 Swing 中的大多数其他类似模型结构(例如您创建的派生自 AbstractTableModel 的任何 TableModel 对象)相同。详情请看SpinnerListModel源码。您的代码应该模拟此类。
关于java - 自定义 JSpinner 模型不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30438173/