有没有一种方便的方法可以在Swing JTable中使用微调器作为编辑器?

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

我看过DefaultCellEditor但它只会带文本字段,combobox或复选框。

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

…并覆盖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(); } } 

这是一个解决我对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(); } } } 

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

杰森的答案是完美的。 为了帮助那些可能正在寻找时间和日期版本的人,我编辑了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(); } } 

}