JDialog大小不合适,为什么BoxLayout中没有使用PreferredSize?
JDialog size not suitable, why isn't the PreferredSize used in BoxLayout?
我有一个 JDialog,只有几个简单的组件,一个 JTextArea,一个 JtextField 和一个 JRadioButton。我只是想让它以合适的尺寸显示。
组件的 PreferredSize 似乎是合理的,但所有内容都被截断了。我在 Y_AXIS.
中使用 BoxLayout
我不想设置明确的大小,我只想为那里的组件设置一个合适的大小。
特别是,为什么文本区域的 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("(.*)-", "");
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);
}
}
}
In particular, why is the PreferredSize for the textarea ignored?
好问题。我无法解释为什么它似乎被忽略了。
默认的首选大小计算将尝试在一行中显示所有文本,但由于某种原因,在计算面板的首选大小和对话框时未使用计算出的首选宽度。
我只能建议一些创建 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 行。如果需要更多行来显示文本,则会出现滚动条。
我有一个 JDialog,只有几个简单的组件,一个 JTextArea,一个 JtextField 和一个 JRadioButton。我只是想让它以合适的尺寸显示。
组件的 PreferredSize 似乎是合理的,但所有内容都被截断了。我在 Y_AXIS.
中使用 BoxLayout我不想设置明确的大小,我只想为那里的组件设置一个合适的大小。
特别是,为什么文本区域的 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("(.*)-", "");
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);
}
}
}
In particular, why is the PreferredSize for the textarea ignored?
好问题。我无法解释为什么它似乎被忽略了。
默认的首选大小计算将尝试在一行中显示所有文本,但由于某种原因,在计算面板的首选大小和对话框时未使用计算出的首选宽度。
我只能建议一些创建 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 行。如果需要更多行来显示文本,则会出现滚动条。