我想请问各位高手一个有关使用spinner做为单元编辑器的问题:
我有一个tabel,其中有一列是使用spinner作为单元编辑器。当我
使用tab健遍历各个单元格时,我希望当遍历到使用spinner的单元格时,
该单元被选中,并且可以在spinner的textfield中输入。我现在的状态是,tab健可以遍历可编辑的单元格,当遍历到spinner单元格时,
使用上下键,可以改变单元的值,但是不可以在textfield上输入。看上去是因为
没有进入编辑状态,只有当鼠标单击textfield后才进入编辑状态。请问各位知不知道如何让编辑器被选中?已经纠结在这个问题上两个星期了,希望各位
能指点迷津。在线等。

解决方案 »

  1.   

    下面是renderer:
    mport java.awt.Component;
    import javax.swing.JFormattedTextField;
    import javax.swing.JSpinner;
    import javax.swing.JTable;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.table.TableCellRenderer;public class SpinnerCellRenderer implements TableCellRenderer{
        private JSpinner spinner;
        private JFormattedTextField ftf;
        public SpinnerCellRenderer(int value, int min) {
            spinner = new JSpinner();
            spinner.setModel(new SpinnerNumberModel(value, min, null, 1));
            ftf = new JFormattedTextField(value);
        }
        public Component getTableCellRendererComponent(JTable table,
                                                       Object value,
                                                       boolean isSelected,
                                                       boolean hasFocus,
                                                       int row,
                                                       int column) {
            // Initializes the panel to be returned with a control that renders
            // realization data
            //Integer currentColor = (Integer)table.getValueAt(row, column);
            spinner.getModel().setValue(value);
            //ftf.setValue(value);
            if (table != null) {
                if(table.isCellEditable(row, column))
                   ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setBackground(table.getSelectionBackground());
                   ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setForeground(table.getSelectionForeground());
                   //ftf.setBackground(table.getSelectionBackground());
                   //ftf.setForeground(table.getSelectionForeground());
            } else {
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setBackground(table.getBackground());
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setForeground(table.getForeground());
                //ftf.setBackground(table.getBackground());
                //ftf.setForeground(table.getForeground());
            }
            
            if (hasFocus) {
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setBackground(table.getSelectionBackground());
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setForeground(table.getSelectionForeground());
                //ftf.setBackground(table.getSelectionBackground());
                //ftf.setForeground(table.getSelectionForeground());
                table.editCellAt(row, column);
                table.getEditorComponent().requestFocusInWindow();
            } else {
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setBackground(table.getBackground());
                ((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setForeground(table.getForeground());
                //((JSpinner.DefaultEditor)(spinner.getEditor())).getTextField().setEditable(false);
                //ftf.setBackground(table.getBackground());
                //ftf.setForeground(table.getForeground());      
            }
                
            //return ftf;
            return spinner;
        }
    }
      

  2.   

    下面是我的editor的code:
    import java.awt.Component;
    import java.awt.event.ActionEvent;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.MouseEvent;
    import java.text.NumberFormat;
    import java.text.ParseException;
    import java.util.EventObject;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.DefaultCellEditor;
    import javax.swing.InputMap;
    import javax.swing.JComponent;
    import javax.swing.JFormattedTextField;
    import javax.swing.JSpinner;
    import javax.swing.JSpinner.DefaultEditor;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.KeyStroke;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.DefaultFormatterFactory;
    import javax.swing.text.NumberFormatter;public class SpinnerCellEditor extends DefaultCellEditor{    protected JTable table;
        protected SpinnerTableModel tableModel;
        private Integer minimum;
        private Integer maximum;
        private JFormattedTextField ftf;
        private NumberFormat integerFormat;
        
        public SpinnerCellEditor(JTable table) {
            super(new JTextField());
            setClickCountToStart(0);
            this.table = table;
            tableModel = (SpinnerTableModel)table.getModel();
            tableTeyActionDefinition();
    //        KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
    //        im.put(up, "none");
            KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
    //        im.put(down, "none");
            
            SpinnerNumberModel tModel = new SpinnerNumberModel(new Integer(0), 0, null,1);
            editorComponent = new JSpinner(tModel);
            createJSpinnerDelegate();
        }
        
         public Component getTableCellEditorComponent(JTable table,
                                                      Object value,
                                                      boolean isSelected, 
                                                      int row, 
                                                      int column) {
                //categoryTable.setFocusTraversalKeysEnabled(false);
                minimum = 0;
                maximum = Integer.MAX_VALUE;
                ((JSpinner)editorComponent).setModel(new SpinnerNumberModel((Integer)(value), minimum, maximum, new Integer(1)));
                setTextFieldProperty();
                    
                if (value != null && value.equals("")) {
                    ((JSpinner)editorComponent).getModel().setValue((Integer)value);
                    ftf.setValue(value);
                }
                
                if (isSelected) {
                    System.out.printf("\n%s",ftf.getText());
                    //ftf.selectAll();
                    //ftf.requestFocusInWindow();
                    //table.editCellAt(row, column);
                    //editorComponent.requestFocusInWindow();
                    //table.getEditorComponent().requestFocusInWindow();
                }            return editorComponent;
            }
        
            private void setTextFieldProperty() {
                
            ftf = ((JSpinner.DefaultEditor)((JSpinner)editorComponent).getEditor()).getTextField();        //Set up the editor for the integer cells.
            integerFormat = NumberFormat.getIntegerInstance();
            NumberFormatter intFormatter = new NumberFormatter(integerFormat);
            intFormatter.setFormat(integerFormat);
            intFormatter.setMinimum(minimum);
            intFormatter.setMaximum(maximum);        ftf.setFormatterFactory(
                    new DefaultFormatterFactory(intFormatter));
            //ftf.setValue(minimum);
            ftf.setHorizontalAlignment(JTextField.TRAILING);
            ftf.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT);
            ftf.addFocusListener(new FocusListener() {            public void focusGained(FocusEvent e) {
                }            public void focusLost(FocusEvent e) {
                    if (ftf.getText() != null && !ftf.getText().equals(""))
                        ((JSpinner)editorComponent).setValue(Integer.parseInt(ftf.getText()));
                }
            });
            //ftf.setFocusTraversalKeysEnabled(false);        // Only allow the input of numbers
            ftf.addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e){  
                    char c = e.getKeyChar();  
                    if(Character.isDigit(c) || c==KeyEvent.VK_BACK_SPACE || c==KeyEvent.VK_DELETE) {
                        System.out.printf("\n%s\n", ftf.getText().toString());
    //                    if (ftf.getText() != null && !ftf.getText().equals(""))
    //                        ((JSpinner)editorComponent).setValue(Integer.parseInt(ftf.getText()));
                        return;  
                    }
                    e.consume();
                }
                public void keyPressed(KeyEvent e){  
                    if(e.isControlDown())   
                        e.consume();  
                }  
            });        //React when the user presses Enter while the editor is
            //active.  (Tab is handled as specified by
            //JFormattedTextField's focusLostBehavior property.)
            ftf.getInputMap().put(KeyStroke.getKeyStroke(
                                            KeyEvent.VK_TAB, 0),
                                            "check");
            ftf.getActionMap().put("check", new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                    if (!ftf.isEditValid()) { //The text is invalid.
    //                       ((JSpinner)editorComponent).getModel().setValue(((Integer)ftf.getText()));
                            ftf.postActionEvent(); //inform the editor
                        }
                   else {
                        try {              //The text is valid,
                            ftf.commitEdit();     //so use it.
                            ftf.postActionEvent(); //stop editing
                        } catch (java.text.ParseException exc) { }
                    }
                }
            });
        }
      

  3.   

        // handle table input/actionmap
        // tab to editable cell only
        private void tableTeyActionDefinition() {
            InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
            final Action oldTabAction = table.getActionMap().get(im.get(tab));
            Action tabAction = new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                    oldTabAction.actionPerformed( e );
                    JTable table = (JTable)e.getSource();
                    int rowCount = table.getRowCount();
                    int columnCount = table.getColumnCount();
                    int row = table.getSelectedRow();
                    int column = table.getSelectedColumn();
     
                    while (! table.isCellEditable(row, column) ) {
                        column += 1; 
                        if (column == columnCount) {
                            column = 0;
                            row +=1;
                        } 
                        if (row == rowCount)
                            row = 0;
     
                        //  Back to where we started, get out.
                        if (row == table.getSelectedRow()
                        &&  column == table.getSelectedColumn()) {
                            break;
                        }
                    }
     
                    table.changeSelection(row, column, false, false);
    //                if (table.editCellAt(row, column))
    //                    table.getEditorComponent().requestFocusInWindow();
                }
            };
            table.getActionMap().put(im.get(tab), tabAction);
        }    
            
        public Object getCellEditorValue() {
            return ((JSpinner)editorComponent).getValue();
        }
        
        /**
         * Creates a delatee obj for the combobox which will handle changes.
         */
        private void createJSpinnerDelegate() {
            ((JSpinner)editorComponent).putClientProperty("JSpinner.isTableCellEditor", Boolean.TRUE);        this.clickCountToStart = 1;
            delegate = new CustomEditorDelegate(this) {            public void setValue(Object value) {
                    ((JSpinner)editorComponent).setValue((value != null) ? value : 0);
                }            public Object getCellEditorValue() {
                    return ((JSpinner)editorComponent).getValue();
                }            public boolean shouldSelectCell(EventObject anEvent) { 
                    if (anEvent instanceof MouseEvent) { 
                        MouseEvent e = (MouseEvent)anEvent;
                        return e.getID() != MouseEvent.MOUSE_DRAGGED;
                    }                return true;
                }            public void stateChanged(ChangeEvent e) {
                    //cellEditor.stopCellEditing();
                    System.out.printf("\n%s,%d",ftf.getText(),ftf.getValue());
                    super.stopCellEditing();
                }
            };        ((JSpinner)editorComponent).addChangeListener((CustomEditorDelegate)delegate);
            ((JSpinner)editorComponent).setRequestFocusEnabled(true);
        }    /**
         * Custom delegate class.
         */
        protected class CustomEditorDelegate extends EditorDelegate implements ChangeListener {
            protected SpinnerCellEditor cellEditor;        public CustomEditorDelegate(final SpinnerCellEditor cellEditor) {
                this.cellEditor = cellEditor;
            }        //FIXME: check that this works well for the Combobox as well.
            public void stateChanged(ChangeEvent e) {
                //only applicable for the spinner
            }
        }  
    }