Reputation: 69
I've been looking for a way to have a JComboBox
where the items in the list are displayed normally, but in the edit field is showed with just a number.
I came across this code (only slightly modified to my needs):
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class ComboBoxItem extends JFrame implements ActionListener {
public ComboBoxItem() {
Vector model = new Vector();
model.addElement( new Item(1, "car" ) );
model.addElement( new Item(2, "plane" ) );
model.addElement( new Item(3, "train" ) );
model.addElement( new Item(4, "boat" ) );
JComboBox comboBox;
comboBox = new JComboBox( model );
comboBox.addActionListener( this );
getContentPane().add(comboBox, BorderLayout.NORTH );
comboBox = new JComboBox( model );
// I want the comboBox editable.
//comboBox.setEditable(true);
comboBox.setRenderer( new ItemRenderer() );
comboBox.addActionListener( this );
getContentPane().add(comboBox, BorderLayout.SOUTH );
}
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
Item item = (Item)comboBox.getSelectedItem();
System.out.println( item.getId() + " : " + item.getDescription() );
}
class ItemRenderer extends BasicComboBoxRenderer {
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value != null) {
Item item = (Item)value;
setText( item.getDescription().toUpperCase() );
}
if (index == -1) {
Item item = (Item)value;
setText( "" + item.getId() );
}
return this;
}
}
class Item {
private int id;
private String description;
public Item(int id, String description) {
this.id = id;
this.description = description;
}
public int getId() {
return id;
}
public String getDescription() {
return description;
}
public String toString() {
return description;
}
}
public static void main(String[] args) {
JFrame frame = new ComboBoxItem();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible( true );
}
}
This works well, until I make the comboBox editable with comboBox.setEditable(true);
.
Background info:
I plan to populate the popup list with object from a database as the user types in the edit field. When the user then selects an item from the popup list, the edit field should display only the object's id
, but the popup list should show some more information so the user can make an informed choice.
Can anyone help me make this work whether editable is on or off?
Upvotes: 1
Views: 3087
Reputation: 3103
What you need is to override the default editor of the combo box because when you set the combo box to be editable, it uses the editor to render what you selected in the drop down list.
Below is one way of implementation using BasicComboBoxEditor. You just need to override the setItem method.
comboBox.setEditor(new ItemEditor());
class ItemEditor extends BasicComboBoxEditor {
public void setItem(Object anObject) {
Item item = (Item) anObject;
editor.setText(item.getId() + "");
}
}
Upvotes: 3
Reputation: 343
If I correctly understand your request, you can use your own javax.swing.ComboBoxEditor
.
I just took your example and added a very quick'n'dirty ComboBoxEditor which uses a javax.swing.JTextField
and set this as the seconds ComboBox editor.
Maybe this example shows you a way to handle your problem.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.ComboBoxEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class ComboBoxItem extends JFrame implements ActionListener {
public ComboBoxItem() {
final Vector model = new Vector();
model.addElement(new Item(1, "car"));
model.addElement(new Item(2, "plane"));
model.addElement(new Item(3, "train"));
model.addElement(new Item(4, "boat"));
JComboBox comboBox;
comboBox = new JComboBox(model);
comboBox.addActionListener(this);
this.getContentPane().add(comboBox, BorderLayout.NORTH);
comboBox = new JComboBox(model);
// I want the comboBox editable.
comboBox.setEditable(true);
comboBox.setRenderer(new ItemRenderer());
comboBox.setEditor(new MyComboBoxEditor()); ///<------- Quick'n'Dirty editor added
comboBox.addActionListener(this);
this.getContentPane().add(comboBox, BorderLayout.SOUTH);
}
@Override
public void actionPerformed(final ActionEvent e) {
final JComboBox comboBox = (JComboBox) e.getSource();
final Item item = (Item) comboBox.getSelectedItem();
System.out.println(item.getId() + " : " + item.getDescription());
}
class MyComboBoxEditor implements ComboBoxEditor {
JTextField editor;
Item editedItem;
@Override
public void addActionListener(final ActionListener l) {
}
@Override
public Component getEditorComponent() {
if (this.editor == null) {
this.editor = new JTextField();
}
return this.editor;
}
@Override
public Object getItem() {
return this.editedItem;
}
@Override
public void removeActionListener(final ActionListener l) {
// TODO Auto-generated method stub
}
@Override
public void selectAll() {
// TODO Auto-generated method stub
}
@Override
public void setItem(final Object anObject) {
this.editedItem = (Item) anObject;
this.editor.setText(String.valueOf(this.editedItem.getId()));
}
}
class ItemRenderer extends BasicComboBoxRenderer {
@Override
public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected,
final boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
final Item item = (Item) value;
this.setText(item.getDescription().toUpperCase());
}
if (index == -1) {
final Item item = (Item) value;
this.setText("" + item.getId());
}
return this;
}
}
class Item {
private final int id;
private final String description;
public Item(final int id, final String description) {
this.id = id;
this.description = description;
}
public int getId() {
return this.id;
}
public String getDescription() {
return this.description;
}
@Override
public String toString() {
return this.description;
}
}
public static void main(final String[] args) {
final JFrame frame = new ComboBoxItem();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
You can find the editor between the lines 47 and 88.
Regards
Upvotes: 1