【问题标题】:How to put a JButton inside a JComboBox如何将 JButton 放在 JComboBox 中
【发布时间】:2012-08-19 09:01:05
【问题描述】:

我想在 JComboBox 中放置一个 JButton。此按钮允许用户浏览文件。用户选择的文件被添加到 JComboBox 列表中。我该怎么做呢?我是否使用某种渲染器?谢谢你。

编辑: 在阅读了有关 ListCellRenderer 的更多信息后,我尝试了以下代码:

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;
    }
}

上面的问题是按钮“浏览”将被添加 3 次,我希望它只显示一次,并在其下方显示 Item1 和 Item2 作为普通/常规组合框选择对象。

【问题讨论】:

    标签: java swing render jbutton jcombobox


    【解决方案1】:

    在尝试了很多事情之后,我想我找到了答案,我相信当你看到它时它看起来很容易:

            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;
                }
            }
        }
    

    您现在可以随意自定义按钮和标签。

    【讨论】:

    • 1.不要创建新组件,而是在渲染器中重用和调整现有组件 2. 不能通过简单地使用渲染器来按下按钮。
    【解决方案2】:

    我会避免使用JButton。在您的组合框中获取JButton 的图像是完全可能的,但它本身不会像一个按钮一样。您无法单击它,它永远不会在视觉上被“按下”或“释放”,...。简而言之,您的组合框将包含一个您的用户不熟悉的项目。

    原因是getListCellRendererComponent方法中返回的组件不包含在JCombobox中。它们仅用作邮票。这也解释了为什么您可以(并且应该)重用您在该方法中返回的Component,而不是一直创建新组件。这一切都在JTable 教程中关于Renderers and Editors 的部分中进行了解释(针对JTable 进行了解释,但对使用渲染器和编辑器的所有其他Swing 组件有效)。

    如果您真的想要组合框中的项目允许显示文件选择器,我会选择类似于以下 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();
          }
        } );
      }
    }
    

    【讨论】:

    • 感谢罗宾的详细解答。您在上面发布的示例显示了如何将事件侦听器添加到浏览组件,但它仍然作为常规 JList 文本显示给用户。我在 ComboBoxes 中看到了带有按钮的应用程序,我不确定它们是否是用 Java 编写的。
    • @jadrijan 当然它看起来不像一个按钮。这就是我想说的......你可以使用JButton,但它永远不会像一个。所以最好不要使用JButtonimo
    • 我完全理解你,罗宾。 :) 我只是想澄清一下,做我所做的事情并不违反 Java“规则”。
    【解决方案3】:

    根据您想要放置搜索按钮的位置,您可以查看xswingx Prompt/Buddy API。您可以使用它与编辑器字段“结伴”浏览按钮

    或者您可以简单地在组合框旁边添加一个浏览按钮。

    【讨论】:

    • 谢谢,我真的很想把按钮放在组合框中而不是旁边。我原以为会有一种更简单的方法来做到这一点,而不是使用 3rd 方 api。
    • 根据记忆,comobox 的布局似乎是由 UI 委托(外观和感觉)完成的,我可能是错的,但我似乎记得的就是这个
    【解决方案4】:

    确实,您必须使用http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer 中解释的自定义渲染器。

    【讨论】:

    • 如果你只有一个渲染器,你将如何按下按钮?
    • @Robin:你不改变按钮的渲染器,只改变JCombobox的渲染器。该按钮仍将像在组合框外一样起作用。
    • 你真的试过这个吗?渲染器中返回的组件不包含在JComboBox 中,因此您将无法按下按钮
    猜你喜欢
    • 1970-01-01
    • 2013-05-03
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多