如何将 JButton 放在 JComboBox 中

Posted

技术标签:

【中文标题】如何将 JButton 放在 JComboBox 中【英文标题】:How to put a JButton inside a 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 作为普通/常规组合框选择对象。

【问题讨论】:

【参考方案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 中,因此您将无法按下按钮

以上是关于如何将 JButton 放在 JComboBox 中的主要内容,如果未能解决你的问题,请参考以下文章

如何将JComboBox添加到JTable单元格?

如何相对于另一个组件布局组件?

如何将特定数据字段从 ArrayList 加载到某些 JTextFields?

java中如何将数据显示到jcombobox上?

如何将 JComboBox 事件处理程序的字符串放入变量中进行查询?

如何将 JPanel 放在 JFrame 的前面