带有“,”分隔符的Jtable数字编辑器,而不是“。”

时间:2015-11-21 09:03:51

标签: java swing jtable tablecelleditor decimal-point

我是法国人,不是Java新手。 在法语中,双打有“,”分隔符而不是“。”。所以我有一个列类为Double的JTable Cell,当我输入例如2.4时,它是好的。但是当我输入2,4时它会阻塞。

我使用了Locale.setDefault(Locale.FRENCH);,但结果相同:

Number

正如您在下图所示,我的应用程序以法语区域设置开头: System Locale 有没有办法输入2,4而不是2.4?

此致。

4 个答案:

答案 0 :(得分:2)

我建议您使用AbstractTableModel实施自定义数据模型,然后在方法getValueAt(int row, int col)内使用NumberFormat,如下所示:

NumberFormat.getInstance(Locale.FRENCH).format(2.4);

答案 1 :(得分:2)

  

有没有办法输入2,4而不是2.4?

那么有几个问题。

  1. 默认渲染器将显示"。"不是","。
  2. 默认编辑器将显示"。",而不是","
  3. 默认编辑器无法识别","当您尝试将值保存到TableModel时,将其作为Double的有效字符
  4. 当您离开单元格时,必须将输入的字符串转换为Double。但是,Double.parseDouble(...)方法无法识别","即使使用法语区域设置。

    默认单元格编辑器意识到无法正确转换字符串,因此单元格以红色边框突出显示,表示无效值。

    下面的解决方案使用自定义编辑器在内部处理","的转换。到"。"在将String解析为Double之前。它还将转换"。"到","所以这个值在编辑器中正确显示。

    import java.awt.*;
    import java.text.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    
    public class LocaleEditor extends DefaultCellEditor
    {
        private Object value;
    
        public LocaleEditor()
        {
            super( new JTextField() );
            ((JTextField)getComponent()).setHorizontalAlignment(JTextField.RIGHT);
        }
    
        @Override
        public Object getCellEditorValue()
        {
            return value;
        }
    
        @Override
        public boolean stopCellEditing()
        {
            try
            {
                String editingValue = (String)super.getCellEditorValue();
    
                //  Don't allow user to enter "."
    
                if (editingValue.contains("."))
                {
                    JTextField textField = (JTextField)getComponent();
                    textField.setBorder(new LineBorder(Color.red));
                    return false;
                }
    
                // Replace local specific character
    
                int offset = editingValue.lastIndexOf(",");
    
                if (offset != -1)
                {
                    StringBuilder sb = new StringBuilder(editingValue);
                    sb.setCharAt(offset, '.');
                    editingValue = sb.toString();
                }
    
                value = Double.parseDouble( editingValue );
            }
            catch(NumberFormatException exception)
            {
                JTextField textField = (JTextField)getComponent();
                textField.setBorder(new LineBorder(Color.red));
                return false;
            }
    
            return super.stopCellEditing();
        }
    
        @Override
        public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column)
        {
            Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);
    
            JTextField textField = (JTextField)c;
            textField.setBorder( new LineBorder(Color.BLACK) );
    
            String text = textField.getText();
            int offset = text.lastIndexOf(".");
    
            // Display local specific character
    
            if (offset != -1)
            {
                StringBuilder sb = new StringBuilder(text);
                sb.setCharAt(offset, ',');
                textField.setText( sb.toString() );
            }
    
            return c;
        }
    
        private static void createAndShowUI()
        {
            String[] columnNames = {"String", "Double", "Boolean"};
    
            Object[][] data =
            {
                {"A", new Double(1), Boolean.TRUE },
                {"B", new Double(2.25), Boolean.FALSE},
                {"C", new Double(12.34), Boolean.TRUE },
                {"D", new Double(1234.56), Boolean.FALSE}
            };
    
            DefaultTableModel model = new DefaultTableModel(data, columnNames)
            {
                //  Returning the Class of each column will allow different
                //  renderers and editors to be used based on Class
    
                public Class getColumnClass(int column)
                {
                    for (int row = 0; row < getRowCount(); row++)
                    {
                        Object o = getValueAt(row, column);
    
                        if (o != null)
                            return o.getClass();
                    }
    
                    return Object.class;
                }
            };
    
            JTable table = new JTable(model);
            table.setRowHeight(20);
    
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane scrollPane = new JScrollPane( table );
            scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    
            //  Use a custom renderer and editor
    
            NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
            nf.setMinimumFractionDigits(2);
            TableCellRenderer renderer = new NumberRenderer( nf );
            table.setDefaultRenderer(Double.class, renderer);
            TableCellEditor fce = new LocaleEditor();
            table.setDefaultEditor(Double.class, fce);
    
            JFrame frame = new JFrame("Table Five Character Editor");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( scrollPane );
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    

    上面的代码还使用Table Format Renderers中的代码,它允许您轻松地为给定的Locale创建自定义渲染器。如果您不想使用渲染器,请注释掉代码,然后注意&#34;。&#34;将显示在表格中。

答案 2 :(得分:1)

如果您的应用程序仅供法国用户使用,您可以将默认语言环境硬编码为法语。

Locale.setDefault( Locale.FRENCH );

答案 3 :(得分:0)

或者,作为变通方法,只需将所有列设置为String(因此,将接受所有输入),并在DefaultTableModel - &gt; TableModelListener - &gt; {{1根据需要格式化您的String,然后使用tableChanged()将其解析为Double