【问题标题】:jgoodies binding: using a JTextField with a formatted number?jgoodies 绑定:使用带有格式化数字的 JTextField?
【发布时间】:2010-12-30 11:44:04
【问题描述】:

我正在尝试使用 JGoodies Binding 将 JTextField 绑定到 double 的 bean 字段:

JTextField myJTextField = ...
BeanAdapter adapter = ...
Bindings.bind(myJTextField,
ConverterFactory.createStringConverter(adapter.getValueModel("amplitude"),
                    new DecimalFormat("0.00000")));

至少在 bean → JTextField 方向上有效。在 JTextField → bean 方向,它有一个问题:如果我开始在 JTextField 中输入,它会在小数点后的第一个数字后立即更新,弄乱 JTextField 焦点,并调整我的 JTextField 值。

(问题似乎来自于尝试将 GUI 的 String 调整为模型的 double

我该如何解决这个问题????

演示此的示例程序:

package com.example.test.gui;

import java.awt.GridLayout;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.util.Hashtable;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.beans.BeanAdapter;
import com.jgoodies.binding.beans.ExtendedPropertyChangeSupport;
import com.jgoodies.binding.value.ConverterFactory;

public class FloatPointBinding {
    public static class MyModel {
        private int x;

        final private ExtendedPropertyChangeSupport changeSupport = 
            new ExtendedPropertyChangeSupport(this);

        public void addPropertyChangeListener(PropertyChangeListener x) {
            this.changeSupport.addPropertyChangeListener(x);
        }

        public void removePropertyChangeListener(PropertyChangeListener x) {
            this.changeSupport.removePropertyChangeListener(x);
        }

        static private int clip(int a)
        {
            return Math.min(Math.max(a, -32768), 32767);
        }
        static private int d2i(double a) {
            return clip((int) Math.floor(a*32768 + 0.5));
        }
        static private double i2d(int a) {
            return (clip(a)/32768.0);
        }

        public void setXCount(int x) {
            int oldX = this.x;
            int newX = x;
            this.x=newX; 
            this.changeSupport.firePropertyChange("x", i2d(oldX), i2d(newX));
            this.changeSupport.firePropertyChange("XCount", oldX, newX);
        }
        public void setX(double x) { setXCount(d2i(x)); }
        public double getX() { return i2d(this.x); }
        public int getXCount() { return this.x; }

    }

    public static class MyView extends JFrame
    {
        public MyView(MyModel model, String title)
        {
            super(title);
            JTextField jtf = new JTextField();
            JSlider jsl = new JSlider();

            jsl.setMinimum(-32768);
            jsl.setMaximum(32767);
            jsl.setMajorTickSpacing(4096);
            jsl.setPaintTicks(true);

            Hashtable labelTable = new Hashtable();
            labelTable.put( new Integer( -32768 ), new JLabel("-1") );
            labelTable.put( new Integer( 0 ), new JLabel("0") );
            labelTable.put( new Integer( 32767 ), new JLabel("1") );
            jsl.setLabelTable( labelTable );
            jsl.setPaintLabels(true);


            setLayout(new GridLayout());
            add(jsl);
            add(jtf);

            BeanAdapter adapter = new BeanAdapter(model, true);
            Bindings.bind(jtf, 
                    ConverterFactory.createStringConverter(adapter.getValueModel("x"),
                            new DecimalFormat("0.#####")));
            jsl.setModel(new BoundedRangeAdapter(adapter.getValueModel("XCount"), 0, -32768, 32767));
        }
    }

    public static void main(String[] args)
    {
        MyModel model = new MyModel();
        MyView view = new MyView(model, "FloatPointBinding");
        view.pack();
        view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        view.setVisible(true);
    }
}

【问题讨论】:

    标签: swing binding jtextfield jgoodies


    【解决方案1】:

    我不确定这是否是您要解决的问题,但是如果您将绑定更改为仅在焦点丢失时提交,您就不应该再遇到这个问题了。只需将 true 指定为以下 bind 方法的第三个参数:

    Bindings.bind(jtf, 
                  ConverterFactory.createStringConverter(adapter.getValueModel("x"),
                            new DecimalFormat("0.#####")),
                  true);
    

    【讨论】:

    • 哦——好吧,我不知道你能做到这一点。它不如即时更新好,但更可靠+可能是处理它的正确方法。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    相关资源
    最近更新 更多