【问题标题】:Resizing JTextField in JMenuBar在 JMenuBar 中调整 JTextField 的大小
【发布时间】:2013-03-06 01:39:45
【问题描述】:

我正在尝试将JTextField 作为搜索栏添加到我的JFrame 顶部的JMenuBar。我的问题是JTextField 不断调整大小以占用JMenuBar 中的所有可用空间,我不希望这样。我试过setPreferredSize()setMaximum Size(),但这些都不起作用,大概是因为JMenuBar 中使用的LayoutManager 不尊重这些尺寸。我还尝试使用FlowLayoutJTextField 添加到JPanel 并将面板添加到JMenuBar,但我得到的结果如下所示:

面板在JMenuBar 的右侧,大小似乎是正确的,但除了这个奇怪的蓝色条之外我什么都看不到。

这是(我认为)相关的代码。如果需要更多信息,请告诉我:

       JPanel searchPanel = new JPanel();
    searchPanel.setPreferredSize(new Dimension(100, 25));


    JTextField searchBar = new JTextField(50);

    String[] fields = {"title", "author", "subject", "publisher", "year", "circulating", "catalog" };


    JComboBox searchFields = new JComboBox(fields);

    JButton searchBtn = new JButton("search");

    searchPanel.add(searchBar);
    searchPanel.add(searchFields);
    searchPanel.add(searchBtn);
    searchPanel.setVisible(true);

    fileMenu.add(open);
    fileMenu.add(save);
    fileMenu.add(exit);

    libMenu.add(viewLib);
    libMenu.addSeparator();
    libMenu.add(newBook);
    libMenu.add(search);

    this.setJMenuBar(topBar);
       topBar.add(fileMenu);
    topBar.add(libMenu);
    topBar.add(Box.createHorizontalGlue());
   topBar.add(searchPanel);

【问题讨论】:

  • JMenuBar 有自己的布局管理器,可能会忽略您的尺寸提示
  • 是的,我知道,但这里肯定有解决方法。似乎我发布的那个(将 JTextField 等添加到 JPanel)会起作用,但是 JPanel 显示不正确,这是我真的不明白的地方
  • JPanel 将受到与 JTextField 相同的限制...抱歉,需要一点思考空间 ;)
  • don't use setXXSize,对于@splungebob,这 never-ever-ever 至少符合第二个近似值,非常接近实际值 :-) 实际上,我不知道不记得这些年来见过一个用例(在现实世界的应用程序中,而不是快速示例),它并没有引发比它应该解决的问题更多的问题。

标签: java swing jtextfield layout-manager preferredsize


【解决方案1】:

这对我有用。

menuBar.add(Box.createHorizontalGlue());
JTextField textField = new JTextField(10);
textField.setMaximumSize( textField.getPreferredSize() );
menuBar.add(textField);

如果您需要更多帮助,请发布 SSCCE。

编辑:

同样,发布代码只是为了表明问题在于包含文本字段的最大大小。您如何选择执行此操作取决于您。

【讨论】:

  • +1 依赖getPreferredSize()
  • 这很有趣。这与我之前的代码完全相同,只是我在代码的前面创建了 JTextField,并在创建水平胶水后将其添加到菜单栏。出于某种原因,在创建胶水后创建并添加它使其工作。谁能解释这是为什么?
  • arrggg ...这仍然是当前首选项的最大硬编码,出于所有已知原因,这是一个坏主意。而是覆盖并让 getMax 返回 getPref
【解决方案2】:

我的解决方案与 camickr 的类似,但不需要 setMaximumSize()。并不是说我反对它,但我知道 SO 的狂热者发誓“永远永远不会调用 setXxxsize() 永远!!!”我不是他们中的一员,但他们就在那里。

无论如何,我会用 GridBagLayout 制作一个 JPanel,然后将 JTextField 放入其中并填充 NONE,然后将 Box.createHorizo​​ntalGlue() 填充为 HORIZONTAL。然后,将此面板放在您的菜单栏中。

编辑:

为了完整起见,这是一个使用 JPanel 的解决方案,无需调用 setMaximumSize(...)
(从而避免永远在地狱中燃烧……根据某些人的说法):

GridBagConstraints gbc = new GridBagConstraints();
JPanel gbPanel = new JPanel(new GridBagLayout());
gbc.gridx = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbPanel.add(Box.createHorizontalGlue(), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbPanel.add(new JTextField(10), gbc);
menuBar.add(gbPanel);

一些cmets:
1) 伙计,我忘了 GBL 有多冗长。通常我使用一个帮助类来大大减少代码,但我不想为这么小的例子发布它。

2) 如果采用面板路线,camickr 的使用 BorderLayout 的建议(见下面的评论)不仅有效,而且是更简单的代码。

3) 此外,正如 camickr 所指出的,使用面板会影响“胶水”区域的外观。它被绘制成 JPanel 而不是 JMenuBar。老实说,在他提到它之前,我什至没有在我的机器上注意到它(使用 Metal L&F),但它是不同的,可能是一个不受欢迎的副作用。

【讨论】:

  • @camickr 的做法并不违反原则,因为它依赖于getPreferredSize()
  • @trashgod:我认为它确实违反了“从不原则”,原因有两个:(1)它设置了一次最大大小,这意味着如果以后 pref 大小发生变化,max 不会。 (2) 索赔是“从不”。正如“永远不会”(正如我所看到的那样)。没有条件或例外,这就是为什么我基本上不同意这个绝对。如果相反,这是一个“强烈推荐的指南”,那么我会同意。只是我的 2c。
  • 您是对的,任何使用setMaximumSize() 的行为都应严格检查是否有意外后果。 +1 替代方案。
  • 我不是 GridBagLayout 专家,但我尝试了您的建议,但无法让它发挥作用。问题是面板似乎增加了尺寸,因为它没有最大值。我最终尝试了一个带有 BorderLayout 的面板并将文本字段添加到 EAST。这行得通,但问题是菜单栏“间隙”现在像面板一样绘制
  • @kleopatra,我在技术上并不反对你所说的任何事情。菜单栏已经使用了自定义布局管理器,因此您需要自定义自定义布局管理器。大多数提出此类问题的人都不是在从事大型项目(或者他们会向项目中的人寻求帮助)。大多数是独立学习语言的学生。对他们来说,不断地重写 Swing 基类将是一项艰巨的任务,并且他们将使用 Swing 关闭它们。当我没有完美的解决方案时,我会尝试提出合理的方法,让他们学习和探索。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
相关资源
最近更新 更多