IT-Academy Logo
Sign Up Login Help
Home - Programmieren - Java - Java Swing: Popups



Java Swing: Popups

Die Klasse Popup erlaubt es Elemente unabhängig von Layout-Manager (zeitlich begrentzt) über andere Elemente zu legen.


Autor: Patrick Faes (dreamer)
Datum: 01-11-2007, 11:29:08
Referenzen: siehe Text
Schwierigkeit: Fortgeschrittene
Ansichten: 30423x
Rating: 10 (2x bewertet)

Hinweis:

Für den hier dargestellte Inhalt ist nicht der Betreiber der Plattform, sondern der jeweilige Autor verantwortlich.
Falls Sie Missbrauch vermuten, bitten wir Sie, uns unter missbrauch@it-academy.cc zu kontaktieren.

[Druckansicht] [Als E-Mail senden] [Kommentar verfassen]



Layout-Manager hin oder her, manchmal soll ein Objekt im User-Interface eines Programms unabhängig von anderen Objekten angezeigt, bzw. drüber gelegt werden. Es könnte z.B. sein dass ein Eingabefeld nur abhängig von einer Interaktion des Users angezeigt werden soll. Dies kann in Java mit der Klasse Popup im Paket javax.swing erreicht werden. Die Klasse stellt dabei keine weitere Funktionalität zur Verfügung als die dass ein Objekt überhalb anderer Objekte gelegt werden kann.

Der Konstruktor der Klasse Popup ist als protected eingestuft, was in der objektorientiereten Programmierung heißt dass wir eine Unterklasse erstellen müssen um sie verwenden zu können. Anstatt dies zu tun, werden wir aber die PopupFactory verwenden um ein Popup zu erstellen. Eine Factory ist eine Klasse die wir verwenden können um eine Instanz einer bestimmten Klasse erstellen zu können ohne dass wir wissen müssen wie diese Klasse verwendet werden muss.

Die Methode getPopup() erwartet dabei vier Parameter:
  1. ein Elternelement
  2. den Inhalt
  3. die X-Koordinate
  4. die Y-Koordinate

Das Elternelement soll dabei ein Fenster sein, sei es nun ein JFrame oder ein JWindow. Als Inhalt kann das Popup ein willkürliches Element haben, jedoch nur eins! Die X- und Y-Koordinaten geben die Position des Popups an. Die X-Koordinate gibt die Position von links aus gesehen in Pixel an, die Y-Koordinate dagegen von oben aus. Beachten Sie dass die Position am Bildschirm gemessen wird und nicht relativ zum Elternelement.

Folgendes Codebeispiel erstellt ein Popup das ein JButton enthält und jeweils 50 Pixel vom linken und oberen Bildschirmrand entfernt positioniert wird.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
import javax.swing.JFrame;
import javax.swing.JButton;

import javax.swing.Popup;
import javax.swing.PopupFactory;

public class Beispiel1
{
   JFrame frame;
   Popup popup;

   public Beispiel1()
   {
      frame = new JFrame("Beispiel 1");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(500, 300);

      PopupFactory factory = PopupFactory.getSharedInstance();
      popup = factory.getPopup(frame, new JButton("JButton"), 50, 50);
      popup.show();

      frame.setVisible(true);
   }

   public static void main(String[] args)
   {
      Beispiel1 beispiel = new Beispiel1();
   }
}

Auf Zeile 1 bis 5 werden die benötigten Klassen importiert. Interessant sind für uns davon eigentlich nur die Klassen javax.swing.Popup und javax.swing.PopupFactory auf Zeile 4 und 5. Auf der Zeile 18 laden wir mit der Methode getSharedInstance() ein Popup in der Factory, wonach wir auf Zeile 19 das Popup mit Inhalten füllen und positionieren (dabei müssen die vorher schon besprochenen Parameter übergeben werden). Mit der Methode show() wird dann das Popup sichtbar gemacht (Zeile 20).

Das Popup enthält nur eine JButton. Wie schon gesagt, kann ein Popup immer nur ein Element enthalten. Wenn Sie komplexere Popups erstellen möchten, können Sie einen Container (wie z.B. ein JPanel) erstellen dass mehrere Elemente enthält. Im folgenden Beispiel erstellen wir ein Popup das ein JPanel mit drei JButtons enthält.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;

import javax.swing.Popup;
import javax.swing.PopupFactory;

public class Beispiel2
{
   JFrame frame;
   Popup popup;

   public Beispiel2()
   {
      frame = new JFrame("Beispiel 2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(500, 300);

      JPanel panel = new JPanel();
      panel.add(new JButton("JButton 1"));
      panel.add(new JButton("JButton 2"));
      panel.add(new JButton("JButton 3"));

      PopupFactory factory = PopupFactory.getSharedInstance();
      popup = factory.getPopup(frame, panel, 50, 50);
      popup.show();

      frame.setVisible(true);
   }

   public static void main(String[] args)
   {
      Beispiel2 beispiel = new Beispiel2();
   }
}

Auf Zeile 3 importieren wir zusätzlich die Klasse javax.swing.JPanel. Auf Zeile 19 erstellen wir dann eine JPanel und fügen diese drei JButtons hinzu (Zeile 20 bis 22). Diese JPanel fügen wir dann in das Popup ein (Zeile 25).

In den bisherigen Beispielen wurde das Popup immer an derselben Stelle platziert, nl. 50 Pixel vom linken und oberen Rand des Bildschirms entfernt. Ein Popup kann an sich unabhängig vom Elternelement platziert werden. Jedoch wurde beobachtet wie das Popup, wenn außerhalb des Elternelements (das zentrale Fenster der Anwendung) platziert wurde (wobei das linke obere Pixel als Position gilt), das Popup nicht automatisch unsichtbar gemacht oder geschlossen wurde wann das Fenster minimiert oder geschlossen wurde. (Testplattform: openSUSE 10.2, KDE 3)

Deshalb sollten Sie beim Positionieren des Popups die Position des Elternelements in Betracht ziehen. Die Position des Fensters lässt sich über die von java.awt.Component geerbten Methode getLocation() herausfinden. Diese liefert ein Objekt vom Typ java.awt.Point, das einen Punkt auf dem Bildschirm markiert anhand einer X- und einer Y-Koordinate. Folgendes Beispiel demonstriert dies:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Point;

import javax.swing.Popup;
import javax.swing.PopupFactory;

public class Beispiel3
{
   JFrame frame;
   Popup popup;

   public Beispiel3()
   {
      frame = new JFrame("Beispiel 3");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(500, 300);
      frame.setLocation(130, 75);

      JPanel panel = new JPanel();
      panel.add(new JButton("JButton 1"));
      panel.add(new JButton("JButton 2"));
      panel.add(new JButton("JButton 3"));

      Point position = frame.getLocation();

      PopupFactory factory = PopupFactory.getSharedInstance();
      popup = factory.getPopup(frame, panel, position.x + 20, Position.y + 30);
      popup.show();

      frame.setVisible(true);
   }

   public static void main(String[] args)
   {
      Beispiel3 beispiel = new Beispiel3();
   }
}

Auf Zeile 4 importieren wir die Klasse java.awt.Point. Beispielhalber positionieren wir unser Fenster auf Zeile 19 mit der Methode setLocation(). Die Position lesen wir danach wieder aus (Zeile 26). Unser Popup positionieren wir dann 20 Pixel nach rechts und 30 Pixel nach unten von der Position unseres Fensters (Zeile 29).

Tip: wenn Sie ein erfahrener Java-Programmierer sind, können Sie das Popup auch außerhalb des Fenster positionieren und mit einem WindowListener (java.awt.event.WindowListener) Veränderungen des Fensters überwachen.

Ein Popup lässt sich aber auch sehr leicht im Fenster zentrieren. Dazu müssen die Position und die Größe des Fensters sowie die größe des Popups beachtet werden. Folgendes Beispiel könnte dies verdeutlichen.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Point;

import javax.swing.Popup;
import javax.swing.PopupFactory;

public class Beispiel4
{
   JFrame frame;
   Popup popup;

   public Beispiel4()
   {
      frame = new JFrame("Beispiel 4");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(500, 300);
      frame.setLocation(130, 75);

      JPanel panel = new JPanel();
      panel.add(new JButton("JButton 1"));
      panel.add(new JButton("JButton 2"));
      panel.add(new JButton("JButton 3"));

      Point position = frame.getLocation();
      int x = position.x + frame.getWidth()/2 - panel.getPreferredSize().width/2;
      int y = position.y + frame.getHeight()/2 - panel.getPreferredSize().height/2;

      PopupFactory factory = PopupFactory.getSharedInstance();
      popup = factory.getPopup(frame, panel, x, y);
      popup.show();

      frame.setVisible(true);
   }

   public static void main(String[] args)
   {
      Beispiel4 beispiel = new Beispiel4();
   }
}

Auf Zeile 26 wird nochmal die aktuelle Position des Elternelements bestimmt. Auf Zeile 27 bis 28 werden die Koordinaten unseres Popups errechnet. Diese ergeben sich aus der aktuelle Position des Elternelements + die Hälfte der Größe dieses Elternelements - die Hälfte der Größe unseres Popups. Die Größe des Fensters können wir mit den Methoden getWidth() und getHeight() auslesen. Die Methode getPreferredSize() liefert uns die gewünschte Größe unseres Popups. Die Eigenschaften width und height enthalten die Breite, bzw. die Höhe unseres Popups in Pixel. Auf Zeile 31 können wir dann schließlich unser Popup erstellen.

Eine andere Anwendungsmöglichkeit für Popups ist es mehrere Elemente zu kombinieren, um z.B. beim Betätigen eines JButtons ein anderes Element anzuzeigen. Folgendes Beispiel erstellt ein Fenster mit eine JButton drin. Beim Betätigen dieser JButton wird eine Reihe von drei JButtons sichtbar gleich unter unserer JButton. Beim Betätigen einer dieser drei JButtons im Popup verschwindet das Popup wieder.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.


31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.Popup;
import javax.swing.PopupFactory;

public class Beispiel5 implements ActionListener
{
   JFrame frame;
   PopupFactory factory;
   Popup popup;
   JPanel panel;

   public Beispiel5()
   {
      frame = new JFrame("Beispiel 5");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(550, 300);
      frame.setLocation(130, 75);

      factory = PopupFactory.getSharedInstance();

      JButton popupButton1 = new JButton("JButton 1"),
         popupButton2 = new JButton("JButton 2"),
         popupButton3 = new JButton("JButton 3");
      popupButton1.addActionListener(this);
      popupButton2.addActionListener(this);
      popupButton3.addActionListener(this);

      panel = new JPanel();
      panel.add(popupButton1);
      panel.add(popupButton2);
      panel.add(popupButton3);

      JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
      JButton button = new JButton("Popup");
      button.addActionListener(this);
      topPanel.add(button);

      frame.getContentPane().setLayout(new BorderLayout());
      frame.getContentPane().add(topPanel, BorderLayout.NORTH);

      frame.setVisible(true);
   }

   public void actionPerformed(ActionEvent event)
   {
      JButton source = (JButton) event.getSource();
      String text = source.getText();

      if (text.equals("Popup"))
      {
         int x = source.getLocationOnScreen().x;
         int y = source.getLocationOnScreen().y + source.getPreferredSize().height;

         this.popup = this.factory.getPopup(this.frame, this.panel, x, y);
         this.popup.show();
      }
      else
      {
         this.popup.hide();
      }
   }

   public static void main(String[] args)
   {
      Beispiel5 beispiel = new Beispiel5();
   }
}

Auf Zeile 30 bis 38 erstellen wir das JPanel und die JButtons die wir benötigen für unser Popup. Das JPanel (welches im Popup angezeigt werden soll) und die PopupFactory wurden auf Zeile 17 bis 19 als Eigengschaften der Klasse definiert. Somit sind Sie auch nach Ablauf der Methode noch verfügbar, was für die Methode actionPerformed() notwendig ist. Die Methode actionPerformed() wird beim Betätigen der JButtons ausgeführt.

Auf Zeile 58 und Zeile 59 wird die Position des Popups bestimmt. Die X-Koordinate (die Position vom linken Bildschirmrand aus gesehen) ist gleich die der JButton. Diese können wir auslesen über die Methode getLocationOnScreen(), welche die Position auf dem Bildschirm ausgibt. Die Eigenschaft x enthält die X-Koordinate. Beachten Sie dass die Methode getLocation() die Position relativ zum Elternelement ausgibt und nicht die exacte Position auf dem Bildschirm. Bei deren Verwendung würde das Popup warscheinlich außerhalb unseres Fensters landen.

Die Y-Koordinate (die Position vom oberen Bildschirmrand aus gesehen) ergibt sich aus die Position der JButton plus deren Höhe. Die Größe der JButton können wir auslesen über die Methode getPreferredSize() und die Eigenschaft height. Damit lässt sich das Popup exact unter der JButton positionieren. Auf Zeile 61 und 62 wird dann das Popup erstellt und eingeblendet.

Auf Zeile 31 bis 33 wurden für die JButtons im Popup ActionListener registriert. Bei Betätigung wird die Methode hide() des Popups aufgerufen. Dadurch verschwindet das Popup. Jedoch ist es damit nicht unbedingt gelöscht, sondern wurde nur ausgeblendet. Wenn das Popup danach im Speicher noch existiert, kann es jederzeit wieder eingeblendet werden.
Verwendete Klassen:


paedubucher
Professonial
Beitrag vom:
04-01-2008, 11:42:30

Ein Musterbeispiel

Deinen Artikel kann man als Musterbeispiel betrachten:

1. Inhaltlich (sofern ich das beurteilen kann) korrekt, die Erläuterungen sind sehr verständlich.
2. Das Layout ist meiner Meinung nach perfekt. Der Code wurde schön herausgehoben (sogar die Zeilen sind nummeriert) und die Abschnitte sind sinnvoll unterteilt.
3. Die Verweise auf die JavaDoc sind äusserst sinnvoll (vielleicht hättest du eine aktuellere Doku verwenden sollen - 6.0 statt 1.4.2 - aber ich weiss ja nicht, welche Version du verwendest).

So hat ein Artikel auszusehen; 10 Punkte!

-----------------------------------------------------


[back to top]



Userdaten
User nicht eingeloggt

Gesamtranking
Werbung
Datenbankstand
Autoren:04511
Artikel:00815
Glossar:04116
News:13565
Userbeiträge:16552
Queueeinträge:06248
News Umfrage
Ihre Anforderungen an ein Online-Zeiterfassungs-Produkt?
Mobile Nutzung möglich (Ipone, Android)
Externe API Schnittstelle/Plugins dritter
Zeiterfassung meiner Mitarbeiter
Exportieren in CSV/XLS
Siehe Kommentar



[Results] | [Archiv] Votes: 1158
Comments: 0