【问题标题】:JComboBox does not play well with GroupLayoutJComboBox 不能很好地与 GroupLayout 配合使用
【发布时间】:2012-11-16 17:00:59
【问题描述】:

JComboBox 组件放入GroupLayout 时,我遇到了一种奇怪的行为。我已将代码简化为以下最小示例,其中恰好有一个 JComboBoxGroupLayout 布局。

观察到的行为如下:

  • 当框架小于展开的组合框列表(带有虚拟条目 a、b、c)时,单击组合框上的小向下箭头可以正确打开它。
  • 当我将框架调整为大于展开的组合框列表时,展开的组合框列表不会打开!

我已经发现了什么:

  • 当 JComboBox 的父窗口太小时,javax.swing.PopupFactory 会创建一个 HEAVY_WEIGHT_POPUP 组件。
  • 当父窗口足够大时,会创建一个 LIGHT_WEIGHT_POPUP。
  • 该行为肯定与 GroupLayout 或其某些副作用有关,因为我尝试过的任何其他布局管理器都可以正常工作。
  • 在 GroupLayout 中使用 addGap() 时,问题发生了一些变化,即 JComboBox 不显示的窗口大小发生了变化。

这是示例代码 - 欢迎使用 cmets:

import java.awt.BorderLayout;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JRootPane;

public class DummyUI_cbdiagnosis extends javax.swing.JPanel {
    private javax.swing.JComboBox cbCategory;

    public DummyUI_cbdiagnosis() {
        initComponents();
    }

    private void initComponents() {
        cbCategory = new JComboBox();
        cbCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
                "a", "b", "c" }));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(
                javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup().addComponent(cbCategory,
                        javax.swing.GroupLayout.PREFERRED_SIZE,
                        javax.swing.GroupLayout.PREFERRED_SIZE,
                        javax.swing.GroupLayout.PREFERRED_SIZE)));
        layout.setVerticalGroup(layout.createParallelGroup(
                javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup().addComponent(cbCategory)
        ));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JRootPane rootPane = frame.getRootPane();
        rootPane.setLayout(new BorderLayout());

        DummyUI_cbdiagnosis panel = new DummyUI_cbdiagnosis();
        rootPane.add(panel, BorderLayout.NORTH);

        frame.pack();
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 你不必显式调用包名,如果你导入它们...

标签: java swing jcombobox


【解决方案1】:

永远不要将组件添加到RootPane 本身,而是将它们添加到contentPane

frame.add(panel);

frame.setContentPane(panel);

RootPane 可以控制放置:

  • 菜单栏。
  • 内容。
  • 玻璃窗格。
  • 还有最重要的轻量级弹出窗口(包括JComboBox)、对话框、拖放等。

RootPane 使用名为RootLayout 的特殊布局管理器,不应更改为BorderLayout

【讨论】:

  • 您能解释一下为什么我不能添加到根窗格吗?
  • 不是你的反对者,而是frame.add() 转发到内容窗格,使getContentPane() 多余; frame.setContentPane() 替换内容窗格,可能是无意的。更多here.
  • @trashgod 似乎我已经过时了,JFrame#add(...) 曾经在旧版本的 JDK 上抛出 Error
  • 谢谢,我没有意识到有 getRootPane() getContentPane() - 我误认为 getRootPane() 是为您提供框架顶级窗格的方法(确实请记住,尽管 frame.add() 在旧的 JDK 中不起作用;有趣的事情)。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
相关资源
最近更新 更多