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