Search code examples
javaswingscreen-resolutionjoptionpanejdialog

JDialog vs JOptionPane vs JPanel correct screen resize


I'm having endless problems when I need to show the user some very complex interface with save or cancel buttons and need this interface to correctly deal with different monitor resolutions. Suppose for instance this interface needs to fit 17 JTextFields and a resizable JTextArea in a 1280 x 768 monitor (my 13'' laptop has vertical size of 760 pixel).

here is an SSCCE:

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

public class OptionPanePanel extends JFrame
{
    private static Container layoutComponents(String title, float alignment)
    {
        JPanel container = new JPanel();
        BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
        container.setLayout(layout);

        for (int i = 0, n = 7; i < n; i++)
        {
            JTextField jtextField= new JTextField("jtextfield "+i, n);
            jtextField.setAlignmentX(alignment);
            container.add(jtextField);
            container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), 
                    new java.awt.Dimension(32767, 20)));
        }
        JTextArea jTextArea = new JTextArea(15, 30);
        container.add(jTextArea);
        for (int i = 6, n = 13; i < n; i++)
        {
            JTextField jtextField= new JTextField("jtextfield "+i, n);
            jtextField.setAlignmentX(alignment);
            container.add(jtextField);
            container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), 
                    new java.awt.Dimension(32767, 20)));
        }
        return container;
    }

    public static void main(String args[])
    {
        Container panel1 = layoutComponents("Left", Component.LEFT_ALIGNMENT);
        JOptionPane.showConfirmDialog(
            null, panel1, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);  
    }
}

Now I would like the above example to behave so that:

  1. The size of the window resizes not cropping any of the content
  2. The size of the window somehow deals differently based on the resolution of the monitor.
  3. I dont' have to statically specify maximumSize, MinimumSize and preferredSize (with the NetBeans GUI editor for instance) so that each time I have to make numerous tests just to find out the correct size
  4. the JtextArea resizes itself vertically depending on the vertical resolution up to a maximum.

Solution

  • Thank you for you answers, so far I came with this solution: get the monitor height and if smaller than 1024 then show a small dialog within a JscrollPane (thanks to trashgod for pointing it), otherwise show a normal dialog with standard height (I have to calculate by trial unfortunately)

    import java.awt.*;
    import javax.swing.*;
    
    public class OptionPanePanel extends JFrame
    {
    
        private static Container layoutComponents(String title, float alignment)
        {
            JPanel container = new JPanel();
            BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
            container.setLayout(layout);
    
            for (int i = 0, n = 7; i < n; i++)
            {
                JTextField jtextField = new JTextField("jtextfield " + i, n);
                jtextField.setAlignmentX(alignment);
                container.add(jtextField);
                container.add(createFiller());
            }
            JTextArea jTextArea = new JTextArea(15, 30);
            container.add(jTextArea);
            for (int i = 6, n = 13; i < n; i++)
            {
                JTextField jtextField = new JTextField("jtextfield " + i, n);
                jtextField.setAlignmentX(alignment);
                container.add(jtextField);
                container.add(createFiller());
            }
            return container;
        }
    
        private static Box.Filler createFiller()
        {
            return new Box.Filler(new Dimension(0, 20), new Dimension(0, 20),
                    new Dimension(Short.MAX_VALUE, 20));
        }
    
        public static void main(String args[])
        {
            Container panel = layoutComponents("Left", Component.LEFT_ALIGNMENT);
            /*Let's check the monitor height in multi monitor setup */
            GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            int monitorHeight = gd.getDisplayMode().getHeight();
            int result;
            if (monitorHeight <= 1024)
            {
                final Dimension preferredDimension = new Dimension(500, monitorHeight - 110);
                panel.setPreferredSize(preferredDimension);
                JScrollPane jsp = new JScrollPane(panel)
                {
                    @Override
                    public Dimension getPreferredSize()
                    {
                        return new Dimension(500, 700);
                    }
                };
                result = JOptionPane.showOptionDialog(null, jsp,
                        "",
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.PLAIN_MESSAGE,
                        null,
                        new String[]
                        {
                            ("save"), ("cancel")
                        }, // this is the array
                        "default");
            }
            else
            {
                final Dimension preferredDimension = new Dimension(500, 700);
                panel.setPreferredSize(preferredDimension);
                result = JOptionPane.showOptionDialog(null, panel,
                        "",
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.PLAIN_MESSAGE,
                        null,
                        new String[]
                        {
                            ("save"), ("cancel")
                        }, // this is the array
                        "default");
            }
    
            if (result == JOptionPane.OK_OPTION)
            {
                //do something
            }
        }
    }