最近 我问 这是绑定到 BigDecimal 变量的最佳 Swing 组件(具有一些特定的编辑属性)。事实证明,没有一个标准 Swing 组件完全适合我,我在那里找到的第三方 Swing 组件库也不适合。所以我决定创建我自己的 Swing 组件。

组件说明:

我想延长 文本字段 或者 JFormattedTextField, ,所以我的新组件可以轻松绑定到 大十进制 多变的。

该组件将具有可定制的 规模长度 特性。

行为:

绘制组件时,只显示小数点和空格 规模 其右侧的数字。

当组件获得焦点时,插入符号应位于小数点左侧。当用户键入数字时(任何其他字符都会被忽略),它们只会出现在插入符号的左侧 长度规模 接受数字,输入的任何其他数字都将被忽略,因为整数部分已满。每当用户键入小数点时,插入符号都会移动到小数点的右侧。以下输入的数字只显示小数部分 规模 数字被视为输入的任何其他数字都将被忽略,因为小数部分已满。此外,当用户键入小数点后的数字时,应显示千位分隔符。

我还希望能够将该组件用作 单元格编辑器 在一个 J表 (无需编码两次)。

在组件上调用 getValue() 方法应生成表示刚刚输入的数字的 BigDecimal。


我从未创建过自己的 Swing 组件;我几乎没用过标准的。因此,我将不胜感激有关创建所描述组件的任何好的教程/信息/提示。 这是我迄今为止唯一拥有的东西。

提前致谢。

有帮助吗?

解决方案

我喜欢 格鲁奇尼科夫 您引用的文章,但我不确定您是否想要更改 UI 委托。由于这将是一个不可变对象的视图,因此我更喜欢组合而不是继承。我倾向于认为你所描述的组件是 渲染器, ,正如在此看到的 例子. 。您可以添加一个 InputVerifier 或者 DocumwntListener 以获得您想要的验证。

附录:这是一个使用的示例 JFormattedTextField 和一个 MaskFormatter. 。您需要调整格式掩码以匹配您的比例和长度。

public class TableGrid extends JPanel {

    private DecimalFormat df;
    private MaskFormatter mf;
    private JFormattedTextField tf;

    public TableGrid() {
        df = new DecimalFormat("0.00");
        try {
            mf = new MaskFormatter("#.##");
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        tf = new JFormattedTextField(mf);
        TableModel dataModel = new TableModel();
        JTable table = new JTable(dataModel);
        table.setCellSelectionEnabled(true);
        table.setRowHeight(32);
        table.setDefaultRenderer(BigDecimal.class, new DecRenderer(df));
        table.setDefaultEditor(BigDecimal.class, new DecEditor(tf, df));
        this.add(table);
    }

    private static class TableModel extends AbstractTableModel {

        private static final int SIZE = 4;
        private BigDecimal[][] matrix = new BigDecimal[SIZE][SIZE];

        public TableModel() {
            for (Object[] row : matrix) {
                Arrays.fill(row, BigDecimal.valueOf(0));
            }
        }

        @Override
        public int getRowCount() {
            return SIZE;
        }

        @Override
        public int getColumnCount() {
            return SIZE;
        }

        @Override
        public Object getValueAt(int row, int col) {
            return matrix[row][col];
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            matrix[row][col] = (BigDecimal) value;
        }

        @Override
        public Class<?> getColumnClass(int col) {
            return BigDecimal.class;
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            return true;
        }
    }

    private static class DecRenderer extends DefaultTableCellRenderer {

        DecimalFormat df;

        public DecRenderer(DecimalFormat df) {
            this.df = df;
            this.setHorizontalAlignment(JLabel.CENTER);
            this.setBackground(Color.lightGray);
            this.df.setParseBigDecimal(true);
        }

        @Override
        protected void setValue(Object value) {
            setText((value == null) ? "" : df.format(value));
        }
    }

    private static class DecEditor extends DefaultCellEditor {

        private JFormattedTextField tf;
        private DecimalFormat df;

        public DecEditor(JFormattedTextField tf, DecimalFormat df) {
            super(tf);
            this.tf = tf;
            this.df = df;
            tf.setHorizontalAlignment(JFormattedTextField.CENTER);
        }

        @Override
        public Object getCellEditorValue() {
            try {
                return new BigDecimal(tf.getText());
            } catch (NumberFormatException e) {
                return BigDecimal.valueOf(0);
            }
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
            Object value, boolean isSelected, int row, int column) {
            tf.setText((value == null) ? "" : df.format((BigDecimal) value));
            if (isSelected) tf.selectAll();
            return tf;
        }
    }

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

            @Override
            public void run() {
                JFrame f = new JFrame("TableGrid");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.add(new TableGrid());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

其他提示

使用任何组件,您喜欢并注册的KeyListener拒绝字符,以配合您behaviour.Add一个的getValue()的setValue获取/容易设置BiDecimal和其他一些方法,所有的画会被任何的JTextComponent提供。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top