【问题标题】:JDialog size not suitable, why isn't the PreferredSize used in BoxLayout?JDialog 大小不合适,为什么 BoxLayout 中没有使用 PreferredSize?
【发布时间】:2017-09-29 03:02:41
【问题描述】:

我有一个只有几个简单组件的 JDialog,一个 JTextArea、一个 JtextField 和一个 JRadioButton。我只是希望它以合适的尺寸显示。

组件的 PreferredSize 似乎是合理的,但一切都被截断了。我正在使用带有 Y_AXIS 的 BoxLayout。

我不想设置明确的尺寸,我只想为那里的组件设置合适的尺寸。

特别是,为什么忽略 textarea 的 PreferredSize?

我创建的最小代码如下:-

它创建以下输出:-

0|Name: dialog0, Class: javax.swing.JDialog,  [175, 132], H: 103, W: 132, AlignmentX: 0, AlignmentY: 0
1|-Name: null, Class: javax.swing.JRootPane,  [137, 116], H: 65, W: 116, AlignmentX: 0, AlignmentY: 0
2|--Name: null.glassPane, Class: javax.swing.JPanel,  [10, 10], H: 65, W: 116, AlignmentX: 0, AlignmentY: 0
2|--Name: null.layeredPane, Class: javax.swing.JLayeredPane,  [1, 1], H: 65, W: 116, AlignmentX: 0, AlignmentY: 0
3|---Name: null.contentPane, Class: javax.swing.JPanel,  [137, 116], H: 65, W: 116, AlignmentX: 0, AlignmentY: 0
4|----Name: null, Class: javax.swing.JPanel,  [137, 116], H: 65, W: 116, AlignmentX: 0, AlignmentY: 0
5|-----Name: null, Class: javax.swing.JTextArea,  [94, 116], H: 22, W: 116, AlignmentX: 0, AlignmentY: 0
5|-----Name: null, Class: javax.swing.JRadioButton,  [23, 57], H: 23, W: 57, AlignmentX: 0, AlignmentY: 0
5|-----Name: null, Class: javax.swing.JTextField,  [20, 6], H: 20, W: 116, AlignmentX: 0, AlignmentY: 0

代码如下:-

package testing.example;

import java.awt.Component;
import java.awt.Container;
import javax.swing.BoxLayout;
import static javax.swing.BoxLayout.Y_AXIS;
import javax.swing.ButtonGroup;
import javax.swing.CellRendererPane;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JViewport;
import testing.Panel;
import testing.testPanel;

public class DialogSize {

final private static String LOOKANDFEEL = "Windows";
private static JDialog dialog;
private static JTextArea textArea;
private static JTextField textField;
private static JPanel panel;
private static JRadioButton button;

// <editor-fold defaultstate="collapsed" desc="initLookAndFeel">
private static void initLookAndFeel() {
    if (LOOKANDFEEL != null) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch (ClassNotFoundException | 
                InstantiationException | 
                IllegalAccessException | 
                javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BlankBorder.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
    }
} // </editor-fold>

private static void createAndShowDialog() {
    initLookAndFeel();
    dialog = new JDialog();
    panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, Y_AXIS));
    textArea = new JTextArea();
    textArea.setText("Enter the dribble furble that you wish to frangle from all time.");
    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    button = new JRadioButton("Button");
    textField = new JTextField();
    panel.add(textArea);
    panel.add(button);
    panel.add(textField);
    dialog.add(panel);
    dialog.setVisible(true);
    dialog.pack();
    analyseComponent(dialog);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            createAndShowDialog();
        }
    });
}

private static int level = 0;
private static String indent = "|";

public static void analyseFrame(JFrame frame) {
    if (frame == null) return;
    int h = frame.getHeight();
    int w = frame.getWidth();
    Container container = frame.getContentPane();
    analyseComponent(frame);
    System.out.print("\n\n");
}

public static void analyseContainer(Container container) {
    level++;
    indent += "-";
    int componentCount = container.getComponentCount();
    Component[] components = container.getComponents();
    for (int i=0; i < componentCount; i++) {
        Component component = components[i];
        analyseComponent(component);
    }
    indent = indent.replaceAll("(.*)-", "$1");
    level--;
}

public static void analyseComponent(Component component) {
    Class componentClass = component.getClass();
    String className = componentClass.getName();
    int alignmentX = (int) component.getAlignmentX();
    int alignmentY = (int) component.getAlignmentY();
    int h = component.getHeight();
    int w = component.getWidth();
    System.out.print(level+indent+
            "Name: "+component.getName()+", "+
            "Class: "+component.getClass().getName()+", "+
            " ["+(int)component.getPreferredSize().getHeight() +", "+
            (int)component.getPreferredSize().getWidth()+"], "+
            "H: "+h +", "+"W: "+w+", "+
            "AlignmentX: "+alignmentX+", "+
            "AlignmentY: "+alignmentY+
            "\n");
    if (className.contains("Dialog")) {
        analyseContainer((Container)component);
    }
    else if (className.contains("Pane")) {
        analyseContainer((Container)component);
    }
}

}

【问题讨论】:

  • 旁注:您永远不会想要设置 JTextArea 的大小或首选大小。 JTextAreas 通常位于 JScrollPanes 中,如果您以这种方式限制它们的大小,则会破坏它们的行为,阻止它们在需要时扩展,并阻止显示滚动条。而是设置 JTextArea 的 visible 列和行属性。

标签: java swing jdialog preferredsize


【解决方案1】:

特别是,为什么忽略 textarea 的 PreferredSize?

好问题。我无法解释为什么它似乎被忽略了。

默认的首选大小计算将尝试在一行上显示所有文本,但由于某种原因,在计算面板和对话框的首选大小时不使用计算出的首选宽度。

我只能建议一些创建 GUI 的指南:

首先执行的顺序应该是:

dialog.pack();
dialog.setVisible(true);

当您以相反的方式执行此操作时,对话框最初将以其默认大小显示,然后在 pack() 完成时将调整其大小。您可能会看到绘制的对话框和默认大小,然后跳转到更大的大小。

使用文本组件时,您需要向组件提供额外信息,以便它可以更好地确定其首选大小。所以你会使用类似的东西:

JTextArea textArea = new JTextArea(3, 20); 
JTextField textField = new JTextField(10);

这将允许每个组件根据指定的列值确定其首选宽度。对于文本区域,行将提供用于确定高度的信息。

当您使用这种方法时,文本区域和文本字段的首选大小将用于 pack() 计算。

你也应该使用:

panel.add( new JScrollPane( textArea ) );

这将确保最初显示 3 行。如果需要更多行来显示文本,则会出现滚动条。

【讨论】:

    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2016-11-10
    • 2020-07-03
    相关资源
    最近更新 更多