2

在 a 中显示一系列带符号的 HexBinary 数字的最佳方法是JSpinner什么?

例如从0x80000x7ffe

我尝试了以下解决方案,但运气不佳:

  1. 使用JSpinnerNumberModel带有默认格式化程序的 a 从 int 转换为 Hexbinary。[无法显示范围的负数部分]
  2. 使用 aJSpinnerListModel并将其传递给该范围内的 HexBinary 值的构造列表(带有不必要代码的人为解决方案。不能完美运行)。

有没有更好的通用解决方案?

4

1 回答 1

4

我......认为可能有一种方法可以在不构建整个范围的实际列表的情况下做到这一点。

一种方法是扩展AbstractSpinnerModel创建一个LongNumberModel,如下所示。另请参阅此相关示例

六角微调器测试图像

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.text.ParseException;
import javax.swing.AbstractSpinnerModel;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;

/**
 * @see https://stackoverflow.com/a/13121724/230513
 * @see https://stackoverflow.com/a/9758714/230513
 */
public class HexSpinnerTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                display();
            }
        });
    }

    private static void display() throws HeadlessException {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JSpinner sp = new JSpinner(new LongNumberModel(0x8000L, 0x8000L, 0xFFFFL, 1L));
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) sp.getEditor();
        JFormattedTextField tf = editor.getTextField();
        tf.setFormatterFactory(new MyFormatterFactory());
        f.getContentPane().add(sp, BorderLayout.NORTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static class LongNumberModel extends AbstractSpinnerModel {

        private Long value, stepSize;
        private Comparable<Long> minimum, maximum;

        public LongNumberModel(Long value, Long minimum, Long maximum, Long stepSize) {
            this.value = value;
            this.minimum = minimum;
            this.maximum = maximum;
            this.stepSize = stepSize;
        }

        @Override
        public Object getValue() {
            return value;
        }

        @Override
        public void setValue(Object value) {
            this.value = (Long) value;
            fireStateChanged();
        }

        @Override
        public Object getNextValue() {
            long v = value.longValue() + stepSize.longValue();
            return bounded(v);
        }

        @Override
        public Object getPreviousValue() {
            long v = value.longValue() - stepSize.longValue();
            return bounded(v);
        }

        private Object bounded(long v) {
            if ((maximum != null) && (maximum.compareTo(v) < 0)) {
                return null;
            }
            if ((minimum != null) && (minimum.compareTo(v) > 0)) {
                return null;
            }
            return Long.valueOf(v);
        }
    }

    private static class MyFormatterFactory extends DefaultFormatterFactory {

        @Override
        public AbstractFormatter getDefaultFormatter() {
            return new HexFormatter();
        }
    }

    private static class HexFormatter extends DefaultFormatter {

        @Override
        public Object stringToValue(String text) throws ParseException {
            try {
                return Long.valueOf(text, 16);
            } catch (NumberFormatException nfe) {
                throw new ParseException(text, 0);
            }
        }

        @Override
        public String valueToString(Object value) throws ParseException {
            return Long.toHexString(
                ((Long) value).intValue()).toUpperCase();
        }
    }
}
于 2012-10-29T12:33:29.983 回答