user4031188
user4031188

Reputation:

Resizing Windows and Swing

Please can you help me understand window and component sizing. I have read through this forum, tutorial and reference documentation and have come to the conclusion that if I am using Swing I use LayoutManagers, setPreferredSize on components and Pack() the frame after setting it up. This works fine and I get the following:

enter image description here

However, when I make the window smaller I get this:

enter image description here

If I wish to change the size of my components as the window size changes do I need to introduce listeners to capture the change and act accordingly?

To me the best thing is that the window can be made smaller but the top level Panel does not change so contained components do not need resizing?

Any views?

EDIT - Code as requested - complete MVCE

package mvc;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JPanel;

import javax.swing.JScrollPane;


import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.LookAndFeel;

import java.awt.Insets;
import java.util.Calendar;

import javax.swing.JComboBox;

public class BudgetValuesWindow extends JFrame
{
        private JList<String> listIncomeMissing;
        private JList<String> listExpenseMissing;
        private JList<String> listIncomeSelect;
        private JList<String> listExpenseSelect;
        public String strBudget;
        public String strFileName;
        /*
         * Screen fields
         */
        private JButton btnGenerate;
        private JButton btnClose;
        private JButton btnSave;
        private JButton btnChoose;
        private JComboBox<String> boxBudget;
        private JCheckBox chkRoll;
        private JTextField txtFileName;
        @SuppressWarnings("unused")
        private LookAndFeel previousLF;
        /*
         *  date fields
         */
        public static int iFiscalYear;
        public static int iYear;
        public static int iFiscalMonth;
        public static int iFiscalDay;
        public static Calendar dtWeekStart;


        private JPanel panScreen;   
        private JPanel panTop;
        private JPanel panMid;
        private JScrollPane spExpenseMissing;
        private JScrollPane spExpenseSelected;
        private JScrollPane spIncomeMissing;
        private JScrollPane spIncomeSelected;
        private JButton btnESelect;
        private JButton btnEDeselect;
        private JButton btnISelect;
        private JButton btnIDeselect;
    public BudgetValuesWindow() {
        String [] data1 = {"Line 1","Line 2","Line 3"};
        String [] data2 = {"Line 4","Line 5","Line 6","Line 7"};
        String [] data3 = {"Line 8","Line 9"};
        String [] data4 = {"Line 10","Line 11","Line 12"};
        listIncomeMissing = new JList<String>(data1);
        listExpenseMissing = new JList<String>(data2);
        listIncomeSelect = new JList<String>(data3);
        listExpenseSelect = new JList<String>(data4);
        /*
         * start of screen
         */ 
        panScreen = new JPanel();
        this.add(panScreen);
        panScreen.setLayout(new BorderLayout());
        /*
         * Top panel
         */
        panTop = new JPanel();
        panTop.setPreferredSize(new Dimension(Constants.TOPWIDTH,Constants.TOPDEPTH));
        GridBagLayout gbl_panTop = new GridBagLayout();
        gbl_panTop.columnWidths = new int[]{100, 80, 100, 80, 100,30};
        panTop.setLayout(gbl_panTop);

        GridBagConstraints conBudgl = new GridBagConstraints();
        conBudgl.insets = new Insets(10, 10,10,10);
        conBudgl.gridx=0;
        conBudgl.gridy = 0;
        conBudgl.fill = GridBagConstraints.HORIZONTAL;
        conBudgl.anchor = GridBagConstraints.LINE_END;
        // Budget
        JLabel lblAccountsName = new JLabel("Budget:");
        panTop.add(lblAccountsName,conBudgl);

        GridBagConstraints conBudg = new GridBagConstraints();
        conBudg.insets = new Insets(10, 10,10,10);
        conBudg.gridx = 1;
        conBudg.gridy = 0;
        conBudg.fill = GridBagConstraints.HORIZONTAL;
        conBudg.anchor = GridBagConstraints.LINE_START;
        String strNames[] = {"Budget","Budget 2"};
        boxBudget = new JComboBox<String> (strNames);
        panTop.add(boxBudget,conBudg);
        /*
         * parameter file
         */
        JLabel lblFileName = new JLabel("Parameters : ");
        GridBagConstraints gbc_lblFileName = new GridBagConstraints();
        gbc_lblFileName.insets = new Insets(10, 10, 10, 10);
        gbc_lblFileName.gridx = 0;
        gbc_lblFileName.gridy = 1;
        gbc_lblFileName.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblFileName.anchor = GridBagConstraints.LINE_END;
        panTop.add(lblFileName, gbc_lblFileName);

        txtFileName = new JTextField();
        txtFileName.setText("File3");
        GridBagConstraints gbc_txtFileName = new GridBagConstraints();
        gbc_txtFileName.insets = new Insets(10,0, 10, 0);
        gbc_txtFileName.gridx = gbc_lblFileName.gridx+1;
        gbc_txtFileName.gridy = gbc_lblFileName.gridy;
        gbc_txtFileName.gridwidth=3;
        gbc_txtFileName.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtFileName.anchor = GridBagConstraints.LINE_START;
        txtFileName.setColumns(20);
        txtFileName.setText(strFileName);
        panTop.add(txtFileName, gbc_txtFileName);

        btnChoose = new JButton();
        btnChoose.setText("Find");
        GridBagConstraints gbc_btnChoose = new GridBagConstraints();
        gbc_btnChoose.insets = new Insets(10, 0, 0, 0);
        gbc_btnChoose.gridx = gbc_txtFileName.gridx+gbc_txtFileName.gridwidth;
        gbc_btnChoose.gridy = gbc_txtFileName.gridy;
        panTop.add(btnChoose, gbc_btnChoose);
        /*
         * Start Date
         */
        JLabel lblDatesStart = new JLabel("Dates - Start :");
        GridBagConstraints gbc_lblDateStart = new GridBagConstraints();
        gbc_lblDateStart.insets = new Insets(10,10,10,10);
        gbc_lblDateStart.gridx = gbc_lblFileName.gridx;
        gbc_lblDateStart.gridy = gbc_lblFileName.gridy+1;
        gbc_lblDateStart.anchor = GridBagConstraints.LINE_END;
        panTop.add(lblDatesStart, gbc_lblDateStart);
        JLabel jdtStartDate = new JLabel("02/12/2015");
        GridBagConstraints gbc_txtStartDate = new GridBagConstraints();
        gbc_txtStartDate.anchor = GridBagConstraints.LINE_START;
        gbc_txtStartDate.insets = new Insets(10,10,10,10);
        gbc_txtStartDate.gridx = gbc_lblDateStart.gridx+1;
        gbc_txtStartDate.gridy = gbc_lblDateStart.gridy;
        panTop.add(jdtStartDate, gbc_txtStartDate);

        /*
         * End Date
         */
        JLabel lblEnd = new JLabel("End :");
        GridBagConstraints gbc_lblEnd = new GridBagConstraints();
        gbc_lblEnd.insets = new Insets(10,10,10,10);
        gbc_lblEnd.gridx = gbc_txtStartDate.gridx+1;
        gbc_lblEnd.gridy = gbc_txtStartDate.gridy;
        gbc_lblEnd.anchor = GridBagConstraints.LINE_END;
        panTop.add(lblEnd, gbc_lblEnd);

        JLabel jdtEndDate = new JLabel("02/02/2016");
        GridBagConstraints gbc_txtEndDate = new GridBagConstraints();
        gbc_txtEndDate.insets = new Insets(10,10,10,10);
        gbc_txtEndDate.gridx = gbc_lblEnd.gridx+1;
        gbc_txtEndDate.gridy = gbc_lblEnd.gridy;
        gbc_txtEndDate.anchor = GridBagConstraints.LINE_START;
        panTop.add(jdtEndDate, gbc_txtEndDate);

        /*
         * Roll Up
         */
        JLabel lblRoll = new JLabel("Roll Up? :");
        GridBagConstraints gbc_lblRoll = new GridBagConstraints();
        gbc_lblRoll.insets = new Insets(10,10,10,10);
        gbc_lblRoll.gridx = gbc_txtEndDate.gridx+1;
        gbc_lblRoll.gridy = gbc_txtEndDate.gridy;
        gbc_lblRoll.anchor = GridBagConstraints.LINE_END;
        panTop.add(lblRoll, gbc_lblRoll);

        chkRoll = new JCheckBox();
        GridBagConstraints gbc_cbRoll = new GridBagConstraints();
        gbc_cbRoll.insets = new Insets(10,10,10,10);
        gbc_cbRoll.gridx = gbc_lblRoll.gridx+1;
        gbc_cbRoll.gridy = gbc_lblRoll.gridy;
        gbc_cbRoll.anchor = GridBagConstraints.LINE_START;
        chkRoll.setSelected(true);
        panTop.add(chkRoll, gbc_cbRoll);
        /*
         * Button 1 - Save
         */
        GridBagConstraints gbcbt1 = new GridBagConstraints();
        gbcbt1.gridx = gbc_lblDateStart.gridx;
        gbcbt1.gridy = gbc_lblDateStart.gridy+1;
        gbcbt1.anchor = GridBagConstraints.LINE_START;
        gbcbt1.insets = new Insets(5,5,5,5);
        btnSave = new JButton("Save Parameters");
        panTop.add(btnSave,gbcbt1);

        /*
         * Button 2 - Generate values
         */
        GridBagConstraints gbcbt2 = new GridBagConstraints();
        gbcbt2.gridx = gbcbt1.gridx+1;
        gbcbt2.gridy = gbcbt1.gridy;
        gbcbt2.anchor = GridBagConstraints.LINE_START;
        gbcbt2.insets = new Insets(5,5,5,5);
        btnGenerate = new JButton("Generate");
        panTop.add(btnGenerate,gbcbt2);

        /*
         * Button 3 - Close
         */
        GridBagConstraints gbcbt3 = new GridBagConstraints();
        gbcbt3.gridx = gbcbt2.gridx+1;
        gbcbt3.gridy = gbcbt2.gridy;
        gbcbt3.anchor = GridBagConstraints.LINE_START;
        gbcbt3.insets = new Insets(5,5,5,5);
        btnClose = new JButton("Close");
        panTop.add(btnClose,gbcbt3);
        panTop.setPreferredSize(new Dimension(Constants.TOPWIDTH,Constants.TOPDEPTH));      

        panScreen.add(panTop, BorderLayout.PAGE_START);

        /*
         * Middle panel - table
         */
        panMid = new JPanel(new GridBagLayout());
        JLabel lblIncome = new JLabel("Income Categories :");
        GridBagConstraints gbc_lblIncome = new GridBagConstraints();
        gbc_lblIncome.insets = new Insets(0,10,0,0);
        gbc_lblIncome.gridx = 0;
        gbc_lblIncome.gridy = 0;
        gbc_lblIncome.anchor = GridBagConstraints.FIRST_LINE_START;
        panMid.add(lblIncome, gbc_lblIncome);
        JLabel lblIncmis = new JLabel("Available");
        GridBagConstraints gbc_lblIncmis = new GridBagConstraints();
        gbc_lblIncmis.gridx = gbc_lblIncome.gridx;
        gbc_lblIncmis.gridy = gbc_lblIncome.gridy+1;
        gbc_lblIncmis.anchor = GridBagConstraints.CENTER;
        panMid.add(lblIncmis, gbc_lblIncmis);
        JLabel lblIncsel = new JLabel("Selected");
        GridBagConstraints gbc_lblIncsel = new GridBagConstraints();
        gbc_lblIncsel.gridx = gbc_lblIncmis.gridx+2;
        gbc_lblIncsel.gridy = gbc_lblIncmis.gridy;
        gbc_lblIncsel.anchor = GridBagConstraints.CENTER;
        panMid.add(lblIncsel, gbc_lblIncsel);
        spIncomeMissing = new JScrollPane(listIncomeMissing);   
        GridBagConstraints gbc_spIncmis = new GridBagConstraints();
        gbc_spIncmis.insets = new Insets(0,10,0,0);
        gbc_spIncmis.gridx = gbc_lblIncome.gridx;
        gbc_spIncmis.gridy = gbc_lblIncmis.gridy+1;
        gbc_spIncmis.gridheight = 2;
        spIncomeMissing.setPreferredSize(new Dimension(Constants.PANELWIDTH,Constants.PANELHEIGHT));
        panMid.add(spIncomeMissing, gbc_spIncmis);
        btnISelect = new JButton("Sel");
        GridBagConstraints gbc_btISelect = new GridBagConstraints();
        gbc_btISelect.insets = new Insets(40,5,5,5);
        gbc_btISelect.gridx = gbc_spIncmis.gridx+1;
        gbc_btISelect.gridy = gbc_spIncmis.gridy;
        gbc_btISelect.anchor = GridBagConstraints.PAGE_END;
        gbc_btISelect.fill = GridBagConstraints.HORIZONTAL;
        panMid.add(btnISelect, gbc_btISelect);
        btnIDeselect = new JButton("Des");
        GridBagConstraints gbc_btIDeselect = new GridBagConstraints();
        gbc_btIDeselect.insets = new Insets(0,5,5,5);
        gbc_btIDeselect.gridx = gbc_btISelect.gridx;
        gbc_btIDeselect.gridy = gbc_btISelect.gridy+1;
        gbc_btIDeselect.anchor = GridBagConstraints.PAGE_START;
        gbc_btIDeselect.fill = GridBagConstraints.HORIZONTAL;
        panMid.add(btnIDeselect, gbc_btIDeselect);
        spIncomeSelected = new JScrollPane(listIncomeSelect);   
        GridBagConstraints gbc_spIncsel = new GridBagConstraints();
        gbc_spIncsel.insets = new Insets(0,0,0,10);
        gbc_spIncsel.gridx =gbc_btISelect.gridx+1;
        gbc_spIncsel.gridy = gbc_spIncmis.gridy;
        gbc_spIncsel.gridheight = 2;
        spIncomeSelected.setPreferredSize(new Dimension(Constants.PANELWIDTH,Constants.PANELHEIGHT));
        panMid.add(spIncomeSelected, gbc_spIncsel);

        JLabel lblExpense = new JLabel("Expense Categories :");
        GridBagConstraints gbc_lblExpense = new GridBagConstraints();
        gbc_lblExpense.insets = new Insets(0,10,0,0);
        gbc_lblExpense.gridx = gbc_lblIncome.gridx;
        gbc_lblExpense.gridy = gbc_lblIncmis.gridy+gbc_spIncmis.gridheight+1;
        gbc_lblExpense.anchor = GridBagConstraints.FIRST_LINE_START;
        panMid.add(lblExpense, gbc_lblExpense);
        JLabel lblExpmis = new JLabel("Available");
        GridBagConstraints gbc_lblExpmis = new GridBagConstraints();
        gbc_lblExpmis.gridx = gbc_lblExpense.gridx;
        gbc_lblExpmis.gridy = gbc_lblExpense.gridy+1;
        gbc_lblExpmis.anchor = GridBagConstraints.CENTER;
        panMid.add(lblExpmis, gbc_lblExpmis);
        JLabel lblExpsel = new JLabel("Selected");
        GridBagConstraints gbc_lblExpsel = new GridBagConstraints();
        gbc_lblExpsel.gridx = gbc_lblExpmis.gridx+2;
        gbc_lblExpsel.gridy = gbc_lblExpmis.gridy ;
        gbc_lblExpsel.anchor = GridBagConstraints.CENTER;
        panMid.add(lblExpsel, gbc_lblExpsel);
        spExpenseMissing = new JScrollPane(listExpenseMissing); 
        GridBagConstraints gbc_spExpmis = new GridBagConstraints();
        gbc_spExpmis.insets = new Insets(0,10,10,0);
        gbc_spExpmis.gridx = gbc_lblExpense.gridx;
        gbc_spExpmis.gridy = gbc_lblExpsel.gridy+1;
        gbc_spExpmis.gridheight = 2;
        spExpenseMissing.setPreferredSize(new Dimension(Constants.PANELWIDTH,Constants.PANELHEIGHT));
        panMid.add(spExpenseMissing, gbc_spExpmis);
        btnESelect = new JButton("Sel");
        GridBagConstraints gbc_btESelect = new GridBagConstraints();
        gbc_btESelect.insets = new Insets(40,5,5,5);
        gbc_btESelect.gridx = gbc_spExpmis.gridx+1;
        gbc_btESelect.gridy = gbc_spExpmis.gridy;
        gbc_btESelect.anchor = GridBagConstraints.PAGE_END;
        gbc_btESelect.fill = GridBagConstraints.HORIZONTAL;
        panMid.add(btnESelect, gbc_btESelect);
        btnEDeselect = new JButton("Des");
        GridBagConstraints gbc_btEDeselect = new GridBagConstraints();
        gbc_btEDeselect.insets = new Insets(0,5,5,5);
        gbc_btEDeselect.gridx = gbc_btESelect.gridx;
        gbc_btEDeselect.gridy = gbc_btESelect.gridy+1;
        gbc_btEDeselect.anchor = GridBagConstraints.PAGE_START;
        gbc_btEDeselect.fill = GridBagConstraints.HORIZONTAL;
        panMid.add(btnEDeselect, gbc_btEDeselect);
        spExpenseSelected = new JScrollPane(listExpenseSelect); 
        GridBagConstraints gbc_spExpsel = new GridBagConstraints();
        gbc_spExpsel.insets = new Insets(0,0,10,10);
        gbc_spExpsel.gridx = gbc_btESelect.gridx+1;
        gbc_spExpsel.gridy = gbc_spExpmis.gridy;
        gbc_spExpsel.gridheight = 2;
        spExpenseSelected.setPreferredSize(new Dimension(Constants.PANELWIDTH,Constants.PANELHEIGHT));
        panMid.add(spExpenseSelected, gbc_spExpsel);

        panMid.setPreferredSize(new Dimension(Constants.MIDWIDTH,Constants.MIDDEPTH));
        panScreen.add(panMid,BorderLayout.CENTER);
        /*
         * Set dirty back to false so real changes are caught
         */
        this.pack();
    }

}

package mvc;

public abstract class Constants {

    /*
     * Screen Size Parameters
     */
    public static final int FRAMEWIDTH =800;
    public static final int FRAMEDEPTH = 800;
    public static final int TOPWIDTH = FRAMEWIDTH-40;
    public static final int TOPDEPTH = 200;
    public static final int MIDWIDTH = FRAMEWIDTH-40;
    public static final int MIDDEPTH = FRAMEDEPTH - TOPDEPTH;
    public static final int ADDSCREENWIDTH = 350;
    public static final int ADDSCREENHEIGHT =300;
    public static final int PANELWIDTH = 300;
    public static final int PANELHEIGHT= 200;
    public static final int GENSCREENWIDTH = 1000;
    public static final int GENSCREENHEIGHT = 800;
    /*
     * Generate screen panel sizes
     */
    public static final int GENBOTWIDTH = GENSCREENWIDTH-50;
    public static final int GENBOTDEPTH = (GENSCREENHEIGHT)/8;
    public static final int GENTOPWIDTH = GENSCREENWIDTH-50;
    public static final int GENTOPDEPTH = (GENSCREENHEIGHT)/8;
    public static final int GENMIDWIDTH = GENSCREENWIDTH-50;
    public static final int GENMIDDEPTH = GENSCREENHEIGHT-GENTOPDEPTH-GENBOTDEPTH-50;
    public static final int GENCATPREFWIDTH = 200;
    public static final int GENCATMINWIDTH = 100;
    public static final int GENAMOUNTWIDTH = 80;
}

package mvc;

import javax.swing.JFrame;

public class MVC {
        /**
         * Create the GUI and show it.  For thread safety,
         * this method should be invoked from the
         * event-dispatching thread.
         */
        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new BudgetValuesWindow();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }

        public static void main(String[] args) {
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }

}

Upvotes: 0

Views: 182

Answers (2)

camickr
camickr

Reputation: 324088

Why are you using "static" for your variables? You don't use static for the components and don't need static for the variables.

However, when I make the window smaller I get this:

The basic answer to your question is that when using a GridBagLayout, if there is not enough space for a component to be displayed at its preferred size, then the component is displayed at its "minimum size". In the case of a scroll pane the minimum is (0, 0).

So the solution is to provide your scroll panes with a reasonable minimum size.

Also, it is not necessary to create a new GridBagConstraint for every component. In many cases where the parameters are similar you can reuse the same constraint and just change a specific property, for example, the gridx or gridy.

Upvotes: 1

durron597
durron597

Reputation: 32323

Do NOT use GridBagLayout.

The best way to do components that can resize appropriately in Java is to use GroupLayout.

GroupLayout:

  • Properly respects specified sizes
  • Investigates inherited sizes from child components
  • Supports gaps to which you can assign ranges

This is definitely your best bet for fixing this problem; I understand it will be a lot of work to relayout your entire page, but trust me, it is worth it.

One piece of advice I have for you to make the code more manageable: make custom components and break the JFrame into multiple classes. For example, these sections should be broken into their own class (and then you populate two instances of them):

Boxed form

Doing this will:

  • Eliminate redundant code
  • Make the controls easier to lay out (because each piece is less complicated)
  • Make the code easier to maintain in the future

Upvotes: 0

Related Questions