# JFrame sperren



## p3lotud0 (27. Feb 2007)

Hi,

habe folgende Problemstellung:

ich besitze einen JFrame, der einen anderen aufruft (durch Button-Klick). Nun möchte ich, dass solange der zweite Frame geöffnet ist, den ersten gesperrt haben.
Habe schon gesucht und Tipps wie mit JDialog-Verwendung etc. gelesen.
Das geht bestimmt, aber ist doch recht umständlich, oder?!?

"JFrame sperren" ist als Titel eigentlich falsch gewählt, weil das weniger ein Problem ist als das Entsperren.
Habe im ActionListener beim JFrame-Aufruf (dem zweiten) einfach das aktuelle Frame auf disable gesetzt gehabt. Damit wäre das Sperren ja gelöst, nur wie mache ich dieses JFrame wieder enable?

Beim Schließen des 2. JF via WindowListener, aber wie greife ich auf das Ursprungsframe zu?
Oder ist das alles nicht das wahre und es gibt noch ne bessere Alternative?

Danke im Voraus

Saludos,

p3lotud0


----------



## dieta (27. Feb 2007)

Mit einem JDialog ist das eigentlich sehr einfach. Du übergibst ihm einfach als Owner dein Frame.
Dann noch ein setModal(true) und dein Frame wird gesperrt, sobald der Dialog geöffnet wird und wieder freigegeben sobald er wieder geschlossen wird.


----------



## AlArenal (27. Feb 2007)

Wenn du dem zweiten Frame z.B. im Konstruktor die Referenzen auf den ersten mitgibst, kannst du diese im zweiten Nutzen, um z.B. beim Schließen den ersten wieder zu enablen. Dafür müsstest du einen eigenen Konstruktor schreiben.

Sinnvoller wäre es gleich einen JDIalog zu benutzen, der bringt das von Haus aus mit und wenn du ihn einfach vor #setVisible(true) auf #setModal(true) setzt, musste auch nix mehr sperren, weil so lange eh nix an den JFrame kommt...


----------



## André Uhres (27. Feb 2007)

Ein modaler Dialog hat auch noch die Eigenschaft, daß er nach seinem Verschwinden wieder an die Stelle zurückkehrt, wo er sichtbar gemacht wurde.


----------



## p3lotud0 (27. Feb 2007)

Vielen Dank für Eure Hilfe.
Mal ne doofe Frage: Als Owner mein JFrame übergeben. Läuft das so ab: JDialog.setOwner(JFrame)? Das ist jetzt das, was ich gefunden habe.
Habe ich nämlich noch nicht mit "gewerkelt".


----------



## André Uhres (28. Feb 2007)

http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JDialog.html#JDialog(java.awt.Frame,%20java.lang.String,%20boolean)


----------



## p3lotud0 (1. Mrz 2007)

Danke Dir.


----------



## p3lotud0 (5. Mrz 2007)

Hi,

habe es jetzt doch anders gelöst, da ich es mit dem JDialog nicht wirklich richtig hinbekommen habe.
Es funktioniert auch so, wie ich es möchte. Allerdings habe ich Probleme beim Schließen des 2. Frames, denn irgendwie wird dieser Frame zwar geschlossen, aber nicht wirklich beendet.

Code in Frame1:


```
if(item.equals("Frame2")){
		    		  	setEnabled(false);
		    		  	JFrame frame2 = new JFrame("Frame2");
		    		  	new JFrameShower(frame2);
		    		  	
		    		  	frame2.addWindowListener(new WindowAdapter(){
		    		  		public void windowClosing(WindowEvent e){
		    		  			setEnabled(true);
		    		  			frame2.dispose();
		    		  		}
		    		  	});
		    		  	
		    	  }
```

Das ganze passiert beim Drücken eines Buttons: Den aktuellen Frame disable ich und rufe den 2. Frame auf. Statte ihn mit einem WindowListener aus, der auf das Schließen des Fensters reagiert und dann das 1. Frame wieder enabled.
Nur irgendwie funktioniert das dispose nicht, denn wenn ich das Projekt aufrufe und im 1. Frame komplett schließe, sagt mir mein Editor das noch etwas läuft, dass ich dann manuell schließen muss.
Wie Schließe ich das 2. Frame denn korrekt?


----------



## Wildcard (5. Mrz 2007)

dispose schließt einen Frame nicht, sondern macht ihn unsichtbar und gibt resourcen frei.
Beendet wird dein Programm erst wenn System.exit aufgerufen wird.


----------



## Guest (5. Mrz 2007)

Ok. 
habe im 1. Frame ein this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE).
Das schliesst mir doch im allgemeinen dann alle noch vorhandenen Frames, oder nicht?
Dann muesste das dispose-betroffene Frame doch auch richtig geschlossen werden?!?!


----------



## Wildcard (5. Mrz 2007)

Sofern du dort auf das X drückst, ja.


----------



## Guest (5. Mrz 2007)

Und mit welchem Befehl kann ich dann das Druecken auf das X realisieren? 
Merkwuerdig ist aber, dass selbst wenn ich beim 1.Frame das X druecke, trotzdem etwas nicht richtig geschlossen ist


----------



## Wildcard (5. Mrz 2007)

Anonymous hat gesagt.:
			
		

> Und mit welchem Befehl kann ich dann das Druecken auf das X realisieren?


Mit System.exit wenn du das Programm beenden willst  :bae:


----------



## Guest (5. Mrz 2007)

Ok, jetzt scheint es "irgendwie" zu funktionieren. Die Konsole muss ich zwar dennoch 1mal schliessen, aber dabei bleibt es bei mehrmaligen Programmaufrufen hintereinander. Zuvor musste ich fuer jeden Aufruf immer ein eigenes Fenster wieder schliessen. Danke Dir.


----------



## Guest (5. Mrz 2007)

Mhmm...

Mir ist jetzt aufgefallen, das ich mit meiner Loesung bezueglich des WindowListeners ein weiteres Problem habe:
Das 1. Frame wird bei Oeffnen des 2. Frame korrekt disabled und beim Schliessen dessen korrekt wieder enabled.

Nun habe ich aber im 2.Frame einen OK-Button, der das 2.Frame auch schliessen bzw. disposen soll. Da es ja jetzt nicht wirklich geschlossen wird, reagiert auch mein WindowListener im 1. Frame nicht mehr und enabled sich wieder.

Nur wie bekomme ich es hin, dass ich dieses "enable" auch durch das Klicken des Buttons im 2. Frame realisieren kann?
Kann ja aus dem 1.Frame schlecht einen ActionListener auf den OK-Button des 2. Frames setzen?!?

Bekommt man das vielleicht durch einen anderen Listener hin, der vielleicht auf das dispose des 2.Frames reagiert?
Sprich, welcher Listener im 1.Frame angewendet auf das 2.Frame registriert ein Klicken des Ok-Buttons oder ein damit ausgeloestes Event?

Vielen vielen Dank schon mal im Voraus fuer Loesungen/-ansaetze.

Saludos

p3lotud0


----------



## André Uhres (7. Mrz 2007)

Du könntest im zweiten Frame den ersten Frame auf "enabled" setzen. Dazu brauchst du lediglich die Referenz vom ersten Frame: diese übergibst du einfach im Konstruktor des zweiten Frames.


----------



## thE_29 (7. Mrz 2007)

Also wenn ich zB den JFrame oder JDialog mit setEnabled(false) setze kann ich trotzdem alles anklicken...


----------



## p3lotud0 (7. Mrz 2007)

Bei funktioniert das setEnabled(false)...

Was bei mir aber immer noch nicht richtig funktioniert ist das Sperren eines JFrames, wenn ich aus ihm einen anderen JFrame öffne und solange gesperrt bleibt bis ich den zweiten wieder schließe.
Das Sperren/Entsperren gelingt, aber nicht das "Drumherum".
Wie ich in einem anderen Thread schon mal angeschnitten hatte und jetzt hier ausführlich beschreiben möchte, ist folgendes:

Hatte das Sperren/Entsperren so umgesetzt:

FRAME1:

```
...
if(item.equals("Frame2")){
                     setEnabled(false);
                     JFrame frame2 = new JFrame("Frame2");
                     new JFrameShower(frame2);
                     
                     frame2.addWindowListener(new WindowAdapter(){
                        public void windowClosing(WindowEvent e){
                           frame2.dispose();
                           setEnabled(true);
                        }

                        public void windowClosed(WindowEvent e){
                           setEnabled(true);
                        }
                     });
                     
               }
```

Das ganze funktioniert problemlos, wenn ich Frame2 über die bekannten Verfahren schließe, zB. durch das Drücken auf das "X" oder auch, wenn ich im Frame2 dieses mit dem Button "OK" dispose...

Soweit so gut 

Jetzt kommt das Problem:
Wenn ich jetzt den Button "Frame2" betätige und Frame2 wieder erstelle und öffne und wieder "OK" bestätige, so wird das ganze irgendwie doppelt ausgeführt:

2x Aufruf des ActionListeners, 2x der Aufruf der Methoden, die ich im ActionListener für den "OK"-Button angelegt habe, etc.
Beim dritten Aufruf von Frame2 passiert alles 3mal.

Das Kouriose ist, dass ich beim OK-Button im Frame2 eine SQL-Abfrage ausführe (UPDATE) und habe dieses mal mit System.out anzeigen lassen.
Ich sehe nun, dass zB. beim dritten Aufruf von Frame2 nicht 3mal die gleiche UPDATE-Query ausgeführt wird, sondern hintereinander auch die beiden anderen von den vorherigen Frame2-Aufrufen!?! 

Und irgendwie sieht es so aus, dass sich die Datenbankzugriffe potenzial vergrößern, aber das kann ich nicht genau sagen.

Weiss jemand, wo da das Problem liegen könnte? Bin da absolut ratlos


----------



## André Uhres (8. Mrz 2007)

p3lotud0 hat gesagt.:
			
		

> ..Wenn ich jetzt den Button "Frame2" betätige und Frame2 wieder erstelle und öffne und wieder "OK" bestätige,
> so wird das ganze irgendwie doppelt ausgeführt..


Bei sowas bitte immer ein KSKB machen (siehe dazu "Lies mich" hier links nebendran):

```
package gui;
/*
 * FramesDemo.java
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FramesDemo extends JFrame {
    final private JButton btFrame2;
    final private JToolBar toolbar;
    public FramesDemo() {
        super("Frames Demo");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        //JComponents erzeugen:
        toolbar = new JToolBar();
        btFrame2 = new JButton("Frame2");
        //Layout:
        toolbar.add(btFrame2);
        getContentPane().add(toolbar, BorderLayout.NORTH);
        //Listener:
        btFrame2.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                btFrame2ActionPerformed(evt);
            }
        });
    }
    private void btFrame2ActionPerformed(final ActionEvent evt) {
        setEnabled(false);
        new Frame2(this).setVisible(true);
    }
    public static void main(final String args[]) {new FramesDemo().setVisible(true);}
}
class Frame2 extends JFrame{
    final private JFrame parent;
    final private JToolBar toolbar;
    final private JButton btOK;
    public Frame2(JFrame parent){
        super("Frame2");
        this.parent = parent;
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        setSize(300,200);
        setLocationRelativeTo(parent);
        //JComponents erzeugen:
        toolbar = new JToolBar();
        btOK = new JButton("OK");
        //Layout:
        toolbar.add(btOK);
        getContentPane().add(toolbar, BorderLayout.NORTH);
        //Listeners:
        btOK.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                System.out.println("OK");
                closeFrame();
            }
        });
        addWindowListener(new WindowAdapter() {
            public void windowClosing(final WindowEvent e) {
                closeFrame();
            }
        });
    }
    private void closeFrame() {
        System.out.println("closeFrame");
        parent.setEnabled(true);
        dispose();
    }
}
```


----------



## p3lotud0 (8. Mrz 2007)

Vielen Dank André für deinen super Rat!!

Habe den Fehler gefunden. Wenn ich sage was es war, werde ich sowieso gesteinigt, aber das ist mir jetzt egal 

Das war ein kleiner Fehler mit großer Wirkung und er ist mir einfach nicht aufgefallen:
Fragt nicht wieso, aber ich habe den OK-Button mit


```
static JButton buttonOK = new JButton("OK");
```

angelegt. Ja ne, ist klar...
Und mir ist es einfach nicht aufgefallen. So kann man sich auch tagelang beschäftigen...


----------

