Is there a convenient way to use a spinner as an editor in a Swing JTable?

后端 未结 4 1824
梦如初夏
梦如初夏 2021-01-06 06:53

I deal with numeric data that is often edited up or down by 0.01*Value_of_variable, so a spinner looks like a good choice compared to a usual text cell.

I\'ve looke

相关标签:
4条回答
  • 2021-01-06 07:27

    Here's an example that addresses the issue I commented on camickr's answer. This is a complete and compilable example. Take what you need and ditch what you don't.

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class JSpinnerInTables {
        static String[] columnNames = {
            "Name","Value"
        };
        static Object[][] data = {
            {"one",1.0},
            {"two",2.0}
        };
        public static void main( String[] args ) {
            JFrame frame = new JFrame();
            JTable table = new JTable(data,columnNames);
            //table.setSurrendersFocusOnKeystroke(true);
            TableColumnModel tcm = table.getColumnModel();
            TableColumn tc = tcm.getColumn(1);
            tc.setCellEditor(new SpinnerEditor());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(table);
            frame.pack();
            frame.setVisible(true);
        }
        public static class SpinnerEditor extends DefaultCellEditor
        {
            JSpinner spinner;
            JSpinner.DefaultEditor editor;
            JTextField textField;
            boolean valueSet;
    
            // Initializes the spinner.
            public SpinnerEditor() {
                super(new JTextField());
                spinner = new JSpinner();
                editor = ((JSpinner.DefaultEditor)spinner.getEditor());
                textField = editor.getTextField();
                textField.addFocusListener( new FocusListener() {
                    public void focusGained( FocusEvent fe ) {
                        System.err.println("Got focus");
                        //textField.setSelectionStart(0);
                        //textField.setSelectionEnd(1);
                        SwingUtilities.invokeLater( new Runnable() {
                            public void run() {
                                if ( valueSet ) {
                                    textField.setCaretPosition(1);
                                }
                            }
                        });
                    }
                    public void focusLost( FocusEvent fe ) {
                    }
                });
                textField.addActionListener( new ActionListener() {
                    public void actionPerformed( ActionEvent ae ) {
                        stopCellEditing();
                    }
                });
            }
    
            // Prepares the spinner component and returns it.
            public Component getTableCellEditorComponent(
                JTable table, Object value, boolean isSelected, int row, int column
            ) {
                if ( !valueSet ) {
                    spinner.setValue(value);
                }
                SwingUtilities.invokeLater( new Runnable() {
                    public void run() {
                        textField.requestFocus();
                    }
                });
                return spinner;
            }
    
            public boolean isCellEditable( EventObject eo ) {
                System.err.println("isCellEditable");
                if ( eo instanceof KeyEvent ) {
                    KeyEvent ke = (KeyEvent)eo;
                    System.err.println("key event: "+ke.getKeyChar());
                    textField.setText(String.valueOf(ke.getKeyChar()));
                    //textField.select(1,1);
                    //textField.setCaretPosition(1);
                    //textField.moveCaretPosition(1);
                    valueSet = true;
                } else {
                    valueSet = false;
                }
                return true;
            }
    
            // Returns the spinners current value.
            public Object getCellEditorValue() {
                return spinner.getValue();
            }
    
            public boolean stopCellEditing() {
                System.err.println("Stopping edit");
                try {
                    editor.commitEdit();
                    spinner.commitEdit();
                } catch ( java.text.ParseException e ) {
                    JOptionPane.showMessageDialog(null,
                        "Invalid value, discarding.");
                }
                return super.stopCellEditing();
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 07:36

    ... and overwrite the getCellEditorValue() method:

    class SpinnerEditor extends DefaultCellEditor
    {
        private JSpinner spinner;
    
        public SpinnerEditor()
        {
            super( new JTextField() );
            spinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 5));
            spinner.setBorder( null );
        }
    
        public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column)
        {
            spinner.setValue( value );
            return spinner;
        }
    
        public Object getCellEditorValue()
        {
            return spinner.getValue();
        }
    }
    
    0 讨论(0)
  • 2021-01-06 07:37

    Jason's answer is perfect. To help others that might be looking for a Time and Date version, I've edited Jason's code to suit. Hope it helps someone as Jason's has helped me.

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class SpinnerInJTable {
    static String[] columnNames = {
        "Name","Time & Date"
    };
    static Object[][] data = {
        {"Date One",new Date(Long.decode("1397091313404"))},
        {"Date Two", new Date(Long.decode("1397001313404"))}
    };
    public static void main( String[] args ) {
        JFrame frame = new JFrame();
        JTable table = new JTable(data,columnNames);
        //table.setSurrendersFocusOnKeystroke(true);
        TableColumnModel tcm = table.getColumnModel();
        TableColumn tc = tcm.getColumn(1);
        tc.setCellEditor(new SpinnerEditor());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(table);
        frame.pack();
        frame.setVisible(true);
    }
    public static class SpinnerEditor extends DefaultCellEditor
    {
        JSpinner spinner;
        JSpinner.DefaultEditor editor;
        JTextField textField;
        boolean valueSet;
    
        // Initializes the spinner.
        public SpinnerEditor() {
            super(new JTextField());
            spinner = new JSpinner(new SpinnerDateModel());
            editor = ((JSpinner.DateEditor)spinner.getEditor());
            textField = editor.getTextField();
            textField.addFocusListener( new FocusListener() {
                public void focusGained( FocusEvent fe ) {
                    System.err.println("Got focus");
                    //textField.setSelectionStart(0);
                    //textField.setSelectionEnd(1);
                    SwingUtilities.invokeLater( new Runnable() {
                        public void run() {
                            if ( valueSet ) {
                                textField.setCaretPosition(1);
                            }
                        }
                    });
                }
                public void focusLost( FocusEvent fe ) {
                }
            });
            textField.addActionListener( new ActionListener() {
                public void actionPerformed( ActionEvent ae ) {
                    stopCellEditing();
                }
            });
        }
    
        // Prepares the spinner component and returns it.
        public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column
        ) {
            if ( !valueSet ) {
                spinner.setValue(value);
            }
            SwingUtilities.invokeLater( new Runnable() {
                public void run() {
                    textField.requestFocus();
                }
            });
            return spinner;
        }
    
        public boolean isCellEditable( EventObject eo ) {
            System.err.println("isCellEditable");
            if ( eo instanceof KeyEvent ) {
                KeyEvent ke = (KeyEvent)eo;
                System.err.println("key event: "+ke.getKeyChar());
                textField.setText(String.valueOf(ke.getKeyChar()));
                //textField.select(1,1);
                //textField.setCaretPosition(1);
                //textField.moveCaretPosition(1);
                valueSet = true;
            } else {
                valueSet = false;
            }
            return true;
        }
    
        // Returns the spinners current value.
        public Object getCellEditorValue() {
            return spinner.getValue();
        }
    
        public boolean stopCellEditing() {
            System.err.println("Stopping edit");
            try {
                editor.commitEdit();
                spinner.commitEdit();
            } catch ( java.text.ParseException e ) {
                JOptionPane.showMessageDialog(null,
                    "Invalid value, discarding.");
            }
            return super.stopCellEditing();
        }
    }
    

    }

    0 讨论(0)
  • 2021-01-06 07:48

    Simply extend DefaultCellEditor and overwrite the getTableCellEditorComponent() method to return a JSpinner.

    0 讨论(0)
提交回复
热议问题