Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why setting setPreferredSize() on JFrame is bad?

Tags:

java

swing

Is setting preferred size of JFrame using setPreferredSize() considered bad?

If it is bad, what is good way to change JFrame window size to dimension I need.

I know laying components in way to reflect final JFrame dimension that I need. But if I use shortcut to change preferred size using call setPreferredSize() just before call to pack() to change final JFrame size is bad? If so why?

For example I have sample form:

enter image description here

This is displayed without setting preferred size.

Now I can resize form with call to setPreferredSize() before call to pack().

enter image description here

This is displayed with call: setPreferredSize(new Dimension(500, 300));

I can have similar effect with setting components size while laying it out. But what is disadvantage of setting frame size with just call to setPreferredSize().

I can think setting preferred size as resizing displayed window manually with mouse after it has been displayed. Isn't it?

Code:

import java.awt.Dimension;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class MyFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    private JTextField fullNameTextField = new JTextField();
    private JTextField emailIDTextField = new JTextField();
    private JTextArea addressTextArea = new JTextArea();
    private JButton submitButton = new JButton("Submit");
    private JButton cancelButton = new JButton("Cancel");

    public MyFrame(){
        super("MyFrame");

        layoutComponents();

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        setPreferredSize(new Dimension(500, 300));

        pack();
    }

    private void layoutComponents(){
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);

        JLabel fullNameLabel = new JLabel("Full Name:");
        JLabel emailIDLabel = new JLabel("Email ID:");
        JLabel addressLabel = new JLabel("Address:");

        JScrollPane addressScrollPane = new JScrollPane(addressTextArea);

        layout.setHorizontalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addGap(10)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addGroup(layout.createSequentialGroup()
                                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                .addComponent(fullNameLabel)
                                                .addComponent(emailIDLabel)
                                                .addComponent(addressLabel)
                                            )
                                        .addGap(15)
                                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                .addComponent(fullNameTextField, 10, 200, Short.MAX_VALUE)
                                                .addComponent(emailIDTextField)
                                                .addComponent(addressScrollPane)
                                                .addGroup(layout.createSequentialGroup()
                                                        .addGap(0, 0, Short.MAX_VALUE)
                                                        .addComponent(submitButton)
                                                        .addGap(10)
                                                        .addComponent(cancelButton)
                                                    )
                                            )
                                    )
                            )
                        .addGap(10)
                    )
            );

        layout.setVerticalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addGap(10)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(fullNameLabel)
                                .addComponent(fullNameTextField)
                            )
                        .addGap(5)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(emailIDLabel)
                                .addComponent(emailIDTextField)
                            )
                        .addGap(5)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(addressLabel)
                                .addComponent(addressScrollPane, 20, 60, Short.MAX_VALUE)
                            )
                        .addGap(15)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(submitButton)
                                .addComponent(cancelButton)
                            )
                        .addGap(10)
                    )
            );

        layout.linkSize(submitButton, cancelButton);

        getRootPane().setDefaultButton(submitButton);
    }

    public static void main(String [] args){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}
like image 584
nullptr Avatar asked Feb 12 '23 14:02

nullptr


1 Answers

The main reason it would be considered bad (bad is probably too strong a word, unwise might be better) is the use of unknown (magic) numbers, rather than empirical values.

Every platform (and even similar OS running on different hardware and settings) has it's own means for rendering content which can change the amount of space that individual components require.

In regards to things like text fields and text-areas, you can make suggestions about the number of columns (and rows for text areas) which can be used to change a frames final size, using setColumns and setRows for example...

So, using the following code...

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestLayout101 {

    public static void main(String[] args) {
        new TestLayout101();
    }

    public TestLayout101() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextField fullNameTextField = new JTextField(10);
        private JTextField emailIDTextField = new JTextField(10);
        private JTextArea addressTextArea = new JTextArea(10, 20);
        private JButton submitButton = new JButton("Submit");
        private JButton cancelButton = new JButton("Cancel");

        public TestPane() {

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.insets = new Insets(4, 4, 4, 4);

            add(new JLabel("Full Name: "), gbc);
            gbc.gridy++;
            add(new JLabel("Email ID: "), gbc);
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            add(new JLabel("Address: "), gbc);

            gbc.gridx++;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;

            add(fullNameTextField, gbc);
            gbc.gridy++;
            add(emailIDTextField, gbc);
            gbc.gridy++;
            gbc.weighty = 1;
            add(new JScrollPane(addressTextArea), gbc);

            JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 4, 4));
            buttons.add(submitButton);
            buttons.add(cancelButton);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weighty = 0;
            add(buttons, gbc);
        }
    }
}

Which produces...

Compact

Now by changing only one line...

private JTextArea addressTextArea = new JTextArea(10, 20);
                                // Only this value ---^

It produces this...

Mini

And again...

private JTextArea addressTextArea = new JTextArea(10, 40);
                                // Only this value ---^

Luxury

I could change the number of rows for the JTextArea and effect the height of the window as well.

The difference is, these values are used in combination with the systems font metrics to calculate the preferred size of the components when the program is run, so it will be different for different systems and platforms...

The main point to layouts is to spend your time focused on the intent and the work flow and not trying to get a pixel perfect solution, because there's simply no such thing...talk to web developers, they have the same issues, just much worse (multiple browsers on a single system, all rendering differently)

like image 88
MadProgrammer Avatar answered Feb 27 '23 23:02

MadProgrammer