How to put a JButton inside a JComboBox

2019-07-07 03:46发布

I would like to put a JButton inside a JComboBox. This button lets users browse for files. The file the user selects gets added to the JComboBox list. How do I do this? Do I use some kind of a Renderer? Thank you.

EDIT: After reading more about ListCellRenderer I tried the following code:

JComboBox comboBox = new JComboBox(new String[]{"", "Item1", "Item2"});
ComboBoxRenderer renderer = new ComboBoxRenderer();
comboBox.setRenderer(renderer);

class ComboBoxRenderer implements ListCellRenderer {

    public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {

        JButton jbutton = new JButton("Browse");

        return jbutton;
    }
}

The problem with the above is that the Button "Browse" will be added 3 times and I want it to display only once and below it to display Item1 and Item2 as normal/regular combobox selection objects.

4条回答
ら.Afraid
2楼-- · 2019-07-07 04:26

Indeed, you will have to use a custom renderer as explained on http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer.

查看更多
可以哭但决不认输i
3楼-- · 2019-07-07 04:26

Depending on where you want to put the search button, you could take a look at the xswingx Prompt/Buddy API. You could use this to "buddy" the browse button with the editor field

Or you could simply add a browse button next to the combo box.

查看更多
劳资没心,怎么记你
4楼-- · 2019-07-07 04:27

After trying out many things I think I figured out the Answer, I am sure it will look very easy when you see it:

        JComboBox comboBox = new JComboBox(new String[]{"Item1", "Item2"});
        ComboBoxRenderer renderer = new ComboBoxRenderer();
        comboBox.setRenderer(renderer);
        comboBox.addItem("<<BROWSE>>");

class ComboBoxRenderer implements ListCellRenderer {

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index,         boolean isSelected, boolean cellHasFocus) {
            if (value.equals("<<BROWSE>>")) {
                JButton btn = new JButton("Browse");
                return btn;
            } else {
                JLabel lbl = new JLabel(value.toString());
                lbl.setOpaque(true);
                return lbl;
            }
        }
    }

You can now customize the button and labels any way you wish.

查看更多
狗以群分
5楼-- · 2019-07-07 04:49

I would avoid the JButton. It is perfectly possible to get the image of a JButton inside your combobox, but it will not behave itself as a button. You cannot click it, it never gets visually 'pressed' nor 'released', ... . In short, your combobox will contain an item which behaves unfamiliar to your users.

The reason for this is that the components you return in the getListCellRendererComponent method are not contained in the JCombobox. They are only used as a stamp. That also explains why you can (and should) reuse the Component you return in that method, and not create new components the whole time. This is all explained in the JTable tutorial in the part about Renderers and Editors (explained for a JTable but valid for all other Swing components which use renderers and editors).

If you really want an item in the combobox that allows to show a file chooser, I would opt for something similar to the following SSCCE:

import javax.swing.JComboBox;
import javax.swing.JFrame;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class ComboboxTest {

  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame( "TestFrame" );
        JComboBox<String> comboBox = new JComboBox<>(new String[]{"Item1", "Item2"});
        final String browse = "<<BROWSE>>";
        comboBox.addItem( browse );
        comboBox.addItemListener( new ItemListener() {
          @Override
          public void itemStateChanged( ItemEvent e ) {
            if ( e.getStateChange() == ItemEvent.SELECTED && 
                browse.equals( e.getItem() ) ){
              System.out.println("Show filechooser");
            }
          }
        } );
        frame.add( comboBox );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setVisible( true );
        frame.pack();
      }
    } );
  }
}
查看更多
登录 后发表回答