001 /* 002 * $Id: ComboBoxCellEditor.java 2370 2007-11-02 14:26:47Z kschaefe $ 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 javax.swing.*; 024 import javax.swing.table.TableCellEditor; 025 import java.awt.event.ActionEvent; 026 import java.awt.event.KeyAdapter; 027 import java.awt.event.KeyEvent; 028 import java.beans.PropertyChangeEvent; 029 import java.beans.PropertyChangeListener; 030 import java.io.Serializable; 031 032 /** 033 * <p>This is a cell editor that can be used when a combo box (that has been set 034 * up for automatic completion) is to be used in a JTable. The 035 * {@link javax.swing.DefaultCellEditor DefaultCellEditor} won't work in this 036 * case, because each time an item gets selected it stops cell editing and hides 037 * the combo box. 038 * </p> 039 * <p> 040 * Usage example: 041 * </p> 042 * <p> 043 * <pre><code> 044 * JTable table = ...; 045 * JComboBox comboBox = ...; 046 * ... 047 * TableColumn column = table.getColumnModel().getColumn(0); 048 * column.setCellEditor(new ComboBoxCellEditor(comboBox)); 049 * </code></pre> 050 * </p> 051 */ 052 public class ComboBoxCellEditor extends AbstractCellEditor implements TableCellEditor, Serializable { 053 054 /** the combo box */ 055 private JComboBox comboBox; 056 057 /** 058 * Creates a new ComboBoxCellEditor. 059 * @param comboBox the comboBox that should be used as the cell editor. 060 */ 061 public ComboBoxCellEditor(final JComboBox comboBox) { 062 this.comboBox = comboBox; 063 064 Handler handler = new Handler(); 065 066 // Don't do this: 067 // this.comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); 068 // it probably breaks various things 069 070 // hitting enter in the combo box should stop cellediting 071 JComponent editorComponent = (JComponent) comboBox.getEditor().getEditorComponent(); 072 editorComponent.addKeyListener(handler); 073 // remove the editor's border - the cell itself already has one 074 editorComponent.setBorder(null); 075 076 // editor component might change (e.g. a look&feel change) 077 // the new editor component needs to be modified then (keyListener, border) 078 comboBox.addPropertyChangeListener(handler); 079 } 080 081 // ------ Implementing CellEditor ------ 082 /** 083 * Returns the value contained in the combo box 084 * @return the value contained in the combo box 085 */ 086 public Object getCellEditorValue() { 087 return comboBox.getSelectedItem(); 088 } 089 090 /** 091 * Tells the combo box to stop editing and accept any partially edited value as the value of the combo box. 092 * Always returns true. 093 * @return true 094 */ 095 public boolean stopCellEditing() { 096 if (comboBox.isEditable()) { 097 // Notify the combo box that editing has stopped (e.g. User pressed F2) 098 comboBox.actionPerformed(new ActionEvent(this, 0, "")); 099 } 100 fireEditingStopped(); 101 return true; 102 } 103 104 // ------ Implementing TableCellEditor ------ 105 /** 106 * Sets an initial value for the combo box. 107 * Returns the combo box that should be added to the client's Component hierarchy. 108 * Once installed in the client's hierarchy this combo box will then be able to draw and receive user input. 109 * @param table the JTable that is asking the editor to edit; can be null 110 * @param value the value of the cell to be edited; null is a valid value 111 * @param isSelected will be ignored 112 * @param row the row of the cell being edited 113 * @param column the column of the cell being edited 114 * @return the combo box for editing 115 */ 116 public java.awt.Component getTableCellEditorComponent(javax.swing.JTable table, Object value, boolean isSelected, int row, int column) { 117 comboBox.setSelectedItem(value); 118 return comboBox; 119 } 120 121 // ------ Implementing TreeCellEditor ------ 122 // public java.awt.Component getTreeCellEditorComponent(javax.swing.JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { 123 // String stringValue = tree.convertValueToText(value, isSelected, expanded, leaf, row, false); 124 // comboBox.setSelectedItem(stringValue); 125 // return comboBox; 126 // } 127 128 class Handler extends KeyAdapter implements PropertyChangeListener { 129 public void keyPressed(KeyEvent keyEvent) { 130 int keyCode = keyEvent.getKeyCode(); 131 if (keyCode==KeyEvent.VK_ENTER) stopCellEditing(); 132 } 133 public void propertyChange(PropertyChangeEvent e) { 134 if (e.getPropertyName().equals("editor")) { 135 ComboBoxEditor editor = comboBox.getEditor(); 136 if (editor!=null && editor.getEditorComponent()!=null) { 137 JComponent editorComponent = (JComponent) comboBox.getEditor().getEditorComponent(); 138 editorComponent.addKeyListener(this); 139 editorComponent.setBorder(null); 140 } 141 } 142 } 143 } 144 }