How to configure JComboBox so that the popup is JTree (instead of a list)?

I am trying to create a combo box so that I can use any control that I prefer in the popup, in my particular case JTree. After seeing how JComboBox is implemented, the popup is actually created by the delegate of the user interface. The problem with changing this is that it will need to be re-implemented for every look and style, which I don't want to do ...

Basically, I want the component to look the same as JComboBox (in its current appearance), and the popup window to look like JTree (in its current style).

What is the easiest way to do this?

+4
source share
5 answers

JComboBox alone cannot do what you need. If you absolutely agree with the concept that it acts like a JComboBox, you can make the JButton popup JPanel when clicked. Then JPanel can have everything you need inside (JTree, etc.).

+2
source

I had a desire to create something like that.

At first I tried to implement something along the lines suggested by Varun, but it turned out to be a bit messy, and I'm a little nervous when I start playing with ComponentUI objects (I would prefer to leave such a thing to L & F). If anyone has a good example of this, I would be interested to see it.

So, I tried the button approach ... and thought that I would share the code with the SO community:

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.plaf.basic.BasicInternalFrameUI; import javax.swing.plaf.metal.MetalComboBoxIcon; public class MockJComboBox extends JPanel { private boolean _isPoppedUp = false; public MockJComboBox(String label, final JComponent toShow) { setLayout(new BorderLayout()); JLabel jLabel = new JLabel(label); jLabel.setBackground(Color.WHITE); add(jLabel, BorderLayout.CENTER); Icon icon = new MetalComboBoxIcon(); final JInternalFrame popup = new JInternalFrame(null, false, false, false, false); final JPanel panel = new JPanel(new BorderLayout()); panel.add(new JScrollPane(toShow), BorderLayout.CENTER); if(!(System.getProperty("os.name").startsWith("Mac OS"))){ BasicInternalFrameUI ui = (BasicInternalFrameUI) popup.getUI(); ui.getNorthPane().setPreferredSize(new Dimension(0,0)); } popup.setBorder(null); popup.setContentPane(panel); popup.pack(); popup.setVisible(true); final JButton dropDownButton = new JButton(icon); dropDownButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { _isPoppedUp = !_isPoppedUp; Container parent = getParent(); if (_isPoppedUp) { popup.setLocation(panel.getX(), panel.getY() + panel.getHeight()); popup.setSize(panel.getWidth(), toShow.getHeight()); parent.add(popup); } else { parent.remove(popup); parent.repaint(); } } }); add(dropDownButton, BorderLayout.EAST); } public boolean isPoppedUp() { return _isPoppedUp; } } 

If you noticed any errors or have any suggestions for improving this code, I would be grateful for your comments!

+1
source

You just need to extend BasicComboBoxUI and then override the required methods like

 public static ComponentUI createUI( JComponent c) 

and

 protected ComboPopup createPopup() 

Creating a custom ComboPopup will require your efforts when you cannot use BasicComboPopUp because it extends JPopUpMenu

 public class BasicComboPopup extends JPopupMenu implements ComboPopup 

So, in your case, you can extend JTree and implement ComboPopup.

I doubt that "the problem with the change is that it will need to be redone for each appearance." I do not think there will be a problem of re-implementation.

BasicComboPopup looks different in different views and sensations because it is JPopupMenu, which in turn will have UI delegates. Therefore, if you simply extend JTree, you should not have problems with other appearance and sensations.

0
source

The answer to using a button that calls JPanel using JTree is correct. In response to Carcassi's comment, you can use your own TableCellRenderer to change it so it doesn't look like a traditional button.

0
source

Further research on the Internet revealed that Jidesoft , which describes itself as a “professional Java and Swing provider,” is creating a package called JIDE Grids that includes AbstractComboBox — a description for which he would do so.

However, this is a paid package, and I have not tried it ... If someone used this, could they comment on the experience?

0
source

All Articles