How to add JCheckBox objects to a JComboBox

Hello,

I want to find a way to add JCheckBox objects to the drop-down list in a JComboBox. When I expand my JComboBox, I want to be able to see my JCheckBox objects and select/deselect them. Here's my SSCCE. Apart from this, I have also tried using a JPopupMenu to put the JCheckBoxes in and add the JPopupMenu to JComboBox. I have also tried adding the JCheckBoxes directly to JComboBox, but neither has worked.

Please advice!

import java.awt.Component;

import javax.swing.DefaultListCellRenderer;

import javax.swing.JCheckBox;

import javax.swing.JFrame;

import javax.swing.JComboBox;

import javax.swing.JList;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

publicclass MyComboBoxTestextends JComboBox

{

/**

* @param args

*/

JComboBox myComboBox;

public MyComboBoxTest()

{

myComboBox =new JComboBox();

}

publicstaticvoid main(String[] args){

JFrame frame =new JFrame("My ComboBox");

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.setSize(150, 60);

frame.setLocation(300, 300);

final MyComboBoxTest myComboBox =new MyComboBoxTest();

JMenuBar menuBar =new JMenuBar();

JMenu menu =new JMenu();

frame.getContentPane().add(myComboBox);

myComboBox.add(menuBar);

menuBar.add(menu);

menu.add(new JCheckBox("Item1",false));

frame.setVisible(true);

myComboBox.setRenderer(new DefaultListCellRenderer()

{

public Component getListCellRendererComponent(JList list, Object value,

int index,boolean isSelected,boolean cellHasFocus)

{

System.out.println("Inside Renderer");

Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

return comp;

}

});

}

}

[3267 byte] By [programmer_girla] at [2007-11-27 11:28:15]
# 1

Anyone?!?!?!?!

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 2

> Anyone?!?!?!?!

You know, patience is virtue.

Download IconedCellRenderer from this site, http://www.geocities.com/icewalker2g/downloads/IconedCellRenderer.java Or visit the main page http://www.geocities.com/icewalker2g for other useful classes.

I have tweaked the IconedCellRenderer code just enough to work with your JComboBox (it was designed for JLists) so a little more tweaking may have to be done to get it to work perfectly.

import java.awt.Component;

import javax.swing.DefaultListCellRenderer;

import javax.swing.JCheckBox;

import javax.swing.JFrame;

import javax.swing.JComboBox;

import javax.swing.JList;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

public class MyComboBoxTest extends JComboBox

{

/**

* @param args

*/

JComboBox myComboBox;

public MyComboBoxTest()

{

myComboBox = new JComboBox();

}

public static void main(String[] args) {

final MyComboBoxTest myComboBox = new MyComboBoxTest();

for(int i = 0; i < 5; i++) {

myComboBox.addItem("Item " + i);

}

JMenuBar menubar = new JMenuBar();

JMenu menu = new JMenu();

//myComboBox.add(menuBar);

menubar.add(menu);

menu.add(new JCheckBox("Item1",false));

JFrame frame = new JFrame("My ComboBox");

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.setSize(150, 60);

frame.setLocation(300, 300);

frame.setJMenuBar( menubar );

frame.getContentPane().add(myComboBox);

frame.setVisible(true);

myComboBox.setRenderer( IconedCellRenderer.getCheckBoxRendererInstance() );

/*myComboBox.setRenderer(new DefaultListCellRenderer()

{

public Component getListCellRendererComponent(JList list, Object value,

int index, boolean isSelected, boolean cellHasFocus)

{

System.out.println("Inside Renderer");

Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

return comp;

}

});*/

}

}

icewalker2ga at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 3

Hello Ice! Thanks for your help.

I will be able to use your solution once I have the JAR file that recognizes EmptyIcon class. Right now, my code does not understand EmptyIcon() on IconCellRenderer. I've been looking for the jar file, but I'm not sure where to get it. The package for EmptyIcon is org.jdesktop.swingx.icon.EmptyIcon

Could you please get back to me at your earliest convenience?

Thanks!

Message was edited by:

programmer_girl

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 4

Hi, sorry for the frequent posts. My problem is actually solved :) Thanks for all your help! See you next time.

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 5

> Could you please get back to me at your earliest convenience?

Saw your post earlier but was on the move so could not put a reply toegther (almost did).

Just so you know, the EmptyIcon class used is not the one provided by the jdesktop package but my own simple implementation to use whenever I want a space the size of an Icon (usually in JMenuItems). here is the code

import java.awt.Component;

import java.awt.Graphics;

import javax.swing.Icon;

public class EmptyIcon implements Icon {

int width = 16, height = 16;

public EmptyIcon() {

setSize(16,16);

}

public EmptyIcon(int width, int height) {

setSize(width, height);

}

public void setSize(int width, int height) {

this.width = width;

this.height = height;

}

public int getIconWidth() {

return width;

}

public int getIconHeight() {

return height;

}

public void paintIcon(Component c, Graphics g, int x, int y) {

//g.setColor(c.getBackground());

//g.fillRect(x, y, getIconWidth(), getIconHeight() );

}

}

Could you also just let the community know how exactly you are solving your problem? Have you managed to come up with a custom renderer that uses a JCheckBox or you are using the above solution provided?

ICE

icewalker2ga at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 6

Hello,

Yeah I didn't end up using the swingx EmptyIcon either, I wrote my own, similar to yours and called it MyEmptyIcon. And yes, I did use your IconedCellRenderer implementation. Now I got one problem tho, I want the comboBox to show the word "Items" by default, but when I do the following line,

myComboBox.getModel().setSelectedItem("Items");

Items will be shown with a checkBox next to it, as well. So I'm trying to make changes to the getListCellRenderer() method or the IconCellRenderer(icon) constructor to make it go away. Do you have any suggestions?

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 7

did you try

myComboBox.setSelectedIndex(0);

Yannixa at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 8

The JComboBox renders the non-list display when the index is equal to -1, hence you'd have to put some simple code your getListCellRenderer method to return a simple lable when the index == -1

Below is a code snippet with the correction. See the bottom section with the comment

if(useIconBackground == false) {

if(isSelected)

iconLabel.setIcon(selIcon);

else

iconLabel.setIcon(icon);

if(useCheckBoxAsIcon()) {

if(selState == null) {

updateSelectionStateTrackers(list);

}

if(selStateHandler == null) {

list.addMouseListener( selStateHandler = new SelectionStateHandler(list) );

}

try {

box.setSelected( selState[index] );

} catch(Exception e) {}

}

if( shdPaintDivider() ) {

//if(index < theList.getModel().getSize() - 1 ) {

noback.setBorder( getBorder() );

setBorder( new EmptyBorder(1,1,1,1) );

//} else {

// noback.get

//}

}

// this should cause a JComboBox to paint the Label instead

// of the check box + label combination

if(index == -1) {

JLabel label = new JLabel( this.getText() );

if(iconLabel.getIcon() != null ) {

label.setIcon( iconLabel.getIcon() ); // maybe removed if icon not required

}

return label;

}

return noback;

}

I have also uploaded the fully updated code to my site. It also now includes EmptyIcon as an inner class for easy compilation. Added features are the ability to display hyperlink like items in the list, with hover text underline effects. This is still being tested so the code might not run perfectly. To use that, create the renderer call the method setDisplayItemsAsLinks(true) to enable hyperlink item display. It only unfortunate the code is not well documented.

ICE

icewalker2ga at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 9

Thank you ICE!!!!! Problem solved :)

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 10

Ice, do you have any idea how I can draw a line underneath my items?

Right now, when I set a MatteBorder in the getListCellRendererComponent method, it only draw under the text and not the JCheckBox. I know why this is the case, but I need the line to cover underneath the JCheckBox as well.

Please let me know.

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 11

ok, here's my updated code. If you can please take a look at it, you'll see what I'm talking about regarding the MatteBorder. It doesn't cover under the JCheckBox. I've tried calling paintComponent(Graphics g) where the code creates the new JCheckBox in IconedCellRenderer, but when it draws a line under the box, the box itself disappears.

Please help me out!

/*MyComboBoxTest.java*/

import javax.swing.JFrame;

import javax.swing.JComboBox;

import java.awt.Dimension;

public class MyComboBoxTest extends JComboBox

{

JComboBox myComboBox;

public MyComboBoxTest()

{

myComboBox = new JComboBox();

}

public static void main(String[] args) {

final MyComboBoxTest myComboBox = new MyComboBoxTest();

//Add Items to myComboBox

myComboBox.getModel().setSelectedItem("Items");

myComboBox.insertItemAt("Select All", 0);

myComboBox.insertItemAt("Item1",1);

myComboBox.insertItemAt("Item2",2);

myComboBox.insertItemAt("Item3",3);

myComboBox.insertItemAt("Item4",4);

myComboBox.insertItemAt("Item5",5);

//Add myComboBox to JFrame

JFrame frame = new JFrame("My ComboBox");

myComboBox.setPreferredSize(new Dimension(140,20));

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.setSize(150, 60);

frame.setLocation(300, 300);

frame.getContentPane().add(myComboBox);

frame.setVisible(true);

myComboBox.setRenderer( IconedCellRenderer.getCheckBoxRendererInstance() );

}

}

And Here in IconedCellRenderer, is where I'm trying to paint under JCheckBox

Inside method, createNoBackgroundPanel()

if(useCheckBoxAsIcon()) {

box = new JCheckBox()

{

public void paintComponent(Graphics g)

{

g.drawLine(0,20,20,20);

}

};

box.setOpaque(false);

noback.add( box, BorderLayout.WEST );

rect = box.getBounds();

} else {

noback.add( iconLabel, BorderLayout.WEST );

}

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 12

IconedCellRenderer is already designed to take care of that to some extent. It has a setPaintDivider method which you can use.

IconedCellRenderer renderer = IconedCellRenderer.getCheckBoxRendererInstance();

renderer.setPaintDivider(true);

// you can change the divider color by setting the hyperlink color

// this implementation will definately change. Was done for color

// consistency when using hyperlink display

renderer.setLinkColor( Color.red );

// you can also use an image as a divider

// uncomment and supply image.

//renderer.setDividerImage( new ImageIcon("image.gif") );

myComboBox.setRenderer( renderer );

ICE

icewalker2ga at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...
# 13

Thank you! Ice, you're truly a life saver!

programmer_girla at 2007-7-29 16:21:01 > top of Java-index,Desktop,Core GUI APIs...