001 /* 002 * $Id: ComboBoxCellEditor.java,v 1.3 2005/10/10 18:01:33 rbair Exp $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 package org.jdesktop.swingx.autocomplete; 022 023 import java.awt.event.ActionEvent; 024 import java.awt.event.KeyAdapter; 025 import java.awt.event.KeyEvent; 026 import java.beans.PropertyChangeEvent; 027 import java.beans.PropertyChangeListener; 028 import java.io.Serializable; 029 030 import javax.swing.AbstractCellEditor; 031 import javax.swing.ComboBoxEditor; 032 import javax.swing.JComboBox; 033 import javax.swing.JComponent; 034 import javax.swing.table.TableCellEditor; 035 036 /** 037 * <p>This is a cell editor that can be used when a combo box (that has been set 038 * up for automatic completion) is to be used in a JTable. The 039 * {@link javax.swing.DefaultCellEditor DefaultCellEditor} won't work in this 040 * case, because each time an item gets selected it stops cell editing and hides 041 * the combo box. 042 * </p> 043 * <p> 044 * Usage example: 045 * </p> 046 * <code> 047 * JTable table = ...;</br> 048 * JComboBox comboBox = ...;</br> 049 * ...</br> 050 * TableColumn column = table.getColumnModel().getColumn(0);</br> 051 * column.setCellEditor(new ComboBoxCellEditor(comboBox)); 052 * </code> 053 */ 054 public class ComboBoxCellEditor extends AbstractCellEditor implements TableCellEditor, Serializable { 055 056 private JComboBox comboBox; 057 // a Listener listening for key events (handling enter-key) 058 // and changes of the combo box' editor component. 059 private Handler handler; 060 061 /** 062 * Creates a new ComboBoxCellEditor. 063 * @param comboBox the comboBox that should be used as the cell editor. 064 */ 065 public ComboBoxCellEditor(final JComboBox comboBox) { 066 this.comboBox = comboBox; 067 068 handler = new Handler(); 069 070 // Don't do this: 071 // this.comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); 072 // it probably breaks various things 073 074 // hitting enter in the combo box should stop cellediting 075 JComponent editorComponent = (JComponent) comboBox.getEditor().getEditorComponent(); 076 editorComponent.addKeyListener(handler); 077 // remove the editor's border - the cell itself already has one 078 editorComponent.setBorder(null); 079 080 // editor component might change (e.g. a look&feel change) 081 // the new editor component needs to be modified then (keyListener, border) 082 comboBox.addPropertyChangeListener(handler); 083 } 084 085 // ------ Implementing CellEditor ------ 086 /** 087 * Returns the value contained in the combo box 088 * @return the value contained in the combo box 089 */ 090 public Object getCellEditorValue() { 091 return comboBox.getSelectedItem(); 092 } 093 094 /** 095 * Tells the combo box to stop editing and accept any partially edited value as the value of the combo box. 096 * Always returns true. 097 * @return true 098 */ 099 public boolean stopCellEditing() { 100 if (comboBox.isEditable()) { 101 // Notify the combo box that editing has stopped (e.g. User pressed F2) 102 comboBox.actionPerformed(new ActionEvent(this, 0, "")); 103 } 104 fireEditingStopped(); 105 return true; 106 } 107 108 // ------ Implementing TableCellEditor ------ 109 /** 110 * Sets an initial value for the combo box. 111 * Returns the combo box that should be added to the client's Component hierarchy. 112 * Once installed in the client's hierarchy this combo box will then be able to draw and receive user input. 113 * @param table the JTable that is asking the editor to edit; can be null 114 * @param value the value of the cell to be edited; null is a valid value 115 * @param isSelected will be ignored 116 * @param row the row of the cell being edited 117 * @param column the column of the cell being edited 118 * @return the combo box for editing 119 */ 120 public java.awt.Component getTableCellEditorComponent(javax.swing.JTable table, Object value, boolean isSelected, int row, int column) { 121 comboBox.setSelectedItem(value); 122 return comboBox; 123 } 124 125 // ------ Implementing TreeCellEditor ------ 126 // public java.awt.Component getTreeCellEditorComponent(javax.swing.JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { 127 // String stringValue = tree.convertValueToText(value, isSelected, expanded, leaf, row, false); 128 // comboBox.setSelectedItem(stringValue); 129 // return comboBox; 130 // } 131 132 class Handler extends KeyAdapter implements PropertyChangeListener { 133 public void keyPressed(KeyEvent keyEvent) { 134 int keyCode = keyEvent.getKeyCode(); 135 if (keyCode==keyEvent.VK_ENTER) stopCellEditing(); 136 } 137 public void propertyChange(PropertyChangeEvent e) { 138 if (e.getPropertyName().equals("editor")) { 139 ComboBoxEditor editor = comboBox.getEditor(); 140 if (editor!=null && editor.getEditorComponent()!=null) { 141 JComponent editorComponent = (JComponent) comboBox.getEditor().getEditorComponent(); 142 editorComponent.addKeyListener(this); 143 editorComponent.setBorder(null); 144 } 145 } 146 } 147 } 148 }