DefaultCellEditor封装了很多常用的editor组件,比如JTextField,JCheckBox,JComboBox,但是有时需要这样的情形:有些行需要JTextField,有些行需要JComboBox,这样就不能直接使用DefaultCellEditor了,其实实现起来也很简单,只要自己参照DefaultCellEditor实现一个自定义的CellEditor就可以了,
源代码如下:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.EventObject;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.TableCellEditor;
public class ConditionValueEditor extends AbstractCellEditor implements
TableCellEditor {
//
// Instance Variables
//
/** The Swing component being edited. */
protected JComponent editorComponent;
/**
* The delegate class which handles all methods sent from the
* <code>CellEditor</code>.
*/
protected EditorDelegate delegate;
/**
* An integer specifying the number of clicks needed to start editing. Even
* if <code>clickCountToStart</code> is defined as zero, it will not
* initiate until a click occurs.
*/
protected int clickCountToStart = 1;
private ConditionInfo info;
public ConditionValueEditor(){
}
/**
* Specifies the number of clicks needed to start editing.
*
* @param count
* an int specifying the number of clicks needed to start editing
* @see #getClickCountToStart
*/
public void setClickCountToStart(int count) {
clickCountToStart = count;
}
/**
* Returns the number of clicks needed to start editing.
*
* @return the number of clicks needed to start editing
*/
public int getClickCountToStart() {
return clickCountToStart;
}
//
// Override the implementations of the superclass, forwarding all methods
// from the CellEditor interface to our delegate.
//
/**
* Forwards the message from the <code>CellEditor</code> to the
* <code>delegate</code>.
*
* @see EditorDelegate#getCellEditorValue
*/
public Object getCellEditorValue() {
return delegate.getCellEditorValue();
}
/**
* Forwards the message from the <code>CellEditor</code> to the
* <code>delegate</code>.
*
* @see EditorDelegate#isCellEditable(EventObject)
*/
public boolean isCellEditable(EventObject anEvent) {
//return delegate.isCellEditable(anEvent);
return true;
}
/**
* Forwards the message from the <code>CellEditor</code> to the
* <code>delegate</code>.
*
* @see EditorDelegate#shouldSelectCell(EventObject)
*/
public boolean shouldSelectCell(EventObject anEvent) {
return delegate.shouldSelectCell(anEvent);
}
/**
* Forwards the message from the <code>CellEditor</code> to the
* <code>delegate</code>.
*
* @see EditorDelegate#stopCellEditing
*/
public boolean stopCellEditing() {
return delegate.stopCellEditing();
}
/**
* Forwards the message from the <code>CellEditor</code> to the
* <code>delegate</code>.
*
* @see EditorDelegate#cancelCellEditing
*/
public void cancelCellEditing() {
delegate.cancelCellEditing();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (column == 1) {
if (ConditionTableModel.class.isInstance(table.getModel())) {
ConditionTableModel model = (ConditionTableModel) table
.getModel();
info = model.getRow(row);
String paramName = info.getVariableName();
String paramvalue = info.getValue();
if (isEnumAttribute(
paramName,info.getConditionCheckType())) {
final JComboBox comboBox = new JComboBox();
List<String> displayList = ... ...;
String displayValue = ... ...;
for(String text:displayList){
comboBox.addItem(text);
if(text.equals(displayValue)){
comboBox.setSelectedItem(text);
}
}
editorComponent = comboBox;
comboBox.putClientProperty("JComboBox.isTableCellEditor",
Boolean.TRUE);
delegate = new EditorDelegate() {
public void setValue(Object value) {
comboBox.setSelectedItem(value);
}
public Object getCellEditorValue() {
return comboBox.getSelectedItem();
}
public boolean shouldSelectCell(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
MouseEvent e = (MouseEvent) anEvent;
return e.getID() != MouseEvent.MOUSE_DRAGGED;
}
return true;
}
public boolean stopCellEditing() {
if (comboBox.isEditable()) {
// Commit edited value.
comboBox.actionPerformed(new ActionEvent(
ConditionValueEditor.this, 0, ""));
}
return super.stopCellEditing();
}
};
comboBox.addActionListener(delegate);
} else {
final JTextField textField = new JTextField(paramvalue);
editorComponent = textField;
this.clickCountToStart = 2;
delegate = new EditorDelegate() {
public void setValue(Object value) {
textField.setText((value != null) ? value
.toString() : "");
}
public Object getCellEditorValue() {
return textField.getText();
}
};
textField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(FocusEvent e) {
info.setValue(textField.getText());
}
});
textField.addActionListener(delegate);
}
if (!info.isParamCondition()) {
editorComponent.setEnabled(false);
}
return editorComponent;
}
}
JLabel label = new JLabel();
label.setText((String) value);
return label;
}
//
// Protected EditorDelegate class
//
/**
* The protected <code>EditorDelegate</code> class.
*/
protected class EditorDelegate implements ActionListener, ItemListener,
Serializable {
/** The value of this cell. */
protected Object value;
/**
* Returns the value of this cell.
*
* @return the value of this cell
*/
public Object getCellEditorValue() {
return value;
}
/**
* Sets the value of this cell.
*
* @param value
* the new value of this cell
*/
public void setValue(Object value) {
this.value = value;
}
/**
* Returns true if <code>anEvent</code> is <b>not</b> a
* <code>MouseEvent</code>. Otherwise, it returns true if the necessary
* number of clicks have occurred, and returns false otherwise.
*
* @param anEvent
* the event
* @return true if cell is ready for editing, false otherwise
* @see #setClickCountToStart
* @see #shouldSelectCell
*/
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
return ((MouseEvent) anEvent).getClickCount() >= clickCountToStart;
}
return true;
}
/**
* Returns true to indicate that the editing cell may be selected.
*
* @param anEvent
* the event
* @return true
* @see #isCellEditable
*/
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
/**
* Returns true to indicate that editing has begun.
*
* @param anEvent
* the event
*/
public boolean startCellEditing(EventObject anEvent) {
return true;
}
/**
* Stops editing and returns true to indicate that editing has stopped.
* This method calls <code>fireEditingStopped</code>.
*
* @return true
*/
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
/**
* Cancels editing. This method calls <code>fireEditingCanceled</code>.
*/
public void cancelCellEditing() {
fireEditingCanceled();
}
/**
* When an action is performed, editing is ended.
*
* @param e
* the action event
* @see #stopCellEditing
*/
public void actionPerformed(ActionEvent e) {
ConditionValueEditor.this.stopCellEditing();
}
/**
* When an item's state changes, editing is ended.
*
* @param e
* the action event
* @see #stopCellEditing
*/
public void itemStateChanged(ItemEvent e) {
ConditionValueEditor.this.stopCellEditing();
}
}
}