我正在尝试创建一个组合框,以便我可以在弹出窗口中放置我喜欢的任何控件,在我的特定情况下是一个JTree。看看JComboBox是如何实现的,弹出窗口实际上是由UI委托创建的。改变这个问题的方法是需要为每个外观重新实现,这是我不想做的事情......
我基本上想要一个具有JComboBox外观和感觉的组件(在当前的外观中),弹出窗口是一个JTree(在当前的外观中)。
最简单的方法是什么?
答案 0 :(得分:2)
JComboBox本身无法做到你想要的。如果你完全坚持让它像JComboBox一样的概念,你可以让JButton在点击时弹出一个JPanel。然后JPanel可以拥有你想要的任何东西(JTree,等等)。
答案 1 :(得分:1)
我已经开始制作可以做这样的事了。
起初,我试图按照Varun建议的方式实现一些东西,但事实证明它有点混乱,当我开始玩ComponentUI对象时我有点紧张(我宁愿离开那种L& F)的事情。如果有人有这样做的好例子,我有兴趣看到它。
然后我尝试了按钮方法......并且认为我会与SO社区共享代码:
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;
}
}
如果您发现任何错误或有关如何改进此代码的建议,我将非常感谢您的评论!
答案 2 :(得分:0)
您只需要扩展BasicComboBoxUI,然后覆盖所需的方法,如
public static ComponentUI createUI( JComponent c)
和
protected ComboPopup createPopup()
创建自定义ComboPopup需要您在不能使用BasicComboPopUp的地方付出一些努力,因为它扩展了JPopUpMenu
public class BasicComboPopup extends JPopupMenu implements ComboPopup
因此,在您的情况下,您可能希望扩展JTree并实现ComboPopup。
我怀疑“改变的问题在于它需要为每个外观和感觉重新实施”。我不认为会有重新实施的问题。
BasicComboPopup在外观和感觉上看起来不同,因为它是一个JPopupMenu,而后者又会有UI委托。因此,如果您只是扩展一个JTree,那么您应该不会遇到不同外观的问题。
答案 3 :(得分:0)
使用弹出带有JTree的JPanel的按钮的答案是正确的。为了回应Carcassi的评论,您可以使用自定义TableCellRenderer进行更改,使其看起来不像传统按钮。
答案 4 :(得分:0)
进一步的网络研究显示,Jidesoft,他们称自己为“专业的Java和Swing组件提供商”,会生成一个名为JIDE Grids的软件包,其中包含AbstractComboBox - 其描述建议它会这样做。
然而,这是一个付费的套餐,我没有尝试过......如果有人使用过它,他们可以评论一下这个经历吗?