Hallo!
Ich arbeite gerade an einer Art Wizard-API (ja, ich weiß, dass es so etwas schon gibt, aber ich habe schon seit einiger Zeit versucht, die vorhandene API meinen Bedürfnissen anzupassen, aber es hat nie so richtig geklappt, außerdem bin ich so flexibler).
Die API funktioniert folgendermaßen: Es gibt eine Hauptklasse Wizard, welche einen JDialog anzeigt, sobald man die showDialog()-Methode aufruft. Diese soll am Ende von dem Assistenten gesammelte Daten zurückgeben, d.h. sie blockiert solange, bis entweder der Dialog mit dem "Fertig"-Button oder dem "Abbrechen"-Button beendet wird oder einfach geschlossen.
Vor dem Öffnen wurden einige WizardPanels registriert, die dann in einer gewissen Reihenfolge durch das Drücken der "Weiter", bzw. "Zurück"-Buttons nacheinander angezeigt werden. Am Ende wird dann die Methode getResult() der Klasse WizardPanel aufgerufen, welche gesammelte Informationen des jeweiligen Panels zurückgibt.
Wird der Dialog durch also, wie oben erklärt, beendet, wird die Methode closeDialog() mit einem entsprechenden Return-Code aufgerufen, welche den wartenden Thread mit notify() eigentlich wieder wecken sollte. Allerdings funktioniert das Aufwecken nicht, sodass die blockierende Methode bis in alle Ewigkeiten wartet. Warum weiß ich nicht genau.
Kann mit da vielleicht jemand helfen? Danke.
Hier sind die betreffenden Codestellen aus der Klasse Wizard (gekürzt):
Wizard erweitert WindowAdapter und so wird die Methode windowClosing() aufgerufen, sobald der Dialog über die "Schließen"-Schaltfläche verlassen wird. CancelAction und FinishAction sind jeweils den entsprechenden Buttons zugewiesen.
Gruß,
Jan.
Ich arbeite gerade an einer Art Wizard-API (ja, ich weiß, dass es so etwas schon gibt, aber ich habe schon seit einiger Zeit versucht, die vorhandene API meinen Bedürfnissen anzupassen, aber es hat nie so richtig geklappt, außerdem bin ich so flexibler).
Die API funktioniert folgendermaßen: Es gibt eine Hauptklasse Wizard, welche einen JDialog anzeigt, sobald man die showDialog()-Methode aufruft. Diese soll am Ende von dem Assistenten gesammelte Daten zurückgeben, d.h. sie blockiert solange, bis entweder der Dialog mit dem "Fertig"-Button oder dem "Abbrechen"-Button beendet wird oder einfach geschlossen.
Vor dem Öffnen wurden einige WizardPanels registriert, die dann in einer gewissen Reihenfolge durch das Drücken der "Weiter", bzw. "Zurück"-Buttons nacheinander angezeigt werden. Am Ende wird dann die Methode getResult() der Klasse WizardPanel aufgerufen, welche gesammelte Informationen des jeweiligen Panels zurückgibt.
Wird der Dialog durch also, wie oben erklärt, beendet, wird die Methode closeDialog() mit einem entsprechenden Return-Code aufgerufen, welche den wartenden Thread mit notify() eigentlich wieder wecken sollte. Allerdings funktioniert das Aufwecken nicht, sodass die blockierende Methode bis in alle Ewigkeiten wartet. Warum weiß ich nicht genau.
Kann mit da vielleicht jemand helfen? Danke.
Hier sind die betreffenden Codestellen aus der Klasse Wizard (gekürzt):
Code:
public static final Integer NO_RETURN_CODE = new Integer(0);
public static final Integer OK_RETURN_CODE = new Integer(1);
public static final Integer CANCEL_RETURN_CODE = new Integer(2);
public static final Integer CLOSED_RETURN_CODE = new Integer(3);
public static final String RETURN_CODE_KEY = "returnCode";
public static final String IS_DISPLAYING_PROPERTY = "isDisplaying";
public static final String CURRENT_PANEL_PROPERTY = "currentPanel";
protected HashMap<String, Object> data;
protected JDialog dialog;
protected Integer returnCode;
private CardLayout cardLayout;
private JButton backButton;
private JButton nextButton;
private JButton cancelButton;
private WizardPanel<? extends JComponent> currentPanel;
private WizardPanel<? extends JComponent> oldPanel;
private final HashMap<Object, WizardPanel<? extends JComponent>> panels;
public void closeDialog(Integer returnCode) {
if (dialog.isVisible()) {
if (!returnCode.equals(OK_RETURN_CODE)
&& !returnCode.equals(CANCEL_RETURN_CODE)
&& !returnCode.equals(CLOSED_RETURN_CODE))
throw new IllegalArgumentException("Invalid return code: "
+ returnCode);
this.returnCode = returnCode;
currentPanel.aboutToHidePanel(new WizardPanelEvent(this,
currentPanel));
dialog.dispose();
currentPanel.hidingPanel(new WizardPanelEvent(this, currentPanel));
firePropertyChange(IS_DISPLAYING_PROPERTY, true, false);
synchronized (this) {
this.notify();
}
}
}
public HashMap<String, Object> showDialog() {
if (!dialog.isVisible()) {
if (currentPanel == null)
throw new WizardPanelNotFoundException(this,
"No panels registered.");
resetComponents();
currentPanel.aboutToDisplayPanel(new WizardPanelEvent(this,
currentPanel));
dialog.pack();
dialog.setVisible(true);
currentPanel.setDisplaying(true);
currentPanel.displayingPanel(new WizardPanelEvent(this,
currentPanel));
firePropertyChange(IS_DISPLAYING_PROPERTY, false, true);
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
}
data.put(RETURN_CODE_KEY, returnCode);
return data;
}
return null;
}
@Override
public void windowClosing(WindowEvent e) {
closeDialog(CLOSED_RETURN_CODE);
}
private class CancelAction extends AbstractAction {
public CancelAction() {
super("Abbrechen");
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_A));
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A,
InputEvent.ALT_DOWN_MASK));
}
public void actionPerformed(ActionEvent e) {
closeDialog(CANCEL_RETURN_CODE);
}
}
private class FinishAction extends AbstractAction {
public FinishAction() {
super("Fertig");
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_F));
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
0));
}
public void actionPerformed(ActionEvent e) {
closeDialog(OK_RETURN_CODE);
}
}
Wizard erweitert WindowAdapter und so wird die Methode windowClosing() aufgerufen, sobald der Dialog über die "Schließen"-Schaltfläche verlassen wird. CancelAction und FinishAction sind jeweils den entsprechenden Buttons zugewiesen.
Gruß,
Jan.