Java 防止BoxLayout扩展子项

Java 防止BoxLayout扩展子项,java,swing,jpanel,boxlayout,preferredsize,Java,Swing,Jpanel,Boxlayout,Preferredsize,我想在一个JPanel中垂直堆叠一些JComponents,这样它们堆叠在顶部,任何额外的空间都在底部。我使用的是BoxLayout。每个组件都将包含一个JTextArea,该区域应允许文本在必要时进行换行。因此,基本上,我希望每个组件的高度都是显示(可能是包装的)文本所必需的最小值 下面是我正在做的一个包含代码的示例: import javax.swing.*; import java.awt.*; public class TextAreaTester { public static

我想在一个JPanel中垂直堆叠一些JComponents,这样它们堆叠在顶部,任何额外的空间都在底部。我使用的是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();  
    }
}
import javax.swing.*;
导入java.awt.*;
公共类文本区域测试器{
公共静态void main(字符串[]args){
新的TextAreaTester();
}
公共文本区域测试器(){
JFrame=新JFrame();
JPanel面板=新的JPanel();
panel.setLayout(新的BoxLayout(panel,BoxLayout.PAGE_轴));
面板。设置首选尺寸(新尺寸(100400));

对于(int i=0;i一种解决方案:使用Borderlayout将JPanel与外部JPanel嵌套,并使用JPanel将BoxLayout添加到此Borderlayout.NORTH,也称为Borderlayout.PAGE_开始:

为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();
   }
}
import javax.swing.*;
导入java.awt.*;
公共类文本区域测试器{
公共静态void main(字符串[]args){
新的TextAreaTester();
}
公共文本区域测试器(){
JFrame=新JFrame();
JPanel面板=新的JPanel();
panel.setLayout(新的BoxLayout(panel,BoxLayout.PAGE_轴));
//面板。设置首选尺寸(新尺寸(100400));
对于(int i=0;i<3;i++){
JPanel item=newjpanel(newborderlayout());
//item.setLayout(新的BoxLayout(item,BoxLayout.LINE_轴));
JTextArea textarea=新的JTextArea(
“这是一行我想在必要时包装的文本”,3,35);
textarea.setWrapStyleWord(true);
textarea.setLineWrap(true);
//textarea.setMaximumSize(textarea.getPreferredSize());
//item.setMaximumSize(item.getPreferredSize());
添加(新的JScrollPane(textarea),BorderLayout.NORTH);
面板。添加(项目);
}
panel.add(Box.createGlue());
JPanel mainPanel=newjpanel(newborderlayout()){
私人最终int prefW=100;
专用最终int prefH=400;
@凌驾
公共维度getPreferredSize(){
返回新维度(prefW、prefH);
}
};
//主面板。设置首选尺寸(新尺寸(100400));
主面板。添加(面板,边框布局。页面开始);
添加框架(主面板);
frame.setVisible(true);
//frame.getContentPane().add(jp);
frame.pack();
}
}

或者,您可以使用。只需将对
面板的调用替换为添加(Box.createGlue())

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

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

永远不要使用任何setXXSize-提供合理的大小提示是组件本身独有的任务。@kleopatra如果您有什么理由不应该使用中发布的方法的话API,也许你应该给它。@kleopatra:好了,你高兴吗?世界上太多的程序员在绝对意义上说,“你不应该……”。这没用。我指的是克利奥帕特拉对这个问题的补充。@AdamCross:啊,我明白了。她和我已经就这个问题讨论过很多次了。她的观点是,如果你覆盖
getPreferredSize()
方法,则它成为该类及其对象的固有部分,外力无法改变preferredSize设置,她是对的。如果你关注她在本网站和其他网站上的讨论,你会发现她在Swing方面的知识和智慧是最好的。更好,但仍然是setMax左边over:-)@kleopatra:oops,没看到。删除。问你:你对JavaFX和Swing的未来有什么看法?