2014-01-06 2 views
4

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

Я хотел бы следующее поведение:

  • , когда основной этап сводится к минимуму, все остальные этапы должны быть сведены к минимуму
  • , когда основной этап является не-минимизированы, все остальные этапы должны быть просто не сведены к минимуму
  • , когда любой из стадий выбран, если некоторые другие этапы не видны (скрытые за другими приложениями, например), они должны быть доведены до фронта

фИ Первые два требования легко (если я не пропустил что-то), что-то вроде:

mainStage.iconifiedProperty().addListener((observable, oldValue, newValue) -> { 
    if (newValue != null && newValue != oldValue) { 
     for (Stage s : otherStages) { s.setIconified(newValue); } 
    } 
}); 

Однако я застрял на третьем. Я попытался использовать focusedProperty, но он не работает (если я нажму на меню на одном из этапов, например, потому что он сначала выводит другие сцены на передний план, он теряет фокус, и меню не открывается) .. .

//do this for each stage 
stage.focusedProperty().addListener((observable, oldValue, newValue) -> { 
    if (Boolean.TRUE.equals(newValue) && newValue != oldValue) { 
     for (Stage s : otherStages) { 
      s.setIconified(false); 
      s.toFront(); 
     } 
     //request the focus back, but that creates issues 
     stage.requestFocus(); 
    } 
}); 

Любые идеи о том, как реализовать третье требование?

ответ

6

Решение

Использование stage.initOwner(parentStage).

Sample App

Здесь быстро тестовое приложение, которое инициализирует владельцев всех созданных этапов на начальной стадии применения.

Тестовое приложение, похоже, отвечает всем вашим требованиям (проверено на Windows 7, JavaFX 8b122).

import javafx.application.Application; 
import javafx.scene.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 

public class LotsaStages extends Application { 
    private static final Color[] STAGE_COLORS = { 
     Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW 
    }; 
    private static final double STAGE_OFFSET = 50; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     addContent(primaryStage, Color.LIGHTBLUE); 
     primaryStage.show(); 

     double offset = STAGE_OFFSET; 
     for (Color color: STAGE_COLORS) { 
      Stage child = new Stage(); 
      child.initOwner(primaryStage); 
      child.initStyle(StageStyle.UTILITY); 

      child.setX(primaryStage.getX() + offset); 
      child.setY(primaryStage.getY() + offset); 

      addContent(child, color); 

      child.show(); 

      offset += STAGE_OFFSET; 
     } 
    } 

    private void addContent(Stage child, Color color) { 
     child.setScene(
      new Scene(
       new Group(
        new Rectangle(150, 70, color) 
       ) 
      ) 
     ); 
    } 

    public static void main(String[] args) { launch(args); } 
} 

Тест приложение довольно просто, и я не пытался воспроизвести проблемы на основе меню, так что я не уверен, что если он будет проходить правильно для обработки на основе меню или других требований, которые вы можете иметь.

Дополнительных вопросы

Так в основном initOwner "ссылка" дети на главную сцену?

Да, MSDN explains how window ownage works on Windows. Поведение может незначительно отличаться от других платформ (поэтому JavaFX Javadoc по этому вопросу преднамеренно расплывчато), но я думаю, что большинство принципов одинаковы, и он должен работать на OS X и Linux аналогичным образом.

Из MSDN:

Чтобы создать связь между дочерним окном и родительским окном, окно поддерживает понятие собственности. Собственность устанавливается, когда свойство владельца окна (принадлежащее окну) устанавливается со ссылкой на другое окно (окно владельца).

После того, как эта связь установлена, следующие виды поведения экспонируются:

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

Когда вы открываете дочернее окно, вызывая ShowDialog, вы также должны установить свойство Owner дочернего окна. Если вы этого не сделаете, ваши пользователи не смогут восстановить дочернее окно и родительское окно, нажав кнопку панели задач. Вместо этого нажатие кнопки панели задач даст список окон, включая как дочернее, так и родительское окно, для их выбора; восстанавливается только выбранное окно.


Может, что работа с детьми, такие как child = new Stage(UNDECORATED); child.initModality(Modality.NONE);?

Да, это так.

+0

Из документации Oracle https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html#initOwner-javafx.stage.Window- «стадия может необязательно иметь владельца Окно Когда окно является владельцем сцены, он считается родителем этого этапа. Когда родительское окно закрыто, все его потоки потомков закрыты. То же самое связанное поведение применяется для родительского окна, которое обозначено. всегда будет находиться поверх своего родительского окна. Владелец должен быть инициализирован до того, как сцена станет видимой ». – Linuslabo

Смежные вопросы