Fragen zu Dialoge

Googlehupf

Erfahrenes Mitglied
Hallo zusammen!

Ich hab eine Frage zur Klasse JDialog. Also in meinen Fall wird in MainFrame.java(ist hier nicht aufgelistet, da nicht so wichtig) die Klasse AboutDialog instanziert. Und es wird dann Instanziert wenn ein Button gedrückt wird.

Application.java:
Java:
package Reaktionstester;

import java.awt.*;
import javax.swing.*;

public class Application {

  /**
   * Construct and show the application.
   */
  public Application() {
    MainFrame frame = new MainFrame();
    // Validate frames that have preset sizes
    frame.validate();

    // den folgenden code braucht man ja für das Fenster erstellen, warum brauche ich diesen beim Dialog nicht, das ist doch auch //ein Fenster eigentlich oder?
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
      frameSize.width = screenSize.width;
    }
    frame.setLocation( (screenSize.width - frameSize.width) / 2,
                      (screenSize.height - frameSize.height) / 2);
    frame.setVisible(true);
  }

  /**
   * Application entry point.
   *
   * @param args String[]
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Application();
      }
    });
  }
}

AboutDialog.java:
Java:
package Reaktionstester;

import java.awt.*;

import javax.swing.*;

public class AboutDialog extends JDialog {
	Frame owner;

	public AboutDialog(Frame owner, String title) {//von der MainFrame-klasse, wo ich AboutDialog instanziere übergebe ich ja //this, also: AboutDialog dialog = new AboutDialog(this,"title");n --> MainFrame ist ja ein Fenster, also "JFrame", warum übergibt //man this(also ein JFrame) in eine "Frame-Klasse" rein, also owner? Muss man da nicht JFrame schreiben?
		super(owner, title, true); // das ist klar, generiert sozusagen einfach einen "Jdialog"
		this.owner = owner; //hier halt zwischenspeichern, falls man owner außerhalb vom konstruktur mal braucht
		try {
			setDefaultCloseOperation(DISPOSE_ON_CLOSE);
			dlgInit();
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	private void dlgInit() throws Exception {
		JPanel contentPane = (JPanel) getContentPane(); //diese Zeile verstehe ich nicht, was macht die bitte?
		contentPane.setLayout(new BorderLayout());
		setSize(new Dimension(350, 300));
		Point parloc = owner.getLocation(); //owner ist in dem Fall ja das "Hauptfenster" und man bekommt die Location von //dem dann? oder wie geht das?
		setLocation(parloc.x + 30, parloc.y + 30); //mh irgendwie habe ich die 2 Zeilen nicht ganz begriffen, ich weiß zwar das //sie den Dialog ca. in der linken ecke oben vom Hauptfenster einfügen, aber was hinter dem 2 zeilencode steckt habe ich keine /ahnung.
		
		JPanel panel1 = new JPanel(new FlowLayout());
		contentPane.add(panel1,BorderLayout.CENTER);
		
		panel1.add(new JLabel("test"));
		
		setVisible(true);//den dialog, sichtbar machen, würd ich mal sagen
	}
}

Bitte sagt was zu jeden meiner Kommentare dazu :).

Danke!

mfg
 
Hi,

du solltest dir das Java Grundlagen-Tutorial von Sun/Oracle vielleicht noch einmal durchlesen. Ansonsten ist auch die JavaDoc (http://docs.oracle.com/javase/1.5.0/docs/api/) oft sehr informativ.

1) JFrame ist eine Unterklasse von Frame. Das bedeutet, JFrame kann mindestens all die Dinge, die Frame auch kann - und daher kann hier auch ein JFrame übergeben werden.

2) super(owner, title, true); ruft den Konstruktor von JDialog auf.

3) JPanel contentPane = (JPanel) getContentPane();
Das Content Pane ist im Prinzip die Fläche des Dialoges, wo dessen Inhalte angezeigt werden (Buttons, Text, etc.). All diese Inhalte müssen dem Content Pane hinzugefügt werden (was später mit contentPane.add(...) passiert). Die Methode getContentPane() gibt das ContentPane zurück, allerdings als Container. Da wir wissen, dass JDialog ein JPanel als ContentPane verwendet, casten wir den Rückgabewert zum Typ JPanel - wir ändern also seinen Typ von Container zu JPanel. Dies wird durch das (JPanel) gemacht.

4)
Point parloc = owner.getLocation();
setLocation(parloc.x + 30, parloc.y + 30);
Die erste Zeile speichert die Position des owners (also von dem MainFrame) in parloc. Die zweite Zeile zählt nun sowohl zum x-, als auch zum y-Wert dieser Position noch 30 px dazu, was dazu führt, dass dein AboutDialog 30 Pixel rechts und 30 Pixel unterhalb des linken, oberen Ecks deines owners beginnt.

5) Der Code in deinem Application-Konstruktor stellt sicher, dass dein Fenster nicht größer ist, als der die Anzeigefläche deines Monitors, und positioniert dann das Fenster in der Mitte dieser Fläche. Theoretisch könntest du das in deinem AboutDialog auch machen. Die Position hast du da ja aber schon gesetzt.

Ich hoffe die Dinge sind jetzt etwas klarer geworden - grundsätzlich würde ich dir empfehlen, noch 1-2 Tutorials durchzuarbeiten, um einen etwas besseren Überblick zu bekommen.
 
Java:
package Reaktionstester;
 
import java.awt.*;
import javax.swing.*;
 
public class Application {
 
  /**
   * Construct and show the application.
   */
  public Application() {
    MainFrame frame = new MainFrame();
    // Validate frames that have preset sizes
    frame.validate(); // [1]
 
// den folgenden code braucht man ja für das Fenster erstellen, warum brauche
// ich diesen beim Dialog nicht, das ist doch auch
//ein Fenster eigentlich oder? [2]
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
      frameSize.width = screenSize.width;
    }
    frame.setLocation( (screenSize.width - frameSize.width) / 2,
                      (screenSize.height - frameSize.height) / 2);
    frame.setVisible(true);
  }
 
  /**
   * Application entry point.
   *
   * @param args String[]
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Application();
      }
    });
  }
}

[1] Validieren ist hier unnötig, prinzipiell braucht man diese Funktion sehr selten. Siehe JavaDoc dazu.
[2] Nötig ist dieser Code nicht, eher Quatsch. Ein frisch erzeugter JFrame ist nicht so groß wie der Bildschirm, die Bedingungen werden also alle zu false evaluiert und der Code nicht ausgeführt. Die Position des Fensters auf die Mitte des Bildschirms zu setzen ist auch nicht unbedingt sinnvoll, im Normalfall überlässt man das dem WindowManager des unterliegenden Betriebssystems.

Java:
package Reaktionstester;
 
import java.awt.*;
 
import javax.swing.*;
 
public class AboutDialog extends JDialog {
    Frame owner; // [3]
 
    public AboutDialog(Frame owner, String title) {
//von der MainFrame-klasse, wo ich AboutDialog instanziere übergebe ich ja 
//this, also: AboutDialog dialog = new AboutDialog(this,"title");
//n --> MainFrame ist ja ein Fenster, also "JFrame", warum übergibt 
//man this(also ein JFrame) in eine "Frame-Klasse" rein, also owner?
// Muss man da nicht JFrame schreiben? [4]
        super(owner, title, true);
// das ist klar, generiert sozusagen einfach einen "Jdialog" [5]

        this.owner = owner;
//hier halt zwischenspeichern, falls man owner außerhalb vom konstruktur mal braucht [3]

// [6]
        try {
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            dlgInit();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
 
    private void dlgInit() throws Exception {
        JPanel contentPane = (JPanel) getContentPane();
//diese Zeile verstehe ich nicht, was macht die bitte? [7]

        contentPane.setLayout(new BorderLayout());
        setSize(new Dimension(350, 300)); // [8]

        Point parloc = owner.getLocation();
//owner ist in dem Fall ja das "Hauptfenster" und man bekommt die Location von
//dem dann? oder wie geht das? [9]
        setLocation(parloc.x + 30, parloc.y + 30);
//mh irgendwie habe ich die 2 Zeilen nicht ganz begriffen, ich weiß zwar das
//sie den Dialog ca. in der linken ecke oben vom Hauptfenster einfügen,
//aber was hinter dem 2 zeilencode steckt habe ich keine ahnung. [10]
        
        JPanel panel1 = new JPanel(new FlowLayout());
        contentPane.add(panel1,BorderLayout.CENTER);
        
        panel1.add(new JLabel("test"));
        
        setVisible(true);//den dialog, sichtbar machen, würd ich mal sagen [11]
    }
}

[3] Eine Referenz auf den owner zu erstellen ist nicht nötig und nicht sinnvoll, da bereits die Klasse Window in der Klassenhierarchie von JDialog die Referenz per getOwner() bereit stellt. Siehe auch [12]
[4] Nein, JFrame ist eine Klasse, this ist eine Referenz auf ein Objekt (= eine Referenz auf eine Instanz einer Klasse). this bezeichnet immer eine Referenz auf das Objekt, auf das gerade eine Methode ausgeführt wird. Siehe auch JavaInsel 5.1.3
[5] Ja, Aufruf des übergeordneten Konstruktors, der den Dialog erzeugt. Da die übergeordnete Klasse keinen default-Konstruktor (d.h. Konstruktor ohne Parameter) anbietet, muss der Konstruktor explizit aufgerufen werden.
[6] Dieser try-catch-Block ist Quatsch. Der erste Methodenaufruf gehört nicht in einen try-catch-Block, weil er keine Exception wirft. Der Zweite sollte auch keine Exception werfen, sondern die Exception in der dlgInit() abgefangen werden.
[7] Diese Zeile hohlt eine Referenz auf die contentPane des Fensters. In Java/Swing haben alle Fenster eine contentPane, in der sich der Inhalt des eigentlichen Fensters (bis auf die Menüleiste(n)) befindet.
[8] Es empfiehlt sich, nicht die absolute Größe festzusetzen, sondern die Swing-Bibliothek die Größe selbst festlegen zu lassen, weil die Größe einzelner Komponenten stark variieren kann (je nach Betriebssystem, Theme, Schriftart, Schriftgröße, …}
[9] owner.getLocation() gibt die Position des Fensters als Punkt (Point) zurück. Siehe JavaDoc dazu.
[10] Unnötig, siehe [8]. Zur Erklärung deiner Frage: In der ersten Zeile wird die Position des Hauptfensters genommen und als Point unter dem Namen parloc abgespeichert. In der nächsten Zeile wird diese Position dazu hergenommen, die Position des Dialogs zu berechnen. parloc.x bezeichnet die X-Koordinate der Position des Fensters, +30 verschiebt den Punkt um 30 Pixel nach rechts. Analog parloc.y
[11] Ja, genau.
[12] Ein paar grundlegende Infos findest du in der JavaDoc, http://docs.oracle.com/javase/7/docs/api/index.html , den Java Tutorials http://docs.oracle.com/javase/tutorial/uiswing/components/index.html und der JavaInsel (siehe meine Signatur).

Noch Fragen?
*Ich hoffe, ich hab nicht zu viel kritisiert… ;)*

[EDIT] Harrier war schneller…
 
Zuletzt bearbeitet:
Zurück