Search code examples
javaswinglayoutjdialog

How to limit the dimensions of a JDialog


I'm working on a JDialog subclass (let's call it PendenciesDialog) which shows an arbitrary number of equally sized, vertically stacked JPanels to the user (minimally one) and a close button below them. No interaction involved besides building the JDialog and packing it, displaying it to the user and letting them close the dialog.

These JPanels show some info on invididual monthly payment pendencies, such as account name, the pendency status and a clickable link to the payment management system. I don't think we need to care about how they are constructed.

Now for my question. I want to keep the width of the JDialog fixed at half of the screen width and limit its maximum height to half of the screen height, or shorter if the number of pendencies is small or just one. If I'm unable to achieve that by adjusting the JDialog (e.g. by overriding the JDialog's getXXXSize() methods), I'm okay with adjusting its subcomponents. I'm not sure what I need to do though.

To construct the JDialog I have set its layout manager to BoxLayout with PAGE_AXIS alignment, then added a JScrollPane to it backed by a JPanel (let's call this JPanel's reference variable pendenciesPanel) and then added a close button. That JPanel also has a BoxLayout manager with PAGE_AXIS alignment and will contain the individual pendency JPanels (actually due to the equal sizes requirement I think it should actually be a GridLayout).

I intend the JScrollPane to show a view port of pendenciesPanel and to provide scrolling if the number of pendencies is too large to fit the JDialog's (or the JScrollPane's for that matter) maximum height.

So based in this description, how do I achieve the JDialog size adjustments? From what I've read about it it seems that the most appropriate approach would be to override its getXXXSize() methods, for instance:

private final Dimension SCREEN_DIMENSION = Toolkit.getDefaultToolkit().getScreenSize();

@Override
public Dimension getMaximumSize() {
    return new Dimension(SCREEN_DIMENSION.width / 2, SCREEN_DIMENSION.height / 2);
}

but my attempts to override getMinimumSize(), getPreferredSize(), getSize() etc. don't seem to work, or perhaps I'm implementing them wrong. Will I need to adjust its internal subcomponents? Or just adjusting the JDialog will be enough? If so, how?


Solution

  • I created a simple GUI to illustrate my comment. Here's the JFrame.

    JDialog Test GUI 1

    Here's the JDialog.

    JDialog Test GUI 2

    Here's the complete example code. You'll have to modify the createPendenciesPanel method to be more realistic.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    
    public class JDialogTest implements Runnable {
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new JDialogTest());
        }
    
        private JFrame frame;
    
        @Override
        public void run() {
            frame = new JFrame("JDialog Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            frame.add(createMainPanel());
    
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private JPanel createMainPanel() {
            JPanel panel = new JPanel(new BorderLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(
                    150, 100, 150, 100));
            panel.setPreferredSize(new Dimension(400, 600));
    
            JButton button = new JButton("Open JDialog");
            button.addActionListener(new ButtonListener());
            panel.add(button);
    
            return panel;
        }
    
        public class ButtonListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                new PendenciesDialog(frame, "Pendencies Dialog");
            }
    
        }
    
        public class PendenciesDialog  extends JDialog {
    
            private static final long serialVersionUID = 1L;
    
            public PendenciesDialog(JFrame frame, String title) {
                super(frame, true);
                
                setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                setTitle(title);
    
                add(createMainPanel(frame));
                pack();
                setLocationRelativeTo(frame);
                setVisible(true);
            }
            
            private JPanel createMainPanel(JFrame frame) {
                JPanel panel = new JPanel(new BorderLayout());
                
                JPanel displayPanel = createDisplayPanel();
                JScrollPane scrollPane = new JScrollPane(displayPanel);
                panel.add(scrollPane, BorderLayout.CENTER);
                
                Dimension d = frame.getSize();
                Dimension p = displayPanel.getPreferredSize();
                panel.setPreferredSize(new Dimension(p.width + 50, d.height / 2));
                
                return panel;
            }
            
            private JPanel createDisplayPanel() {
                JPanel panel = new JPanel(new GridLayout(0, 1, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
                
                for (int i = 0; i < 6; i++) {
                    panel.add(createPendenciesPanel());
                }
                
                return panel;
            }
            
            private JPanel createPendenciesPanel() {
                JPanel panel = new JPanel(new FlowLayout());
                panel.setBackground(Color.LIGHT_GRAY);
                panel.setPreferredSize(new Dimension(100, 200));
                
                return panel;
            }
    
        }
        
    }