JSpinner: แสดงช่วงของค่า HexBinary ที่ลงชื่อ

วิธีที่ดีที่สุดในการแสดงช่วงของตัวเลข HexBinary ที่ลงนามใน JSpinner คืออะไร

เช่น. จาก 0x8000 ถึง 0x7ffe

ฉันได้ลองวิธีแก้ไขปัญหาต่อไปนี้แล้ว แต่ไม่มีโชคมากนัก:

  1. ใช้ JSpinnerNumberModel กับฟอร์แมตเตอร์เริ่มต้นเพื่อแปลงจาก int เป็นเลขฐานสิบหก[ไม่สามารถแสดงส่วนลบของช่วงได้]
  2. ใช้ JSpinnerListModel และส่งรายการที่สร้างขึ้นของค่า HexBinary ที่อยู่ในช่วง (โซลูชันที่คิดค้นขึ้นพร้อมโค้ดที่ไม่จำเป็น ทำงานไม่สมบูรณ์)

มีวิธีแก้ไขปัญหาทั่วไปที่ดีกว่านี้หรือไม่?


person schinoy    schedule 29.10.2012    source แหล่งที่มา
comment
เป็นไปได้ที่ซ้ำกันของ คำแนะนำบางประการสำหรับ hex Jspinner ? แนวทางของฉันถูกต้อง   -  person trashgod    schedule 29.10.2012
comment
ฉันลองใช้วิธีการตามรายละเอียดข้างต้นในโซลูชันการทดลองใช้หมายเลข 1. ลิงก์ด้านบนจะแก้ปัญหาเฉพาะการจัดรูปแบบให้เป็นเลขฐานสิบหกเท่านั้น และไม่สามารถแสดงค่าลบได้ ฉันกำลังเผชิญกับปัญหาอื่น ซึ่งเกี่ยวข้องกับการเริ่มต้น JSpinner ที่การแสดง hexBinary ที่เป็นลบ และกลิ้งขึ้นไปจนถึงขีดจำกัดบวกบน   -  person schinoy    schedule 29.10.2012
comment
ในที่สุดฉันก็สามารถจัดการงานให้สำเร็จได้โดยใช้ JSpinnerListModel และส่งรายการสตริงเลขฐานสิบหกของค่าในช่วงที่สร้างขึ้นโดยคลาสยูทิลิตี้ แน่นอน ฉันไม่ชอบวิธีแก้ปัญหานี้ และคิดว่าอาจมีวิธีดำเนินการได้โดยไม่ต้องสร้างรายการจริงของช่วงทั้งหมด   -  person schinoy    schedule 29.10.2012


คำตอบ (1)


ฉัน … คิดว่าอาจมีวิธีที่จะทำได้โดยไม่ต้องสร้างรายการที่แท้จริงของช่วงทั้งหมด

วิธีหนึ่งคือขยาย AbstractSpinnerModel เพื่อสร้าง LongNumberModel ดังที่แสดงด้านล่าง ดูตัวอย่างที่เกี่ยวข้องนี้ด้วย

รูปภาพทดสอบ 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
คุณไม่จำเป็นต้องซับคลาส DefaultFormatterFactory แม้ว่า เพียงใช้เมธอด setDefaultFormatter ของ formatterFactory ของฟิลด์ข้อความเพื่อตั้งค่าอินสแตนซ์ HexFormatter เป็นค่าเริ่มต้น - person phobic; 02.08.2014