【问题标题】:Keep BoxLayout From Expanding Children防止 BoxLayout 扩展子级
【发布时间】:2012-12-10 06:10:14
【问题描述】:

我想在 JPanel 中垂直堆叠一些 JComponent,以便它们堆叠在顶部,而任何多余的空间都在底部。我正在使用 BoxLayout。每个组件都将包含一个 JTextArea,它应该允许文本在必要时换行。所以,基本上,我希望这些组件中的每一个的高度都是显示(可能是包装的)文本所需的最小值。

这是我正在做的包含代码示例:

import javax.swing.*;
import java.awt.*;
public class TextAreaTester {
    public static void main(String[] args){
        new TextAreaTester();
    }
    public TextAreaTester(){
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel,BoxLayout.PAGE_AXIS));
        panel.setPreferredSize(new Dimension(100,400));
        for(int i = 0; i<3; i++){
            JPanel item = new JPanel(new BorderLayout());
            JTextArea textarea = new JTextArea("this is a line of text I want to wrap if necessary");
            textarea.setWrapStyleWord(true);
            textarea.setLineWrap(true);
            textarea.setMaximumSize( textarea.getPreferredSize() );
            item.add(textarea,BorderLayout.NORTH);
            panel.add(item);
        }
        panel.add(Box.createGlue());
        frame.add(panel);
        frame.setVisible(true);
        frame.pack();  
    }
}

子 JPanel 正在扩展以填充垂直空间。我尝试使用胶水,因为我认为这就是胶水的用途,但它似乎什么也没做。有什么帮助吗?

注意:我发现了一些看起来几乎相同的问题,但没有一个问题有我可以应用的答案。

【问题讨论】:

  • 不要永远使用任何 setXXSize - 提供合理的尺寸提示是组件本身的专属任务。
  • @kleopatra 如果你有什么理由我不应该使用 API 中发布的方法,也许你应该给它。

标签: java swing jpanel boxlayout preferredsize


【解决方案1】:

一种解决方案:使用 Borderlayout 将 JPanel 与外部 JPanel 嵌套,并将使用 JPanel 的 BoxLayout 添加到此 BorderLayout.NORTH,也称为 BorderLayout.PAGE_START:

为 Kleopatra 编辑:

import javax.swing.*;
import java.awt.*;

public class TextAreaTester {
   public static void main(String[] args) {
      new TextAreaTester();
   }

   public TextAreaTester() {
      JFrame frame = new JFrame();
      JPanel panel = new JPanel();
      panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
      // panel.setPreferredSize(new Dimension(100,400));
      for (int i = 0; i < 3; i++) {
         JPanel item = new JPanel(new BorderLayout());
         // item.setLayout(new BoxLayout(item,BoxLayout.LINE_AXIS));
         JTextArea textarea = new JTextArea(
               "this is a line of text I want to wrap if necessary", 3, 35);
         textarea.setWrapStyleWord(true);
         textarea.setLineWrap(true);
         // textarea.setMaximumSize(textarea.getPreferredSize());
         // item.setMaximumSize( item.getPreferredSize() );
         item.add(new JScrollPane(textarea), BorderLayout.NORTH);
         panel.add(item);
      }
      panel.add(Box.createGlue());

      JPanel mainPanel = new JPanel(new BorderLayout()) {
         private final int prefW = 100;
         private final int prefH = 400;

         @Override
         public Dimension getPreferredSize() {
            return new Dimension(prefW, prefH);
         }
      };
      // mainPanel.setPreferredSize(new Dimension(100, 400));
      mainPanel.add(panel, BorderLayout.PAGE_START);

      frame.add(mainPanel);
      frame.setVisible(true);
      // frame.getContentPane().add(jp);
      frame.pack();
   }
}

【讨论】:

  • @kleopatra:那里,你开心吗?
  • 世界上到处都是程序员,绝对的说法是,“你不应该……”。这是没有帮助的。我指的是 kleopatra 对这个问题的补充。
  • @AdamCross:啊,我明白了。我和她就这个话题讨论过很多次。她的观点是,如果你重写了一个组件的getPreferredSize() 方法,那么它就成为该类及其对象的固有部分,外部力量无法改变preferredSize 设置,她是对的。如果您关注她在此网站和其他网站上的讨论,您会发现她对 Swing 的知识和智慧是目前最好的。
  • 更好 - 但仍然是 setMax :-)
  • @kleopatra:哎呀,没看到。已删除。给您的问题:您对 JavaFX 与 Swing 的未来有何看法?
【解决方案2】:

或者,您可以使用Box.Filler。只需将您对panel.add(Box.createGlue()) 的呼叫替换为

panel.add(new Box.Filler(new Dimension(0, 0),
    new Dimension(0, Short.MAX_VALUE),
    new Dimension(0, Short.MAX_VALUE)));

如果您想在水平布局中实现相同的效果,只需在 Dimension 调用中使用 Short.MAX_VALUE 作为宽度而不是高度。

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 2014-08-11
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多