Swing приложение глобальный модальный - PullRequest
0 голосов
/ 20 ноября 2008

Простой вопрос:

Может ли поворотная рама быть полностью модальной (заблокировать все остальные окна)?

Я попробовал следующее, но я все еще могу нажимать в окнах других приложений (например, в этом браузере)

JDialog myDialog  = .... 
myDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);

Пожалуйста, вставьте код, если это возможно.

Ответы [ 3 ]

3 голосов
/ 20 ноября 2008

Диалоги не должны быть глобально модальными. Каждая современная ОС категорически не одобряет глобальную модальность в своем HIG, и они могут даже отказаться от функциональности (на что указывает тот факт, что вы не можете заставить ее работать). Ваше приложение должно никогда не красть события из всей системы; это не только плохой дизайн, он почти криминален в моей книге.

Игнорируя тот факт, что большинству людей нравится многозадачность между несколькими приложениями, как насчет сценария, когда вы открываете глобально модальное диалоговое окно, а затем ваше приложение зависает? Ctrl + Alt + Del должен работать в Windows, чтобы убить приложение, но я не уверен насчет Cmd + Opt + Escape на Mac с глобально модальным диалогом (у Cocoa даже есть глобальная модальность?). Ни на одной из платформ Linux нет хороших способов убить приложения, которые полностью контролируют пользовательский интерфейс, как вы предлагаете (вам придется полностью убить X11 и запустить новый экземпляр с нуля).

Мой ответ: найди другой способ. Мне все равно, о чем просит твой клиент, они этого не хотят.

2 голосов
/ 20 ноября 2008

JFrame не предназначен, чтобы быть модальным. Используйте для этого JDialog, но при этом вы потеряете некоторые функциональные возможности JFrame. Если вы не можете смириться с потерей, вы должны заблокировать EventQueue и заменить его своим собственным, чтобы принимать события только от блокирующего.

См. Создание модальных внутренних фреймов для объяснения использования внутренних фреймов, которые также должны применяться к JFrame.

Edit: Ой, мой ответ кажется немного неправильным, так как ваш пример кода показывает, что вы уже используете подкласс Dialog для этого.

1 голос
/ 20 ноября 2008

Я не знаю о глобальном модале, но вот идея.

  1. Сделайте скриншот рабочего стола.
  2. Перейти на весь экран.
  3. Всплывающее диалоговое окно.

Так как рабочий стол - фальшивый скриншот, вы можете игнорировать любую попытку щелкнуть по нему.

Пример полноэкранного режима :

private void toggleFullScreenWindow() {
  GraphicsEnvironment graphicsEnvironment
    = GraphicsEnvironment.getLocalGraphicsEnvironment();
  GraphicsDevice graphicsDevice
    = graphicsEnvironment.getDefaultScreenDevice();
  if(graphicsDevice.getFullScreenWindow()==null) {
    dialog.dispose(); //destroy the native resources
    dialog.setUndecorated(true);
    dialog.setVisible(true); //rebuilding the native resources
    graphicsDevice.setFullScreenWindow(dialog);
  }else{
    graphicsDevice.setFullScreenWindow(null);
    dialog.dispose();
    dialog.setUndecorated(false);
    dialog.setVisible(true);
    dialog.repaint();
  }
  requestFocusInWindow();
}

К вашему сведению: API полноэкранного эксклюзивного режима .

...