Re: Controlling the scroll pane in JComboBox
Good suggestion, Pete! The code is below.
I welcome comments about all aspects of my code, but for now I'm
mostly interested in why there are no scroll bars when there is a
query and a panel is used for rendering...
Many thanks in advance,
Aaron
package pmg;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.ArrayList;
public class ChoiceGui extends JComboBox {
private ArrayList<String> myList = new ArrayList<String>();
private boolean mySettingItem = false;
private boolean myRespondingToChangedQuery = false;
public static void main(String[] args) {
ArrayList<String> choices = new ArrayList<String>();
choices.addAll(java.util.Arrays.asList(
"Hello;Hello, World!;A very looooooooooooooong String;Very
Slow;Bad dog, bad!".split(";")));
JFrame frame = new JFrame("Choice");
frame.getContentPane().add(new ChoiceGui(choices));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public ChoiceGui(ArrayList<String> choices) {
myList = choices;
setEditor(new Editor());
setRenderer(new Renderer3());
setBackground(Color.getHSBColor(1f/6, .2f, 1f));
this.setPreferredSize(new Dimension(150, 22));
for (int s = 0; s < myList.size(); s++)
this.addItem(myList.get(s));
this.setSelectedIndex(-1);
this.setEditable(true); // This is when the first setItem() is
called!
}
public class Editor implements ComboBoxEditor {
private JTextField myTextField = new JTextField();
public void addActionListener(ActionListener l)
{ myTextField.addActionListener(l); }
public void removeActionListener(ActionListener l) { }
public void setItem(Object item) {
if (myRespondingToChangedQuery)
return;
System.out.println("setItem called!!!");
mySettingItem = true;
if (item != null) {
myTextField.setText(item.toString());
myTextField.setCaretPosition(0);
}
else if (!myRespondingToChangedQuery) // The value of
SuperChoice changed for a different reason, so the query must be
reset.
myTextField.setText("");
mySettingItem = false;
}
public void selectAll() { myTextField.selectAll(); }
public Object getItem() { return null; }
public Component getEditorComponent() { return myTextField; }
public Editor() {
myTextField.getDocument().addDocumentListener(new
DocumentListener() {
public void dodo() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
myRespondingToChangedQuery = true;
String q =
((JTextField)getEditor().getEditorComponent()).getText();
removeAllItems();
for (int i = 0; i < myList.size(); i++)
if
(myList.get(i).toUpperCase().contains(q.toUpperCase()))
addItem(myList.get(i));
setPopupVisible(true);
myRespondingToChangedQuery = false;
}
});
}
public void changedUpdate(DocumentEvent e) {
if (mySettingItem)
return;
dodo();
}
public void insertUpdate(DocumentEvent e) {
if (mySettingItem)
return;
dodo();
}
public void removeUpdate(DocumentEvent e) {
if (mySettingItem)
return;
dodo();
}
});
}
}
class Renderer3 implements ListCellRenderer {
JPanel panel = new JPanel();
JLabel label = new JLabel();
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JLabel label3 = new JLabel();
public Renderer3() {
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(label1);
panel.add(label2);
panel.add(label3);
panel.setOpaque(true);
panel.setBackground(Color.RED);
Font font = label1.getFont();
label.setFont(new Font(font.getName(), Font.PLAIN,
font.getSize()-2));
label1.setFont(new Font(font.getName(), Font.PLAIN,
font.getSize()));
label2.setFont(new Font(font.getName(), Font.BOLD,
font.getSize()));
label3.setFont(new Font(font.getName(), Font.PLAIN,
font.getSize()));
label.setOpaque(true);
panel.setBackground(Color.getHSBColor(1f/6, .2f, 1f));
}
public Component getListCellRendererComponent(JList list, Object
value, int index, boolean isSelected, boolean cellHasFocus) {
String str = (value!=null)?value.toString():"null";
String q =
((JTextField)getEditor().getEditorComponent()).getText();
if (q.length() != 0 &&
str.toUpperCase().indexOf(q.toUpperCase()) != -1) {
int start = str.toUpperCase().indexOf(q.toUpperCase());
label1.setText(str.substring(0, start));
label2.setText(str.substring(start, start + q.length()));
label3.setText(str.substring(start + q.length()));
panel.setBackground(isSelected?
list.getSelectionBackground():list.getBackground());
panel.setForeground(isSelected?
list.getSelectionForeground():list.getForeground());
return panel;
}
else {
Font font = label.getFont();
label.setFont(new Font("Dialog", Font.PLAIN, 12));
label.setBackground(isSelected?
list.getSelectionBackground():list.getBackground());
label.setForeground(isSelected?
list.getSelectionForeground():list.getForeground());
label.setText(" " + str);
return label;
}
}
}
}