java - 自定义 JSpinner 模型不起作用

标签 java swing jspinner changelistener

我尝试实现自己的 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/

相关文章:

java - 如何删除ArrayList中的对象

java - 如何通过 Eclipse IDE 运行具有 Java 命令的脚本,以便我看到输出并与程序交互?

java - 在 JFrame MessageBox 中给出计算结果

java - 通过 SQL 查询在 JTree 中动态创建节点

java - 从 SPinnerDateModel 的 Jspinner 获取日期

java - 如何在 JSpinner 中使用 ChangeListener?

java - JSpinner 返回默认值而不是输入值

java - 如何使最简单的 servlet 过滤器尊重设置的字符编码

java - 无法在运行时设置复选框的背景颜色

java - Android 应用程序在手机上崩溃。