JTable 单元格确实通过鼠标单击获得焦点

问题描述 投票:0回答:1

我有一个简单的表格和面板上的一个按钮。 当我单击表格单元格时,我可以对其进行编辑,但该单元格没有焦点。 我希望能够在用户更改单元格内容时保存单元格内容,但只有当我首先使用 Tab 键进入单元格以获得焦点,然后通过鼠标单击选择它时,我才能执行此操作。 我希望能够单击单元格并在退出单元格时保存任何更改。
单击该按钮时,它会显示保存的表格单元格内容。

这是我的代码:

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import javax.swing.*;
    import static javax.swing.SwingConstants.LEFT;
    import javax.swing.SwingUtilities;
    import javax.swing.table.*;

    public class TestFocus {

        public ArrayList<String> mylog;

        public TestFocus() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel = createPanel();
            frame.add(panel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);    
        }

        public JPanel createPanel() {
            mylog = new ArrayList<>();
            JPanel panel = new JPanel();
            TestTableModel tm = new TestTableModel();
            JLabel title = new JLabel("Test Table");
            JTable table = new JTable(tm);
            TableColumnModel tcm = table.getColumnModel();
            TestTableCellEditor editor = new TestTableCellEditor();
            TestTableCellRenderer renderer = new TestTableCellRenderer();
            for (int i = 0; i < tm.getColumnCount(); i++) {
                TableColumn column = tcm.getColumn(i);
                column.setCellEditor(editor);
                column.setCellRenderer(renderer);
            }

            JScrollPane jsp = new JScrollPane(table);

            JButton btn = new JButton("Done");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    for (String s : mylog) {
                        System.out.println(s);
                    }
                }
            });

            panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
            panel.add(jsp);
            panel.add(btn);
            return panel;
        }

        class TestTableModel extends AbstractTableModel {
            private String[] columnNames = { "Firstname", "Lastname", "Age" };
            private Object[][] data = { 
                { "John", "Smith", 29},
                { "Mary", "Thomas", 63},
                { "Peter", "Jones", 48} };

            public int getColumnCount() {
                return columnNames.length;
            }

            public int getRowCount() {
                return data.length;
            }

            public String getColumnName(int col) {
                return columnNames[col];
            }

            public Object getValueAt(int row, int col) {
                return data[row][col];
            }

            public Class getColumnClass(int col) {
                return getValueAt(0, col).getClass();
            }

            public String getColumnClassName(int col) {
                if (col == 2) {
                    return "Integer";
                } else {
                    return "String";
                }
            }

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

            public void setValueAt(Object value, int row, int col) {
                data[row][col] = value;
                fireTableCellUpdated(row, col);
            }
        }

        public class TestTableCellEditor extends AbstractCellEditor
                implements TableCellEditor {
            JComponent component = new JTextField();

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value,
                    boolean isSelected, int row, int column) {

                if (value != null) {
                    ((JTextField)component).setText(value.toString());
                } else {
                    ((JTextField)component).setText("");
                }

                if (isSelected) {
                    mylog.add(value.toString() + ": row/col("+row+"/"+column+")");
                }

                return (JTextField)component;
            }

            @Override
            public Object getCellEditorValue() {
                int size = mylog.size();
                if (size > 0) {
                    Object val = mylog.get(size - 1);
                    if ((((JTextField)component).getText().equals(val))) {
                        mylog.remove(size - 1);
                    }
                }
                return ((JTextField)component).getText();
            }

        }

        public class TestTableCellRenderer extends JLabel implements 
                    TableCellRenderer {

            public TestTableCellRenderer() {
                this.setOpaque(true);
            }

            public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, final int row, int column) {

                DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
                Component c = renderer.getTableCellRendererComponent(table, value,
                        isSelected, hasFocus, row, column);
                if (hasFocus) {
                    c.setBackground(Color.yellow);
                }
                TestTableModel tm = (TestTableModel)table.getModel();
                int col = table.convertColumnIndexToModel(column);
                String colname = tm.getColumnName(col);
                String type = tm.getColumnClassName(col);

                if (type.equals("Integer") || type.equals("Int")) {
                    ((JLabel)c).setHorizontalAlignment(CENTER);
                } else {    // add padding 
                    ((JLabel)c).setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
                    ((JLabel)c).setHorizontalAlignment(LEFT);
                }

                if (type.equals("String")) {
                    String text = ((JLabel)c).getText();
                        ((JLabel)c).setToolTipText(text);
                }
               return c;
            }
        }        

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new TestFocus();
                }
            });
        }

    }
java swing jtable focus selection
1个回答
0
投票

我也曾处理过这个问题。 到目前为止唯一有效的方法是在要使用的单元格上双击鼠标。

© www.soinside.com 2019 - 2024. All rights reserved.