Это относится к этому Java вопросу .
Вот моя проблема. Я написал приложение, которое позволяет людям вводить много данных, вводя множество отдельных полей. Чтобы подтвердить изменение в каждом поле, они могут часто нажимать Return (для однострочного поля) или control-S (для многострочных полей, где Return был бы допустимым вводом), но это громоздко, поэтому я также позволил полям сохранять их содержимое когда они теряют фокус. Таким образом, пользователи могут набирать tab-type, и все идет гладко.
За исключением случаев, когда они меняют поле и затем нажимают на выход окна программы X в углу. Они ожидают, что это считается потерей фокуса и сохранит это последнее изменение. Но событие потерянного фокуса не происходит, и изменение теряется.
Я мог бы добавить кнопку Готово, которая имела бы побочный эффект перемещения фокуса и сохранения последнего поля, а затем выхода. Но я не должен был. В углу есть буква X, и она должна делать правильные вещи.
Моей первой мыслью было
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(.....
, потому что я подумал, что могу опубликовать что-нибудь sh () для моего SwingWorker чтобы сказать это, вызовите потерять фокус на всем. Нет такой удачи; publi sh () защищено.
По сути, мне нужно сделать одну последнюю операцию над моими различными виджетами при нажатии X. Как это сделать?
Редактировать: я должен отметить, что каждый редактируемый виджет (выпадающий список, JTextPane и т. Д. c) был расширен для хранения актуальных релевантных данных. Все данные для этого виджета, например, является ли значение, введенное пользователем, действительным, каким оно было до того, как он его отредактировал и т. Д. c. находится в тех экземплярах расширенного класса. Там нет других мест значения хранятся; это не модель-представление-контроллер.
Причина этого в том, что виджеты могут быть изменены либо действиями пользователя, либо сетевыми сообщениями; может появиться сообщение, которое полностью исключает существующий виджет и заменяет его новым. Другими словами, doInBackground постоянно читает l oop, читает сообщения об обновлении сети и публикует sh () этих запросов на обновление для process (). Действие пользователя происходит как обычно, между вызовами процесса ().
В итоге, нет глобальной структуры данных для go, чтобы во время выхода получить значения. Все они состоят из десятков и сотен структур данных, управляемых рабочим потоком Swing. Само приложение, вне этого рабочего потока Swing, даже не знает, какие существуют значения и виджеты - все виджеты создаются, размещаются и уничтожаются сетевые сообщения с сервера. Остальная часть приложения (что там мало) не сможет безопасно добраться до данных, если захочет, если я не реализую много общих данных и блокировку.
Все это работает безупречно, и я ' Я бы не стал переделывать все это в этом крошечном выключении. Мне просто никогда не приходило в голову, что я не могу опубликовать sh дополнительное сообщение «завершение работы» в рабочей очереди для process () извне этого потока. (Я имею в виду, что потокобезопасные очереди тривиальны для реализации; почему нет?)
Если ответ «вы не можете разговаривать, чтобы качаться при выключении», я буду жить с этим. У меня есть потенциально злой обходной путь - я мог заставить x ничего не делать, кроме как отправлять сообщение на сервер, которое могло бы написать обратно «сообщение, которое вы должны закрыть», которое может сделать все остальное. Но это кажется неуклюжим.