java - 困惑的 GUI : Lot of Blank Space

标签 java swing user-interface jtextarea gridbaglayout

请看下面的代码

package email;

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

public class SendEmail extends JDialog
{
    private JLabel to, cc, bcc, subject, account;
    private JTextField toTxt, ccTxt, bccTxt, subjectTxt;
    private JTextArea messageTxt;
    private JButton send;

    private JComboBox accountBox;

    private JScrollPane scroll;

    private GridBagLayout gbl;
    private GridBagConstraints gbc;

    public SendEmail()
    {
        //Declaring instance variables
        to = new JLabel("To: ");
        cc = new JLabel("CC: ");
        bcc = new JLabel("BCC: ");
        subject = new JLabel("Subject: ");
        account = new JLabel("Select an Account: ");

        toTxt = new JTextField(20);
        ccTxt = new JTextField(20);
        bccTxt = new JTextField(20);
        subjectTxt = new JTextField(20);

        messageTxt = new JTextArea(500,500);
        scroll = new JScrollPane(messageTxt);


        accountBox = new JComboBox();
        accountBox.addItem("Yahoo");
        accountBox.addItem("GMail");
        accountBox.addItem("MSN");
        //accountBox.addItem("Yahoo");
        //accountBox.addItem("Yahoo");



        //Creating thr GUI
        gbl = new GridBagLayout();
        gbc = new GridBagConstraints();

        this.setLayout(gbl);


        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(account,gbc);

        gbc.gridx = 2;
        gbc.gridy = 1;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(accountBox,gbc);


        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(to,gbc);

        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(toTxt,gbc);

        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(bcc,gbc);

        gbc.gridx = 2;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(bccTxt,gbc);

        gbc.gridx = 1;
        gbc.gridy = 4;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(cc,gbc);

        gbc.gridx = 2;
        gbc.gridy = 4;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(ccTxt,gbc);

        gbc.gridx = 1;
        gbc.gridy = 5;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(subject,gbc);

        gbc.gridx = 2;
        gbc.gridy = 5;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(subjectTxt,gbc);

        gbc.gridx = 1;
        gbc.gridy = 6;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(scroll,gbc);


        this.setSize(new Dimension(200,500));
        this.setVisible(true);


    }
}

在这里,GUI 看起来很糟糕。我需要为所有字段留出足够的空间。在 JTextArea 中,您可以看到它甚至不可见。我需要它的高度为 2 列;似乎所有这些问题都在发生,因为它试图将大型 JTextArea 设置为一列。供您引用,这是一个“撰写电子邮件”GUI,因此您可以清楚我在问什么。我使用了 this.pack() 但它让一切变得更糟!

最佳答案

正如我在上面的评论中提到的:

Don't call setSize(). Instead pack() the GUI and let the component's natural preferred sizes and the layouts dictate the size of the GUI. If pack() makes things worse, then you should fix the problem from that side of things, not by calling setSize().

例如,我会

  • 使 JTextArea 的大小合理,而不是 500 行 x 500 列!
  • 不要设置事物的大小
  • 调用pack()
  • 不要忘记使用 weightx 和 weighty(添加到代码中)和 insets(尚未添加)。
  • 避免魔数(Magic Number)。
  • 考虑嵌套更易于使用的布局并尽量减少 GridBagLayout 的使用。
  • 为 JScrollPane 提供额外的网格宽度,使其能够填满底部。例如:

发送邮件.java:

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class SendEmail extends JDialog {
   public final static String[] LABEL_TEXTS = { "Select an Account:", "To:",
         "BCC:", "CC:", "Subject:" };
   public final static String[] ACCOUNT_TEXTS = { "Yahoo", "GMail", "MSN" };
   private static final int TEXT_FIELD_LENGTH = 20;
   private static final int T_AREA_ROWS = 20;
   private static final int T_AREA_COLS = 50;
   private static final int INSET_GAP = 1;
   private static final int RIGHT_INSET_GAP = 15;
   private Map<String, JTextField> fieldMap = new HashMap<String, JTextField>();
   private JTextArea messageTxt;
   private JButton send;

   private JComboBox<String> accountBox;

   private JScrollPane scroll;

   public SendEmail(JFrame frame) {
      super(frame, "Dialog", true);
      messageTxt = new JTextArea(T_AREA_ROWS, T_AREA_COLS);
      scroll = new JScrollPane(messageTxt);
      accountBox = new JComboBox<String>(ACCOUNT_TEXTS);

      this.setLayout(new GridBagLayout());
      int ebGap = 5;
      ((JPanel) getContentPane()).setBorder(BorderFactory.createEmptyBorder(
            ebGap, ebGap, ebGap, ebGap));

      for (int i = 0; i < LABEL_TEXTS.length; i++) {
         JLabel label = new JLabel(LABEL_TEXTS[i]);
         addLabel(0, i, label);

         if (i == 0) {
            addField(1, i, accountBox);
         } else {
            JTextField tField = new JTextField(TEXT_FIELD_LENGTH);
            fieldMap.put(LABEL_TEXTS[i], tField);
            addField(1, i, tField);
         }
      }

      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = 0;
      gbc.gridy = LABEL_TEXTS.length;
      gbc.gridwidth = 2;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, INSET_GAP);
      this.add(scroll, gbc);

      pack();
      this.setVisible(true);
   }

   private void addField(int x, int y, JComponent comp) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.weightx = 1.0;
      gbc.weighty = 0.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, INSET_GAP);
      gbc.anchor = GridBagConstraints.EAST;

      this.add(comp, gbc);
   }

   private void addLabel(int x, int y, JComponent comp) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.weightx = 0.0;
      gbc.weighty = 0.0;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, RIGHT_INSET_GAP);
      gbc.anchor = GridBagConstraints.EAST;

      this.add(comp, gbc);
   }

   public String getTextFieldText(String key) {
      JTextField tField = fieldMap.get(key);
      if (tField == null) {
         String text = "key, " + key + " not a valid argument for fieldMap";
         throw new IllegalArgumentException(text);
      }

      return tField.getText();
   }

   public String getAccountText() {
      return accountBox.getSelectedItem().toString();
   }

   public String getMessageTxt() {
      return messageTxt.getText();
   }

   public static void main(String[] args) {
      JFrame frame = new JFrame();
      frame.pack();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      new SendEmail(frame);
      frame.dispose();
   }
}

运行时看起来像:

enter image description here

关于java - 困惑的 GUI : Lot of Blank Space,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12447562/

相关文章:

java - Maven 无法解析依赖项(返回代码为 : 409 , ReasonPhrase:Conflict)

java - 更改 JList 中一行的字体和背景颜色

java - 回到之前的 JPanel

Java - JButton 与变化的背景

asp.net-mvc - asp.net mvc - 完全脱离 DB 中的自定义字段构建 View

c++ - Qt QTreeWidget 一项一项添加

java - Swing:如何从 JTable 中拖动多行?

java - 在Ubuntu上安装OpenJDK 14

java - 从 json 获取对象会产生 java.lang.RuntimeException : Failed to invoke public java. util.Dictionary() ,不带参数

java - Swing UIManager 默认系统观感