?
Solved

In JComboBox, how do i control the space  between the dropdown and the dropdown icon?

Posted on 2008-06-09
12
Medium Priority
?
643 Views
Last Modified: 2010-05-18
Hi,
In JComboBox, how do i control the space  between the dropdown and the dropdown icon?
Using a renderer does not work, as it just elongates the dropdown.  I need to control the space in between the dropdown component and the button.

If you run the code below, you will see a dropdown in a panel, with "V" denoting the dropdown icon
and "|| ||" representing the dropdown
||Rabbit    || V
I want to make the dropdown look like
||Rabbit    ||         V

I think I have to modify the MetalComboBoxUI or BasicComboBoxUI, but I'm not sure how.

Thanks
Jamie

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
 
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class ComboBoxSpace extends JPanel {
    JComboBox petList;
    public ComboBoxSpace() {
        String[] petStrings = new String[5];
        petStrings[0] = "Bird";
        petStrings[1] = "Cat";
        petStrings[2] = "Dog";
        petStrings[3] = "Rabbit";
        petStrings[4] = "Pig";        
 
        // Create the combo box
        petList = new MyJComboBox(petStrings);
        petList.setEditable(true);
        petList.setSelectedIndex(3);        
 
        // Layout the demo
        setLayout(new BorderLayout());
        add(petList, BorderLayout.NORTH);
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }
    
    public static class MyJComboBox extends JComboBox {
 
	public MyJComboBox (String[] s) {
	    super(s);
	}
    }
    
 
    public static void main(String s[]) {
        JFrame frame = new JFrame("ComboBoxSpace");
 
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
 
        frame.getContentPane().add(new ComboBoxSpace(), BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

Open in new window

0
Comment
Question by:jamie_lynn
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 26

Expert Comment

by:ksivananth
ID: 21749392
try adding more spaces,

petStrings[3] = "Rabbit                              ";
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 21749690
0
 
LVL 17

Expert Comment

by:Dejan Pažin
ID: 21751477

The following code will display a wide button. You have to create the widebuttton.png which is empty on the left side and has a drop down triangle on the right side.

The button will be as wide as the png.



import javax.swing.*;
import javax.swing.plaf.metal.MetalComboBoxUI;
import javax.swing.plaf.metal.MetalComboBoxButton;
import java.util.Vector;
import java.awt.*;
 
public class WideJComboButton extends JFrame {
 
    public WideJComboButton() {
        Vector v = new Vector();
        v.add("A simple ");
        v.add("wider button ");
        v.add("example");
        JComboBox combo = new WideButtonComboBox(v);
        add(combo);
        pack();
        setVisible(true);
    }
 
    public static void main(String[] args) {
        new WideJComboButton();
    }
 
 
    public class WideButtonComboBox extends JComboBox {
 
        public WideButtonComboBox(Vector c) {
            super(c);
            setUI(new MyComboUI());
        }
 
        public class MyComboUI extends MetalComboBoxUI {
            protected JButton createArrowButton() {
                JButton button = new MetalComboBoxButton(comboBox, new ImageIcon("widebuttton.png"), currentValuePane, listBox);
                button.setMargin(new Insets(0, 1, 1, 3));
                return button;
            }
        }
    }
}

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:jamie_lynn
ID: 21753088
Adding more space is not what I want, since it will look like
||Rabbit                || V
instead of
||Rabbit    ||             V

Adding space inside the button does not work either, since the button is wide, and the user can see the wide button when they click on the button.

CEHJ,
Could you attach a code snippet?

Thanks
Jamie
0
 
LVL 17

Expert Comment

by:Dejan Pažin
ID: 21757412

Jamie, pls try to explain again what it is that you want, since I am not sure now. This is what you stated in your question:

---------------------------------------------
I want to make the dropdown look like
||Rabbit    ||         V
---------------------------------------------

In the above picture the right side represents the button, is that correct? If this is correct then the solution I posted will work.

What confuses me is your last post, where you say:
"....since the button is wide, and the user can see the wide button when they click on the button."

I dont understand it, because you are saying that you want to have a wide button.
0
 

Author Comment

by:jamie_lynn
ID: 21757656
Hi dejanpazin,

I want to keep the button the same size, but put more spaces between the dropdown and the dropdown button.
| V | will represent the button
|| Rabbit || will represent the dropdown

I want the combobox to look like below where there are spaces in between
|| Rabbit ||        | v |

I ran your code snippet, and it shows, space in the button, but not between
|| Rabbit ||  |       v |

Thanks
Jamie
0
 
LVL 17

Expert Comment

by:Dejan Pažin
ID: 21757863

Ok. I think I now know what you want. Try the code below.
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import java.util.Vector;
import java.awt.*;
 
public class WideJComboButton extends JFrame {
 
    public WideJComboButton() {
        Vector v = new Vector();
        v.add("A simple ");
        v.add("empty space ");
        v.add("example");
        //JComboBox combo = new WideButtonComboBox(v);
        JComboBox combo = new JComboBox(v);
        combo.setRenderer(new MyRenderer());
        System.out.println("combo.getRenderer() = " + combo.getRenderer().getClass());
        add(combo);
        pack();
        setVisible(true);
    }
 
    public static void main(String[] args) {
        new WideJComboButton();
    }
 
    private class MyRenderer extends BasicComboBoxRenderer {
 
 
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component component =  super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            JLabel label = new JLabel();
            label.setOpaque(true);
            label.setBackground(Color.white);
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(component, BorderLayout.WEST);
            panel.add(label);
            if (!isSelected){
                component.setBackground(Color.white);
            } 
            return panel;
        }
    }
}

Open in new window

0
 

Author Comment

by:jamie_lynn
ID: 21762621
Hi dejanpazin:,

Using a renderer above gives me, with different colors
|| Rabbit             || | v |

But I need to put space between the dropdown and the dropdown image
|| Rabbit ||            | v |

The reason why i am asking for this is that the dropdown is not a list for me, it is an complex component.  I am just using a list as an example to make it simpler.

Thanks
Jamie
0
 
LVL 17

Expert Comment

by:Dejan Pažin
ID: 21766741

OK. In the following solution the actual button is not displayed, but there is one added next to the combobox. The space in between is controlled with the width of the Test.png.

This will display as

|| Rabbit ||            | v |

The | v | is an ordinary button, you can create one witch matches the combobox button.


import javax.swing.*;
import javax.swing.plaf.metal.*;
import java.util.Vector;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
 
public class WideJComboButton extends JFrame {
 
    public WideJComboButton() {
        Vector v = new Vector();
        v.add("Rabbit");
        v.add("more rabbit");
        v.add("some more");
        final WideButtonComboBox combo = new WideButtonComboBox(v);
        setLayout(new FlowLayout());
        add(combo);
        JButton fakeButton = new JButton("V");
        fakeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                combo.doClick();
            }
        });
        add(fakeButton);
        pack();
        setVisible(true);
    }
 
    public static void main(String[] args) {
        new WideJComboButton();
    }
 
    public class WideButtonComboBox extends JComboBox {
 
        public WideButtonComboBox(Vector c) {
            super(c);
            setUI(new MyComboUI());
        }
 
        public void doClick() {
            this.showPopup();
        }
 
 
        public class MyComboUI extends MetalComboBoxUI {
 
 
            protected JButton createArrowButton() {
 
                JButton button = new MetalComboBoxButton(comboBox,
                        new ImageIcon("Test.png"),
                        false,
                        currentValuePane,
                        listBox);
                button.setMargin(new Insets(0, 1, 1, 3));
                return button;
            }
 
            protected void installComponents() {
                arrowButton = createArrowButton();
                if (arrowButton != null) {
                    configureArrowButton();
                }
 
                if (comboBox.isEditable()) {
                    addEditor();
                }
 
                comboBox.add(currentValuePane, BorderLayout.WEST);
            }
        }
    }
}

Open in new window

0
 

Author Comment

by:jamie_lynn
ID: 21772227
Looks great!
One minor thing. How do I close the popup when clicking on the fakebutton?
It seems like isPopupVisible() always return false

Thanks
Jamie
0
 
LVL 17

Accepted Solution

by:
Dejan Pažin earned 2000 total points
ID: 21776716


Here is one solution for that. Its not really perfect, but it works fine in most cases (in some cases you may have to click twice to show the popup).

You can work on that to improve the solution.
import javax.swing.*;
import javax.swing.plaf.metal.*;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.basic.BasicComboPopup;
import java.util.Vector;
import java.awt.*;
import java.awt.event.*;
 
public class WideJComboButton extends JFrame {
 
    public WideJComboButton() {
        Vector v = new Vector();
        v.add("A simple ");
        v.add("empty space ");
        v.add("example");
        FakeButton fakeButton = new FakeButton("V");
        final WideButtonComboBox combo = new WideButtonComboBox(v, fakeButton);
        setLayout(new FlowLayout());
        add(combo);
        fakeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                FakeButton button = (FakeButton)e.getSource();
                if (!button.isPopupVisible()){
                    button.setPopupVisible(true);
                    combo.showPopup();
                } else {
                    combo.hidePopup();
                    button.setPopupVisible(false);
                }
            }
        });
 
 
        add(fakeButton);
        pack();
        setVisible(true);
    }
 
    private class FakeButton extends JButton {
       private boolean isPopupVisible;
 
        public FakeButton(String text){
            super(text);
        }
 
        public boolean isPopupVisible() {
            return isPopupVisible;
        }
 
        public void setPopupVisible(boolean popupVisible) {
            isPopupVisible = popupVisible;
        }
    }
 
    public static void main(String[] args) {
        new WideJComboButton();
    }
 
    public class WideButtonComboBox extends JComboBox {
        private FakeButton fakeButton;
 
        public WideButtonComboBox(Vector c, FakeButton fakeButton) {
            super(c);
            this.fakeButton = fakeButton;
            setUI(new MyComboUI());
        }
 
        public void setPopupVisible(boolean v) {
            super.setPopupVisible(v);
            fakeButton.setPopupVisible(v);
        }
 
        public class MyComboUI extends MetalComboBoxUI {
 
            protected JButton createArrowButton() {
 
                JButton button = new MetalComboBoxButton(comboBox,
                        new ImageIcon("Test.png"),
                        false,
                        currentValuePane,
                        listBox);
                button.setMargin(new Insets(0, 1, 1, 3));
                return button;
            }
 
 
            protected void installComponents() {
                arrowButton = createArrowButton();
                if (arrowButton != null) {
                    configureArrowButton();
                }
 
                if (comboBox.isEditable()) {
                    addEditor();
                }
 
                comboBox.add(currentValuePane, BorderLayout.WEST);
            }
        }
    }
}

Open in new window

0
 

Author Comment

by:jamie_lynn
ID: 21782994
Works great!
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
The viewer will learn how to implement Singleton Design Pattern in Java.
Suggested Courses
Course of the Month10 days, 1 hour left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question