Установите минимальный размер JFrame в Swing - PullRequest
0 голосов
/ 17 апреля 2020

Надеюсь, у вас хороший день.


ПРИМЕЧАНИЕ: Я обнаружил проблему с этим - High DPI Scaling. Поскольку мой компьютер масштабировал все до 250%, setMinimumSize не работал. Здесь - это сообщение об ошибке. У кого-нибудь есть обходной путь, который не использует addComponentListener (рассуждения приведены ниже).


Сегодня я работал над проектом Java Swing, когда пытался изменить минимальный размер для окна JFrame. Сначала я попробовал frame.setMinimumSize(new Dimension(500, 500));. Проблема была (я думаю, что это связано с моими размерами экрана), что он выполнял своего рода работу, но это позволило бы мне изменить размер окна менее чем 500, 500 (окно перестало бы изменять размеры примерно на 100 пикселей).

РЕДАКТИРОВАТЬ: Вот код, который я использовал для проверки этого:

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

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

Вот что происходит с кадром, когда я изменяю его размер:

Using setMinimumSize()

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

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));
        frame.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent evt) {
                Dimension size = frame.getSize();
                Dimension min = frame.getMinimumSize();
                frame.setSize((int) Math.max(min.getHeight(), size.getHeight()),
                        (int) Math.max(min.getWidth(), size.getWidth()));
            }
        });

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

Вот что происходит, когда я изменяю размер этого:

Using addComponentListener()

Проблема с этим заключалась в том (хотя это работало ), если бы я попытался изменить размер до минимального размера, это сильно бы сработало, так как недостаточно быстро изменить его, прежде чем пользователь изменит его.

После еще одного поиска я нашел сообщение об ошибке здесь . Я опробовал этот код в комментариях (да, я действительно отредактировал его для использования Math.max):

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

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test") {
            @Override
            public Dimension getPreferredSize()
            {
                Dimension pSize = super.getPreferredSize();
                Dimension mSize = getMinimumSize();
                int wid, ht;

                wid = Math.max(pSize.width, mSize.width);
                ht = Math.max(pSize.height, mSize.height);
                return new Dimension(wid, ht);
            }
        };

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

Это не повлияло на окно (он вел себя точно так же, как первый setMinimumSize трюк) .

РЕДАКТИРОВАТЬ 2: Я также попробовал это (как предложил @camickr):

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

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.setSize(750, 750);
        frame.setVisible(true);
    }
}

Но он дал тот же результат, что и первый трюк (setMinimumSize ).

Я также удалил все setPreferredSize строки, так как нет менеджера компоновки (подробнее здесь ).

Я использую Windows 10 и JDK v13 .0.2 - вот вывод из java -version:

java version "13.0.2" 2020-01-14
Java(TM) SE Runtime Environment (build 13.0.2+8)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

и вывод из javac -version:

javac 13.0.2

РЕДАКТИРОВАТЬ 3: Я недавно попытался использовать JDK 11, но он дал те же результаты, что и JDK 13 (похоже, это спецификация компьютера / платформы c).

Кто-нибудь знает способ исправить это?

...