Add Blank Space to JComboBox renderer
Hello,
I want to know if there is a way to add a blank space above all the items that exist in a JComboBox renderer? I tried JSeparator(), but either it isn't the right way to go about this or I'm not sure how to use it. Please help out.
Thanks!
Here's my SSCCE:
(I want the space above the green-colored divider.)
import java.awt.Color;
import java.awt.Component;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JFrame;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JSeparator;
import javax.swing.border.MatteBorder;
publicclass MyComboBoxTest{
/**
* @param args
*/
publicstaticvoid main(String[] args){
JFrame frame =new JFrame("My ComboBox Example");
final JComboBox myComboBox =new JComboBox();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(150, 50);
frame.getContentPane().add(myComboBox);
frame.setLocation(300, 300);
frame.setVisible(true);
Hashtable h =new Hashtable();
h.put("key1","value1");
h.put("key2","value2");
h.put("key3","value3");
h.put("key4","value4");
h.put("key5","value5");
Vector v =new Vector(h.keySet());
Collections.sort(v);
for(Enumeration e=v.elements();e.hasMoreElements();)
{
//myComboBox.getModel().addElement(e.nextElement().toString());
myComboBox.addItem(e.nextElement());
}
myComboBox.setRenderer(new DefaultListCellRenderer()
{
public Component getListCellRendererComponent(JList list, Object value,
int index,boolean isSelected,boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(index==0)
{
myComboBox.add(new JSeparator(), 0);
setBorder(new MatteBorder(2, 0, 0, 0, Color.GREEN));
}
return comp;
}
});
}
}
# 1
You can use a CompoundBorder. Create an EmptyBorder to go along with the MatteBorder.
# 2
Thank you for your help :) I'm now very close to where I want to be. However, when I select the first item on the dropdown, both the first item and the emptyBorder get selected. I know it's becuz I specify if(index==0). And I actually want just the first item or the border to be selected. Is there a way to achieve this?
Here's how my SSCCE looks right now:
import java.awt.Color;
import java.awt.Component;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JFrame;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
public class MyComboBoxTest{
/**
* @param args
*/
public static void main(String[] args) {
JFrame frame = new JFrame("My ComboBox Example");
final JComboBox myComboBox = new JComboBox();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(150, 50);
frame.getContentPane().add(myComboBox);
frame.setLocation(300, 300);
frame.setVisible(true);
Hashtable h = new Hashtable();
h.put("key1","value1");
h.put("key2","value2");
h.put("key3","value3");
h.put("key4","value4");
h.put("key5","value5");
Vector v = new Vector(h.keySet());
Collections.sort(v);
for(Enumeration e=v.elements();e.hasMoreElements();)
{
//myComboBox.getModel().addElement(e.nextElement().toString());
myComboBox.addItem(e.nextElement());
}
myComboBox.setRenderer(new DefaultListCellRenderer()
{
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(index==0)
{
setBorder(new CompoundBorder(new EmptyBorder(10, 0, 0, 0), new MatteBorder(2, 0, 0, 0, Color.GREEN)));
}
return comp;
}
});
}
}
# 3
> And I actually want just the first item or the border to be selected. Add a String containing a single space as the first item of the combo box.
# 4
Do you mean a line such as, myComboBox.insertItemAt(" ", index); when index=0?Becuz when I do that, all the items in myComboBox get deleted.
# 5
Well, I used addItem(..) before the loop and I also used insertItemAt(...) after the loop. They both worked fine for me.Maybe the real question is, why to you want an empty entry as the first element?. Maybe there is another solution if we know what you are trying to do.
# 6
Hi! Thanks for your help. I tried it and it worked for me, too. And you made a very good point. That is the real question, actually.
So, in my project, I actually want the blank space to appear when only the 5 keys are in the box. So, when my ComboBox only contains these 5 keys, I need to see a divider as well as a space on top of the 5 elements. If I add anything more, the space is supposed to disappear and the MatteBorder will separate the newly entered items from the other 5 keys. This is what I'm trying to achieve and I've been working on the comboBox's renderer to do this. I also add a ComponentListener to my comboBox, and when the component is shown, I add the space when only the 5 items are in the comboBox.
Thanks and I'm looking forward to your help.
Message was edited by:
programmer_girl
# 7
ok it's been 3 hours and I haven't received a response. Maybe I should redefine my problem, so that it'll start making sense.
Basically, what I want to do is, separate "item" components from "key" components in the following JComboBox. In the following code, the divider gets added every time it recognizes an "item" variable. I want the divider to only be added once between the last key variable and the last item variable. And I don't think I can use the index variable from getListCellRendererComponent to do this, because index always shows whichever index is being pointed to in the renderer. This is what confuses me and what I need help with. Thanks! and please help out.
import java.awt.Color;
import java.awt.Component;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JFrame;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
public class MyComboBoxTest{
/**
* @param args
*/
public static void main(String[] args) {
JFrame frame = new JFrame("My ComboBox Example");
final JComboBox myComboBox = new JComboBox();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(150, 50);
frame.getContentPane().add(myComboBox);
frame.setLocation(300, 300);
frame.setVisible(true);
Hashtable h = new Hashtable();
h.put("key1","value1");
h.put("key2","value2");
h.put("key3","value3");
h.put("key4","value4");
h.put("key5","value5");
h.put("item1", "value6");
h.put("item2", "value7");
h.put("item3", "value8");
h.put("item4", "value9");
final Vector v = new Vector(h.keySet());
Collections.sort(v);
myComboBox.insertItemAt("", 0);
for(Enumeration e=v.elements();e.hasMoreElements();)
{
//myComboBox.getModel().addElement(e.nextElement().toString());
myComboBox.addItem(e.nextElement());
}
myComboBox.insertItemAt(" ", 0);
myComboBox.setRenderer(new DefaultListCellRenderer()
{
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
for(Enumeration e=v.elements();e.hasMoreElements();)
{
if(e.nextElement().toString().startsWith("item"))
{
setBorder(new MatteBorder(1, 0, 0, 0, Color.GREEN));
}
}
return comp;
}
});
}
}
# 8
if I understand your problem, then here is a correction to the posted code
myComboBox.setRenderer(new DefaultListCellRenderer()
{
int borderDrawIndex = -1;
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value != null && value.toString().startsWith("key") &&
(borderDrawIndex == index || borderDrawIndex == -1) ) {
setBorder( new MatteBorder(1,0,0,0,Color.GREEN) );
borderDrawIndex = index;
}
return comp;
}
});
ICE
# 9
Maybe something like this:
myComboBox.setRenderer(new DefaultListCellRenderer()
{
Border border = new MatteBorder(1, 0, 0, 0, Color.GREEN);
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null && value.toString().startsWith("key"))
{
if (index > 0 && list.getModel().getElementAt(index - 1).toString().startsWith("item"))
{
setBorder(border);
}
}
return comp;
}
});
# 10
Thank you so much! yes, they both work :)