JDialog против JOptionPane против JPanel правильное изменение размера экрана

У меня бесконечные проблемы, когда мне нужно показать пользователю очень сложный интерфейс с кнопками сохранения или отмены, и мне нужен этот интерфейс для правильной работы с различными разрешениями монитора. Предположим, например, что этот интерфейс должен соответствовать 17 JTextFields и JTextArea изменяемого размера на мониторе 1280 x 768 (мой 13-дюймовый ноутбук имеет вертикальный размер 760 пикселей).

вот 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);  
    }
}

Теперь я хотел бы, чтобы приведенный выше пример вел себя так, чтобы:

  1. Размер окна изменяется без обрезки содержимого
  2. Размер окна каким-то образом зависит от разрешения монитора.
  3. Мне не нужно статически указывать максимальный размер, минимальный размер и предпочтительный размер (например, с помощью редактора графического интерфейса NetBeans), так что каждый раз, когда мне приходится проводить многочисленные тесты, чтобы узнать правильный размер
  4. JtextArea изменяет свой размер по вертикали в зависимости от разрешения по вертикали до максимума.

person dendini    schedule 09.03.2013    source источник
comment
однако я могу вызвать pack () и setSize и после нескольких попыток найти правильный размер. Цель состоит в том, чтобы сделать «несколько попыток» на каждом компьютере, на котором это предназначено для работы? Потому что один номер не обязательно подойдет для другого экрана / PLAF / OS ...   -  person Andrew Thompson    schedule 09.03.2013
comment
Если ответ здесь не JScrollPane, то я не понимаю вопроса (что также является большой вероятностью).   -  person Andrew Thompson    schedule 09.03.2013
comment
Цель состоит в том, чтобы Java вычислила правильный размер окна на основе разрешения экрана и, возможно, некоторого минимального размера, который я укажу. JScrollPane слишком экстремален для решения, потому что я не хочу скрывать элементы.   -  person dendini    schedule 09.03.2013
comment
+1 для sscce.   -  person trashgod    schedule 11.03.2013


Ответы (3)


Вы можете добавить в диалоговое окно панель параметров, как показано здесь и здесь.

Кроме того, позвоните setSize() после pack().

Приложение: вот вариант вашего 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(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);
        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        JScrollPane jsp = new JScrollPane(panel){

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(320, 2 * screenSize.height / 3);
            }
        };
        JOptionPane optPane = new JOptionPane();
        optPane.setMessage(jsp);
        optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
        optPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
        JFrame f = new OptionPanePanel();
        f.setDefaultCloseOperation(EXIT_ON_CLOSE);
        f.add(optPane);
        f.pack();
        f.setLocationByPlatform(true);
        f.setVisible(true);
    }
}
person trashgod    schedule 09.03.2013
comment
Это еще один вариант, который у меня есть, но он, кажется, не лучше с точки зрения размеров, чем два предложенных мной примера. - person dendini; 09.03.2013
comment
Тогда я тоже не понимаю вопроса. Обычная проблема - панели параметров, которые выходят за пределы экрана, для которых может потребоваться панель прокрутки. - person trashgod; 09.03.2013
comment
Я отредактировал свой вопрос с помощью SSCCE, потому что понял, что он слишком общий. - person dendini; 11.03.2013
comment
Я уточнил выше; см. также эти вопросы и ответы. - person trashgod; 11.03.2013
comment
Хороший ответ, хотя мне не нравится идея прокрутки диалогового окна. Я действительно изменил определение размера вашего монитора для многомониторных настроек .. см. Мое последнее изменение - person dendini; 12.03.2013

как я могу показать что-то подобное, чтобы:

Я не знаю, что это значит. Разместите свой SSCCE, который точно показывает нам проблему, с которой вы столкнулись.

У меня это отлично работает:

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

public class OptionPanePanel extends JFrame
{
    public OptionPanePanel()
    {
        JPanel panel = new JPanel( new BorderLayout() );
        JPanel north = new JPanel();
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );
        north.add( new JTextField(10) );

        JTextArea textArea = new JTextArea(5, 20);

        panel.add(north, BorderLayout.NORTH);
        panel.add(new JScrollPane(textArea));

        int result = JOptionPane.showConfirmDialog(
            this, panel, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
    }


    public static void main(String[] args)
    {
        JFrame frame = new OptionPanePanel();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);
    }
}
person camickr    schedule 09.03.2013
comment
Я добавил SSCCE с конкретной проблемой, ваш SSCCE выравнивает по горизонтали все его JTextFields, в то время как проблема заключается в вертикальной недвижимости мониторов ... - person dendini; 11.03.2013

Спасибо за ответы, до сих пор я пришел с этим решением: получить высоту монитора, а если меньше 1024, показать небольшой диалог в JscrollPane (спасибо trashgod за его указание), в противном случае показать нормальный диалог со стандартной высотой (я приходится рассчитывать пробным путем к сожалению)

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
        }
    }
}
person dendini    schedule 12.03.2013