简体   繁体   English

JTable单元格编辑器错误

[英]JTable cell editor bug

I write a cell editor of JTable. 我编写了JTable的单元格编辑器。 Now it has a bug. 现在有一个错误。 I want it to show default value when first time loading. 我希望它在首次加载时显示默认值。 After editing, it will show user input. 编辑后,它将显示用户输入。 Run the application, you will understand the bug. 运行该应用程序,您将了解该错误。

How to fix it ? 如何解决?

Thanks. 谢谢。

package com.swing;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

public class PropPageTest extends JPanel {

    private static final long serialVersionUID = 1555593265606867986L;

    public JTableX table;
    public DefaultTableModel model;
    private String[] col_names = { "Name", "Value" };
    private String[] anchor_values = { "CENTER", "NORTH" };
    public String[] default_value = {"John", "NORTH"};

    public boolean isFirstTimeLoad = true;

    private void createGUI() {
        setLayout(new BorderLayout());

        model = new DefaultTableModel(col_names, 2) {
            private static final long serialVersionUID = 478700329843848400L;
            public String[] prop_names = { "Name", "Anchor" };

            public Object getValueAt(int row, int col) {
                if (col == 0) return prop_names[row];
                if(isFirstTimeLoad){
                    isFirstTimeLoad = false;
                    return default_value[row];
                }
                else {
                    return super.getValueAt(row, col);
                }               
            }

            public boolean isCellEditable(int row, int col) {
                if (col == 0) return false;
                return true;
            }
        };

        table = new JTableX(model);

        JTextField txtFld = new JTextField();
        table.registerCellEditor(0, new DefaultCellEditor(txtFld));

        JComboBox cb = new JComboBox(anchor_values);        
        table.registerCellEditor(1, new DefaultCellEditor(cb));         

        add(table, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("test");
        f.setSize(300, 350);
        final PropPageTest test = new PropPageTest();
        f.getContentPane().add(test, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();
        JButton saveBtn = new JButton("Save");
        buttonPanel.add(saveBtn);
        f.getContentPane().add(buttonPanel, BorderLayout.SOUTH);

        saveBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                test.table.stopCellEditing();
                String[] newArr = new String[2];
                newArr[0] = test.model.getValueAt(0, 1)+"";
                newArr[1] = test.model.getValueAt(1, 1)+"";
                boolean isTrue = Arrays.equals(test.default_value, newArr);

                System.out.println("new value --" + test.model.getValueAt(0, 1));
                System.out.println("new value --" + test.model.getValueAt(1, 1));
                System.out.println("is true --" + isTrue);
            }
        });

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setLocationRelativeTo(null);
    }

    public PropPageTest() {
        createGUI();
    }
}

-- another file -另一个文件

package com.swing;


import java.util.HashMap;
import java.util.Set;

import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

public class JTableX extends JTable {
    private static final long serialVersionUID = -7180009397735740833L;
    private final HashMap<Integer, TableCellEditor> rowEditorMap;

    public JTableX(TableModel tm) {
        super(tm);
        rowEditorMap = new HashMap<Integer, TableCellEditor>();
        this.setRowSelectionAllowed(false);
        this.setColumnSelectionAllowed(false);
    }

    public void registerCellEditor(int row, TableCellEditor editor){
        rowEditorMap.put(row, editor);
    }

    public TableCellEditor getCellEditor(int row, int col) {
        TableCellEditor tmpEditor = null;
        if (rowEditorMap != null) tmpEditor = rowEditorMap.get(row);

        if (tmpEditor != null) return tmpEditor;
        return super.getCellEditor(row, col);
    }

    public void stopCellEditing() {
        if (rowEditorMap != null) {
            Set<Integer> keySet = rowEditorMap.keySet();
            for (Integer i : keySet) {
                TableCellEditor tmpEditor = rowEditorMap.get(i);
                if (tmpEditor != null) {                    
                    tmpEditor.stopCellEditing();
                }
            }
        }
    }
}

You can't do that. 你不能那样做。 The JTable (or any other part of the code) is allowed to call getValueAt when it wants to. JTable(或代码的任何其他部分)允许在需要时调用getValueAt。 The method should return what the table actually contains. 该方法应返回表实际包含的内容。 If you want default values in the table initially, then store these default values in the model. 如果最初需要表中的默认值,则将这些默认值存储在模型中。

When the data changes in the model, it must fire a TableModelEvent. 当模型中的数据更改时,它必须激发一个TableModelEvent。 This is done automatically by DefaultTableModel when setValueAt is called. 当调用setValueAt时,这将由DefaultTableModel自动完成。

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

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