简体   繁体   English

使用JTable单元格编辑器

[英]using JTable cell editor

I am not sure why the editor i am setting for my jtable is not being called. 我不确定为什么没有为我的jtable设置的编辑器被调用。 I used the editor example from another SO Question . 我使用了另一个SO Question中的编辑器示例。

When i edit my jtable it simply edits as string... i expected it to accept only number values. 当我编辑jtable时,它只是编辑为字符串...我希望它仅接受数字值。 may be some exception if i type any other text... but i dont think the editor is being called here when i edit my table. 如果我键入任何其他文本,可能会有些例外...但是我不认为编辑表时会在这里调用编辑器。

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.NumberFormatter;

import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;

public class Grow extends JFrame {

private static final Object[][] rowData = {{"Hello", "World"}};
private static final Object[] columnNames = {"A", "B"};

private JTable table;
private DefaultTableModel model;

public Grow() {
     Container c = getContentPane();
     c.setLayout(new BorderLayout());

     model = new DefaultTableModel(rowData, columnNames);
     table = new JTable();
     table.setModel(model);
     c.add(new JScrollPane(table), BorderLayout.CENTER);
     JButton add = new JButton("Add");
     JButton delete = new JButton("Delete");
     c.add(add, BorderLayout.LINE_START);
     add.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
             model.addRow(rowData[0]);
         }
     });

     table.setCellEditor(new NumberCellEditor());

     c.add(delete, BorderLayout.LINE_END);
     delete.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
             if(table.getSelectedRow()>-1)
                 model.removeRow(table.getSelectedRow());
         }
     });

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     pack(); 
}

class NumberCellEditor extends DefaultCellEditor {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public NumberCellEditor(){
        super(new JFormattedTextField());
    }

    @Override
     public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        JFormattedTextField editor = (JFormattedTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);

        if (value!=null){
            DecimalFormat numberFormat = new DecimalFormat("#,##0.00;(#,##0.00)");
            editor.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(numberFormat)));
            Number num = (Number) value;  
            String text = numberFormat.format(num);
            editor.setHorizontalAlignment(SwingConstants.RIGHT);
            editor.setText(text);
        }
        System.out.println(value);
        return editor;
    }

    /*@Override
    public boolean stopCellEditing() {
        try {
            // try to get the value
            //this.getCellEditorValue();
            return super.stopCellEditing();
        } catch (Exception ex) {
            return false;
        }

    }
    */

    @Override
    public Object getCellEditorValue() {
        // get content of textField
        String str = (String) super.getCellEditorValue();
        if (str == null) {
            return null;
        }

        if (str.length() == 0) {
            return null;
        }

        // try to parse a number
        try {
            ParsePosition pos = new ParsePosition(0);
            Number n = NumberFormat.getInstance().parse(str, pos);
            if (pos.getIndex() != str.length()) {
                throw new ParseException(
                        "parsing incomplete", pos.getIndex());
            }

            // return an instance of column class
            return new Float(n.floatValue());

        } catch (ParseException pex) {
            throw new RuntimeException(pex);
        }
    }
    }

public static void main(String[] args) {
    Grow g = new Grow();
    g.setLocationRelativeTo(null);
    g.setVisible(true);
}
}
  • use plain vanilla JTextField with DocumentFilter instead of JFormattedTextField as editors Component . 使用带有DocumentFilter普通香草JTextField代替JFormattedTextField作为编辑器Component

  • I cant comment something, attached start_point for JFormattedTextField with XxxFormat (important details are in offical Oracle tutorial, APIs How to use FormattedTextField , NumberFormat etc.) 我无法发表评论,用XxxFormat附加了JFormattedTextField start_point(重要的详细信息在正式的Oracle教程中,API How to use FormattedTextFieldNumberFormat等)。

  • you can to add InternationalFormatter for filtering only Numbers 您可以添加InternationalFormatter仅过滤数字

eg 例如

InternationalFormatter formatter = new InternationalFormatter(format);
formatter.setAllowsInvalid(false);
//formatter.setMinimum(0.0);
//formatter.setMaximum(1000.00);

screen_shot screen_shot

在此处输入图片说明

from code 从代码

import java.awt.Component;
import java.awt.EventQueue;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

public class EditorAsRendererTableTest {

    public EditorAsRendererTableTest() {
        JTable table = new JTable(3, 2);
        TableColumnModel colModel = table.getColumnModel();
        colModel.getColumn(0).setCellEditor(new MyCellEditor());
        colModel.getColumn(0).setCellRenderer(new MyCellEditor());
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new EditorAsRendererTableTest();
            }
        });
    }

    private class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {

        private static final long serialVersionUID = 1L;
        private JFormattedTextField renderer;
        private JFormattedTextField editor;
        private NumberFormat format = DecimalFormat.getInstance();

        public MyCellEditor() {
            format.setMinimumFractionDigits(2);
            format.setMaximumFractionDigits(4);
            format.setRoundingMode(RoundingMode.HALF_UP);
            renderer = new JFormattedTextField(format);
            renderer.setBorder(null);
            editor = new JFormattedTextField(format);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            renderer.setValue(value);
            return renderer;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            editor.setValue(value);
            return editor;
        }

        @Override
        public boolean stopCellEditing() {
            try {
                editor.commitEdit();
            } catch (ParseException e) {
                return false;
            }
            return super.stopCellEditing();
        }

        @Override
        public Object getCellEditorValue() {
            return editor.getValue();
        }
    }
}

i expected it to accept only number values 我希望它只接受数字值

In general there is no need to create a custom editor. 通常,无需创建自定义编辑器。 Just override the getColumnClass() method of the TableModel to return the proper class of data stored in model and the table will use appropriate renderer and editor. 只需重写TableModel的getColumnClass()方法即可返回存储在模型中的数据的正确类,该表将使用适当的渲染器和编辑器。

However, if you want an editor to limit decimal places or do range checking on the number then you can use a custom editor. 但是,如果您希望编辑器限制小数位或对数字进行范围检查,则可以使用自定义编辑器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM