Я понимаю, что формальный способ - это прослушать событие закрытия окна, добавленное к хосту JFrame, а затем просто вызвать метод очистки на JPanel. Однако мне стало любопытно. Лишь недавно у меня возникла потребность в хуке shutdown (закрытие, выход, уход сейчас) в моей Panel, который уже используется в моей программе. И из любопытства я не хотел go повторно посещать места, где эта панель помещается в общий c старый JFrame (тот, который не требует специальной обработки) и где она просто отображается как диалог, ожидая для ввода, после чего будет отклонен. Я не хотел заставлять этот гипотетический другой кодер (я) go добавлять оконных слушателей к тем фреймам, которые уже используют мою панель, требуя от них вызова нового метода выключения. Это мой код в Panel, которому нужна дополнительная возможность, так зачем заставлять всех этих разработчиков go изменять свой код для добавления оконных слушателей? Разве JPanel не может найти это для себя?
Итак, я сделал хак, чтобы JPanel обнаруживал, когда он закрывается, без того, чтобы JFrame нуждался в слушателе окна. JPanel, для меня, теперь более осведомлен о себе ... у него есть собственный tacti c обнаружения закрытия окна, независимо от кодера, использующего мою JPanel, которому нужно писать слушателей и вызывать перехватчики выключения. Я просто хотел попробовать и сделать это без необходимости go назад и изменения существующего кода.
Поймите также, что мой хак работает только с DISPOSE_ON_CLOSE, но ... это то, что я все равно использовал для своего диалога .
Кто-нибудь может мне тогда показать, как мне это делать? Есть ли событие, связанное с недвижимостью, которое я мог бы раскопать? То, что я только что совершил, должно быть огневым. Это должно быть очень неправильно. Тем не менее, у меня есть собственный крючок отключения JPanel, и он работает. Кто-нибудь, пожалуйста, направьте меня в другое место (без очевидного выбора родительского JFrame, использующего собственное событие закрытия окна, я хотел посмотреть, может ли JPanel знать об этом самостоятельно.)
Мой хак работает .. Подскажите, что с этим не так. Это должно быть неправильно, даже если это работает для меня. Верно?
Следующий фрагмент представляет собой работающий макет.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class JPanelClosing extends JPanel {
static JFrame frame; // This frame is only here for the mmockup ... what
// follows after would be part of your own custom JPanel.
private boolean formClosing = false;
private boolean filterEvent = true;
public JPanelClosing() {
initComponents();
}
private void initComponents() {
addPropertyChangeListener(new java.beans.PropertyChangeListener() {
@Override
public void propertyChange(java.beans.PropertyChangeEvent evt) {
formPropertyChange(evt);
}
});
}
private void formPropertyChange(java.beans.PropertyChangeEvent evt) {
// This is a hack I came up with. The JPanel fires two events when
// used in a waiting input dialog of an unkown JFrame that hosts it.
// When the JFrame DefaultCloseOperation is set to DISPOSE_ON_CLOSE:
// PropertyChangeEvent fires twice when it opens, and twice when it closes.
// So, I filter out the two events to pick one, like using !valueIsAdjusting.
// Then, I filter whether it's state one, opening, or state two, closing.
// This is all kept track of using two field variables; filterEvent, and formClosing
// With DISPOSE_ON_CLOSE, (on my machine) I get:
// Form opened.
// Form Closed.
// (EXIT_ON_CLOSE and HIDE_ON_CLOSE will only produce 'Form opened')
if (!filterEvent) {
if ( formClosing ) {
System.out.println("Form Closed.");
System.exit(0);
} else {
formClosing = true;
System.out.println("Form opened.");
}
filterEvent = true;
} else { // end if value not adjusting
filterEvent = false;
}
}
public static void main (String args[] ) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame = new JFrame();
final JPanel panel = new JPanelClosing();
frame.setContentPane(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
}