Hi, ich habe mehrere Windows in einer HashMap. Die Windows können von allen möglichen Typen sein, also JFrame, Frame, JDialog, JWindow, ... eben alles was von Window erbt.
Jetzt möchte ich alle Windows, die sich in der HashMap befinden, synchron zueinander verschieben. Ich adde also jedem Window einen Component Listener
wenn jetzt ein Fenster verschoben wird, bekomme ich das ja durch Aufruf der componentMoved-Methode vom ComponentListener mit. In diesem Fall lasse ich eine eigene Methode für die weitere Verarbeitung sorgen:
Wenn ich jetzt einfach alle Fenster in der HashMap in der move-Methode verschieben würde, hätte das ja eine Endlosschleife zur Folge, da bei jedem Aufruf wieder für alle Fenster ein ComponentEvent geworfen werden würde. Also hab ich mir gedacht, legste n Counter an. Beim Aufruf der Methode wird überprüft, ob der Counter == 0 ist. Falls ja, handelt es sich nicht um ein Folgeevent und der eigentliche Code wird ausgeführt:
Zuerst wird der Counter auf die Anzahl der Fenster in der HashMap - 1 gesetzt, und anschließend alle Fenster (ohne das, welches das Event ausgelöst hat) um die entsprechenden Pixel mit der Methode setLocation verschoben.
Ist der Counter ungleich (größer) 0, handelt es sich um ein Folgeevent, und der Counter wird um den Wert eins heruntergezählt.
Wenn ich da jetzt keinen Denkfehler drin habe, sollte das ja so funktionieren!? Tut es aber nicht. Und zwar werden manchmal alle verschoben, manchmal gar keine, und manchmal nicht alle. Woran das liegt, habe ich auch schon herausgefunden. Und zwar wird, wenn ich bei einem Frame/JFrame die Methode setLocation aufrufe, zweimal ein ComponentEvent gefeuert. Bei einem JDialog aber (wie ich es eigentlich auch von den Frames erwarte) nur einmal.
Ich kann 100pro sicher sagen, dass kein Frame in der HashMap doppelt ist, selbst wenn, sollte es durch die Counter-Methode ja nicht zu Fehlern kommen. Und da nirgends anders "addComponentListener", außer in der oben genannten Methode aufgerufen wird, kann ich eigentlich auch ausschließen, dass bei Frames versehentlich zwei ComponentListener geadded werden.
Weiß jemand warum das so ist, und wie ich das beheben kann?
Danke!
Jetzt möchte ich alle Windows, die sich in der HashMap befinden, synchron zueinander verschieben. Ich adde also jedem Window einen Component Listener
Code:
public void addWindow(Window win) throws NotVisibleException {
if (!win.isVisible()) {
throw new NotVisibleException(win.getName() + " must be visible");
}
win.addWindowListener(this);
win.addComponentListener(this);
WinState wis = new WinState();
wis.setXPos(win.getLocationOnScreen().getX());
wis.setYPos(win.getLocationOnScreen().getY());
if (win instanceof Frame) {
wis.setExtendedState(((Frame)win).getExtendedState());
}
map.put(win, wis);
}
wenn jetzt ein Fenster verschoben wird, bekomme ich das ja durch Aufruf der componentMoved-Methode vom ComponentListener mit. In diesem Fall lasse ich eine eigene Methode für die weitere Verarbeitung sorgen:
Code:
public void componentMoved(ComponentEvent evt) {
move(evt);
}
Wenn ich jetzt einfach alle Fenster in der HashMap in der move-Methode verschieben würde, hätte das ja eine Endlosschleife zur Folge, da bei jedem Aufruf wieder für alle Fenster ein ComponentEvent geworfen werden würde. Also hab ich mir gedacht, legste n Counter an. Beim Aufruf der Methode wird überprüft, ob der Counter == 0 ist. Falls ja, handelt es sich nicht um ein Folgeevent und der eigentliche Code wird ausgeführt:
Zuerst wird der Counter auf die Anzahl der Fenster in der HashMap - 1 gesetzt, und anschließend alle Fenster (ohne das, welches das Event ausgelöst hat) um die entsprechenden Pixel mit der Methode setLocation verschoben.
Ist der Counter ungleich (größer) 0, handelt es sich um ein Folgeevent, und der Counter wird um den Wert eins heruntergezählt.
Code:
protected void move(ComponentEvent evt) {
if (counterMove == 0) {
counterMove = map.size() - 1;
Window moved = (Window)evt.getSource();
Window cur = null;
WinState ws = (WinState)map.get(moved);
double x = moved.getLocationOnScreen().getX() - ws.getXPos();
double y = moved.getLocationOnScreen().getY() - ws.getYPos();
Vector wins = new Vector(map.keySet());
for (int i = 0; i < wins.size(); i++) {
cur = (Window)wins.get(i);
if (cur != moved) {
cur.setLocation((int)(cur.getLocationOnScreen().getX() + x), (int)(cur.getLocationOnScreen().getY() + y));
}
actWinState(cur);
}
}
else {
counterMove--;
}
}
Wenn ich da jetzt keinen Denkfehler drin habe, sollte das ja so funktionieren!? Tut es aber nicht. Und zwar werden manchmal alle verschoben, manchmal gar keine, und manchmal nicht alle. Woran das liegt, habe ich auch schon herausgefunden. Und zwar wird, wenn ich bei einem Frame/JFrame die Methode setLocation aufrufe, zweimal ein ComponentEvent gefeuert. Bei einem JDialog aber (wie ich es eigentlich auch von den Frames erwarte) nur einmal.
Ich kann 100pro sicher sagen, dass kein Frame in der HashMap doppelt ist, selbst wenn, sollte es durch die Counter-Methode ja nicht zu Fehlern kommen. Und da nirgends anders "addComponentListener", außer in der oben genannten Methode aufgerufen wird, kann ich eigentlich auch ausschließen, dass bei Frames versehentlich zwei ComponentListener geadded werden.
Weiß jemand warum das so ist, und wie ich das beheben kann?
Danke!