2015-12-27 2 views
3

Приложение для JavaFX 8 должно быть doStuff(), когда оно фокусируется. Это довольно просто:Как реагировать на получение фокуса из другого приложения?

primaryStage.focusedProperty().addListener((observable, wasFocused, nowFocused) -> { 
    doStuff(); 
}); 

Однако, когда я отобразить диалоговое окно и пользователь закрывает его, doStuff() пожары. Я хочу, чтобы он срабатывал только тогда, когда пользователь переключился с другого приложения на мое, например Alt + Вкладка из браузера.

Другими словами, я хочу, чтобы doStuff() iff окно другого приложения теряет фокус, а окно моего приложения получает фокус.

Возможно ли это?

Редактировать: Ответы, высказанные FibreFoX и Appelemac, требуют явно выполнить дополнительный шаг перед отображением диалога. Это решение далека от совершенства, потому что я (или любой разработчик в целом) должен помнить об этом шаге, прежде чем показывать диалог. Забыть об этом будет сложно найти ошибки.

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

Это довольно простая функция, я был бы удивлен, если в JavaFX нет простого способа добиться этого.

ответ

1

Я бы предложил добавить слушателя к вашему диалогу, который затем позволяет вам не делать setStuff(), если Dialog был просто закрыт/потерян фокус.

Простейший способ, с помощью которого я могу думать, - установить Instant (с помощью Instant.now), когда диалог закрыт, и если приложение восстанавливает фокус, создайте еще одно Мгновенное действие и проверьте, превышает ли значение Duration.between(instantLostFocusDialog, instantGainedFocusApp).getSeconds() (или добавляет getNano() к этому более конкретно). Только тогда вы бы doStuff()

+0

Делать что для каждого отдельного диалога не звучит как весело , Я надеюсь, что есть способ справиться с этим автоматически. – gronostaj

+0

hmmm, я бы предложил создать (массив) список Instant для диалогов, создав небольшой подкласс для слушателей и реализовать добавление Instant в этот список, а затем проверку для каждого Instant. Не очень эффективно, но я думаю, что это сработает. – Appelemac

1

При открытии таких диалогов вы могли использовать глобальное логическое значение, и только тогда, когда этот глобальный коммутатор имеет значение true/false/whatever-you-choose, вы можете отреагировать на этот переключатель состояния.

public class GlobalDialogMemory{ 
    public static boolean dialogShown = false; 
} 

При использовании CDI можно впрыскивать экземпляр текущего приложения в области видимости (но вы должны использовать геттер/сеттер и нестатические булевы вместо;)

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