PeakGen
PeakGen

Reputation: 23025

Messed-up GUI: Lot of Blank Space

Please have a look at the following code

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);


    }
}

In here, the GUI seems very bad. I need to have enough space for all the fields. In the JTextArea, you can see it is not even visible. I need it's height to be 2 columns; it seems like all these problems are occurring because it is trying to set the large JTextArea to one column. For your information, this is an "Compose Email" GUI, so you can be clear of what I am asking. I used this.pack() but it made everything worst!

Upvotes: 1

Views: 449

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

As I mentioned above in the comments:

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().

For instance, I would

  • make the JTextArea a reasonable size, not 500 rows by 500 cols!
  • Don't set size of things
  • Do call pack()
  • Don't forget to use weightx and weighty (added to the code) and insets (not yet added).
  • Avoid magic numbers.
  • Consider nesting easier to use layouts and minimizing use of GridBagLayout.
  • Give the JScrollPane extra gridwidth to allow it to fill up the bottom. For instance:

SendEmail.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();
   }
}

which when run would look like:

enter image description here

Upvotes: 4

Related Questions