Может ли Java вызвать разделение экрана Windows?

Контекст


В Microsoft Windows я могу заставить окно приложения занимать половину экрана, используя ярлыки:

  • ⊞ Win +
  • ⊞ Win +

Эти ярлыки вызывают «разделение экрана», как показано на этом снимке экрана:

Я хотел бы программно изменить размер и положение JFrame таким же образом. Однако я не знаю, как добиться желаемого результата.

Я думал, что решение было:

  1. Установите ширину рамки в половину ширины экрана.
  2. Установите высоту рамки на высоту экрана (за вычетом высоты панели задач).
  3. Установите положение кадра на (0,0).

Вот MCVE:

JFrame testFrame = new JFrame();

Rectangle windowBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
testFrame.setSize(windowBounds.width / 2, windowBounds.height);
testFrame.setLocation((int) windowBounds.getMinX(), (int) windowBounds.getMinY());

testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.setVisible(true);

Это почти работает, но окно имеет небольшие поля внизу и слева:

Вопрос


Есть ли на компьютере под управлением Windows способ программно разделить экран с помощью Java или, возможно, JNI?

Выведите значения windowBounds.getMinX() и windowBounds.getMinY(), а также getMaximumWindowBounds() и убедитесь, что они разумны.

Gilbert Le Blanc 22.09.2023 22:37

Почему вы хотите сделать это сами? Если пользователи вашей программы захотят сделать это с помощью вашей программы, они могут сделать это без специальной поддержки со стороны вашей программы - Windows делает это с программами.

Thomas Kläger 22.09.2023 23:48

Вы говорите об операции, которая контролируется ОС, почему вы чувствуете необходимость воспроизводить ее в своем коде?

MadProgrammer 23.09.2023 00:21

Вероятно, вам нужен testFrame.setExtendedWindowState(Frame.MAXIMIZED_VERT).

VGR 23.09.2023 07:50

@ThomasKläger Функциональность была запрошена для приложения в моей компании. Лично я думаю, что это решает проблему, которой не существует, но компания хочет, чтобы кнопка разделяла экран (поскольку сочетания клавиш предположительно слишком сложны для изучения «нетехнически подкованными» людьми).

Cardinal System 24.09.2023 03:57

@MadProgrammer см. комментарий выше ^

Cardinal System 24.09.2023 03:57

@CardinalSystem, «поскольку сочетания клавиш, как утверждается, слишком сложны для изучения «нетехнически подкованными» людьми» - наступает момент, когда, если некоторые из них «тупые», вы перестаете их обслуживать. Сочетания клавиш универсальны для Windows (например, начиная с Windows 7?!?), поэтому я уверен, что они будут очень рады узнать о них, поскольку это значительно облегчит их повседневную жизнь.

MadProgrammer 24.09.2023 04:49

Возможно, вам следует обслуживать «нетехнически подкованных» пользователей, предлагая провести учебные курсы по Windows. (Не бесплатно... конечно.) Просто потому, что кто-то из вашей компании о чем-то попросил, это не лучшая идея!

Stephen C 24.09.2023 04:58

Если вы добавите его в свое приложение, у людей возникнут проблемы с добавлением другого приложения на другую половину экрана. Если вы их обучите, они смогут использовать эту функцию во всех приложениях. И привязка к левой или правой половине экрана — это только часть функции, которую поддерживает Windows: support.microsoft.com/en-us/windows/… — вы действительно хотите добавить все эти параметры в свой приложение?

Thomas Kläger 24.09.2023 22:47

@StephenC это внутреннее приложение, конечными пользователями которого являются наши сотрудники. Я думаю, что ваша рекомендация может быть подходящей альтернативой автоматическому разделению экрана.

Cardinal System 25.09.2023 13:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
11
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы находитесь в очень нестабильной зоне. В зависимости от предпочтений пользователя значения ширины поля, высоты/ширины панели задач или других настроек могут различаться. Если вы не используете функцию «Диспетчер окон» для позиционирования окна, вам придется провести лотерею с правильными значениями. Для этого из Java может потребоваться использование JNI и правильный вызов API Win32.

Поэтому я бы постарался избежать такой ситуации. Зачем вам это вообще нужно? И могло бы помочь, если бы ваше приложение сохраняло положение и размер окна при выходе, чтобы запомнить их при следующем запуске? Тогда пользователь по-прежнему сможет выбирать, где расположить окно, пока он не зафиксирован на левой или правой половине экрана.

Ответ принят как подходящий

Вот обходной путь, который позволил достичь желаемого результата. (Oracle JDK 21 в Windows 10)

  • Изначально установите JFrame развернутым, т. е. занимающим весь экран.
  • Добавьте WindowListener в JFrame.
  • Когда на экране [компьютера] отобразится JFrame, отрегулируйте его размер.
    (Метод windowOpened вызывается только один раз — при первом отображении окна.)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class TstFrame extends WindowAdapter {

    @Override // java.awt.event.WindowAdapter
    public void windowOpened(WindowEvent event) {
        Window window = event.getWindow();
        Dimension dim = window.getSize();
        window.setSize(dim.width / 2, dim.height);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame testFrame = new JFrame();
            testFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            testFrame.addWindowListener(new TstFrame());
            testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            testFrame.setVisible(true);
        });
    }
}

Скриншот:

Это достаточно близко к желаемому поведению. Спасибо, что ответили, а не поучали! Просто пытаюсь делать свою работу здесь :P

Cardinal System 25.09.2023 13:56

Другие вопросы по теме