У меня есть возможность реализовать в приложении на основе Java 1.5 Swing.
Если при обработке события AWTEvent возникает определенное исключение, мне нужно открыть альтернативную форму, устранить проблему и продолжить обработку исходного события.
Когда я повторно отправляю событие компоненту, ничего не происходит. Когда я помещаю событие в очередь событий, ничего не происходит. Я предполагаю, что в событии есть некоторые поля состояния, которые помечают его как обработанный, поэтому компоненты не получают его.
Пока я не могу найти способ воссоздать клон мероприятия. И пользовательское событие здесь не поможет, потому что я хочу, чтобы предыдущее событие было обработано.
В приложении Swing существующая очередь событий заменяется внутренней очередью.
private class ApplicationEventQueue extends EventQueue
{
private final ArrayList listeners=new ArrayList();
protected void initialize()
{
Toolkit.getDefaultToolkit().getSystemEventQueue().push(this);
}
.
.
.
}
Как часть события отправки, класс перехватывает вызов и делегаты суперкласса. Если возникнет исключение, появится всплывающее окно с сообщением «извините за неудобства».
@Override
protected void dispatchEvent(AWTEvent event)
{
try
{
super.dispatchEvent(event);
if (peekEvent() != null && userEventDispatched)
{
raiseIdleEvent();
userEventDispatched = false;
}
else
{
int eventId = event.getID();
if (eventId == KeyEvent.KEY_TYPED || eventId == MouseEvent.MOUSE_CLICKED)
{
userEventDispatched = true;
}
}
}
catch (Throwable ex)
{
onError(ex);
}
}
Требуемая функция заключается в возможности тайм-аута сеанса пользователя. Сервер выдаст определенное исключение, когда время сеанса истечет. По истечении времени ожидания пользователю предлагается выполнить повторную регистрацию, и исходное действие, которое было прервано, будет продолжено.
То, что я хотел сделать, как часть onError, я обработаю исключение, отображая форму. Это конкретное событие будет использовано, но после повторной аутентификации я могу повторно отправить это событие в приложение или, возможно, поместить его в очередь событий.
Оба подхода потерпели неудачу, так как я предполагаю, что у события есть флаги, указывающие, было ли оно отправлено и использовано.
- Происходящее событие может быть любым событием (будь то нажатие клавиши мыши).
- Определение пользовательского события не решит их проблему, так как мне нужно воспроизвести то же событие.
- Я рассмотрел клонирование события, но AWTEvent не поддерживает клонирование.
- Глубокое копирование путем сериализации, а затем десериализации события не работает, поскольку некоторые отправляемые события не сериализуются.
- Я рассматриваю возможность сброса любых переменных состояния в событии путем отражения, но это кажется опасным.
Извините за паршивое форматирование, я еще не разобрался с разметкой.
Любая помощь здесь будет оценена.
ИСПРАВЛЕНО: Спасибо за все ответы. Исправление (не найденное мной) состояло в том, чтобы перехватить исключение тайм-аута сеанса, когда был сделан вызов. Приложение выскочило диалоговое окно и попросил пользователя повторно пройти аутентификацию. После того, как аутентификация прошла успешно, диалог был закрыт. Это сработало, к моему удивлению.
Я не знаю наверняка, но кажется, что событие оставалось в очереди, когда диалоговое окно отображалось, и как только диалоговое окно было закрыто, оно доставлялось элементам управления, так или иначе.