【问题标题】:JDialog vs JOptionPane vs JPanel correct screen resizeJDialog vs JOptionPane vs JPanel 正确调整屏幕大小
【发布时间】:2013-03-09 13:00:44
【问题描述】:

当我需要向用户展示一些带有保存或取消按钮的非常复杂的界面并且需要该界面正确处理不同的显示器分辨率时,我遇到了无穷无尽的问题。 例如,假设此接口需要在 1280 x 768 显示器中容纳 17 个 JTextField 和一个可调整大小的 JTextArea(我的 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. 我不必静态指定 maximumSize、MinimumSize 和 preferredSize(例如使用 NetBeans GUI 编辑器),这样每次我都必须进行大量测试才能找出正确的大小
  4. JtextArea 根据最大​​垂直分辨率垂直调整自身大小。

【问题讨论】:

  • “但是我可以调用 pack() 和 setSize 并在一些尝试后找到正确的大小。” 目的是在每台计算机上进行“一些尝试”是打算跑上去的吗?因为一个数字不一定适用于另一个屏幕/PLAF/OS...
  • 如果这里的答案不是JScrollPane 那么我不明白这个问题(这也是一个很大的可能性)。
  • Java 的目的是根据屏幕分辨率和我指定的最小尺寸计算窗口的正确尺寸。 JScrollPane 对于解决方案来说太极端了,因为我不想隐藏元素。
  • sscce+1。

标签: java swing screen-resolution joptionpane jdialog


【解决方案1】:

您可以在对话框中添加选项窗格,如herehere 所示。

顺便说一句,请致电setSize() 之后 pack()

附录:这是您的 sscce 的一个变体,它将选项窗格放置在一个滚动窗格中,该窗格具有基于屏幕几何形状的初始大小,如 here 所示。

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);
    }
}

【讨论】:

  • 这是我的另一个选择,但在尺寸方面似乎并没有比我提出的两个示例更好..
  • 那我也不明白这个问题。通常的问题是选项窗格溢出屏幕,可能需要scroll pane
  • 我用 SSCCE 编辑了我的问题,因为我意识到它太笼统了。
  • 我已经在上面详细说明了;另见Q&A
  • 很好的答案,虽然我不喜欢滚动对话框的想法。我实际上为多显示器设置更改了您的显示器尺寸检测.. 请参阅我的上次编辑
【解决方案2】:

我怎样才能显示类似上面的内容:

我不知道那是什么意思。发布您的 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);
    }
}

【讨论】:

  • 我添加了一个具有特定问题的 SSCCE,您的 SSCCE 将其所有 JTextField 水平对齐,而问题是监视器的垂直空间...
【解决方案3】:

感谢您的回答,到目前为止,我提出了这个解决方案:获取显示器高度,如果小于 1024,则在 JscrollPane 中显示一个小对话框(感谢垃圾神指向它),否则显示标准对话框身高(不幸的是我必须通过试验来计算)

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
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    相关资源
    最近更新 更多