【问题标题】:Is there a convenient way to use a spinner as an editor in a Swing JTable?有没有一种方便的方法可以在 Swing JTable 中使用微调器作为编辑器?
【发布时间】:2014-04-16 15:24:35
【问题描述】:

我处理的数字数据通常向上或向下编辑 0.01*Value_of_variable,因此与通常的文本单元格相比,微调器看起来是一个不错的选择。

我查看了 DefaultCellEditor,但它只包含文本字段、组合框或复选框。

有没有方便的使用微调器的方法?

【问题讨论】:

  • 谢谢各位。我想我可以创建一个自定义组件,我只是(错误地)假设可能有不同的方式。

标签: java swing jtable spinner


【解决方案1】:

这是一个解决我在 camickr 的回答中评论的问题的示例。这是一个完整且可编译的示例。拿走你需要的,抛弃你不需要的。

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();
        }
    }
}

【讨论】:

    【解决方案2】:

    ... 并覆盖 getCellEditorValue() 方法:

    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();
        }
    }
    

    【讨论】:

    • 此解决方案的某些行为可能不适合许多用户。当用户在编辑器开始编辑之前键入数字时,JTable 将聚焦 JSpinner,而不是 JSpinner 中的编辑器。这意味着用户刚刚输入的文本无处可去。将此与 DefaultCellEditor 的行为方式进行对比:新键入的键被插入到当前值之后的单元格中。
    • -1 无效的 cellEditor 实现,因为它不符合其通知合同
    【解决方案3】:

    只需扩展DefaultCellEditor 并覆盖getTableCellEditorComponent() 方法以返回JSpinner

    【讨论】:

    【解决方案4】:

    杰森的回答很完美。为了帮助其他可能正在寻找时间和日期版本的人,我编辑了 Jason 的代码以适应。希望它对 Jason 帮助过我的人有所帮助。

    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();
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多