JSpinner: Menampilkan rentang nilai HexBinary yang ditandatangani

Apa cara terbaik untuk menampilkan rentang nomor HexBinary yang ditandatangani dalam JSpinner?

misalnya dari 0x8000 hingga 0x7ffe

Saya telah mencoba solusi berikut, tetapi tidak berhasil:

  1. Gunakan JSpinnerNumberModel dengan formatter default untuk mengonversi dari int ke Hexbinary.[Tidak dapat menampilkan bagian negatif dari rentang]
  2. Gunakan JSpinnerListModel dan berikan daftar nilai HexBinary yang dibuat yang termasuk dalam kisaran tersebut (solusi yang dibuat dengan kode yang tidak perlu. tidak berfungsi dengan sempurna).

Apakah ada solusi yang lebih baik dan umum?


person schinoy    schedule 29.10.2012    source sumber
comment
kemungkinan duplikat Beberapa petunjuk untuk hex Jspinner? Saya pendekatannya benar   -  person trashgod    schedule 29.10.2012
comment
Saya mencoba pendekatan seperti yang dijelaskan di atas dalam solusi percobaan no. 1. Tautan di atas hanya menyelesaikan masalah pemformatan ke hex dan tidak dapat menampilkan nilai negatif. Saya menghadapi masalah yang berbeda, yang melibatkan memulai JSpinner pada representasi hexBinary negatif dan bergulir ke atas hingga batas positif atas.   -  person schinoy    schedule 29.10.2012
comment
Saya akhirnya berhasil menyelesaikan tugas tersebut dengan menggunakan JSpinnerListModel, dan meneruskannya daftar string nilai hexbiner dalam rentang, yang dibuat oleh kelas utilitas. Tentu saja, saya tidak menyukai solusi ini, dan menurut saya mungkin ada cara untuk melakukannya tanpa membuat daftar sebenarnya dari keseluruhan rentang.   -  person schinoy    schedule 29.10.2012


Jawaban (1)


Saya… pikir mungkin ada cara untuk melakukannya tanpa membuat daftar sebenarnya dari keseluruhan rentang.

Salah satu pendekatannya adalah dengan memperluas AbstractSpinnerModel untuk membuat LongNumberModel, seperti yang ditunjukkan di bawah ini. Lihat juga contoh terkait ini.

Gambar Uji Hex Spinner

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();
        }
    }
}
person trashgod    schedule 29.10.2012
comment
Anda tidak perlu membuat subkelas DefaultFormatterFactory. Cukup gunakan metode setDefaultFormatter dari formatterFactory bidang teks untuk mengatur instance HexFormatter sebagai default. - person phobic; 02.08.2014