With flying colours – TrayRSS 1.1.0 is released!

The release of TrayRSS 1.1.0 is here! A new GUI and many internal changes are shipped to be aware of future developements. Check it out!

TrayRSS 1.1.0 is available now! Besides some bugfixes it contains a major redesign of the configuration window. It is now seperated into three tabs containing general parameters, the feeds the tool should monitor and the time settings, where the user can specify the timeframes when TrayRSS monitors the feeds. As a new functionallity the user can disable the timeframes with a single click now, before he had to specify a timeframe from 0000 to 2359.

Take a look at the example pictures in the screenshot section. There you can find screenshots of the old configuration window too. A great change isn’t it?

Inside TrayRSS there where a lot of changes too. In the build process Apache Ant was replaced with Apache Maven and the project is now splitted to some modules like the notification, the model, the monitor, the gui and so on.

A complete List of changes can be found in the Bug Tracker of TrayRSS

Download TrayRSS 1.1.0

Future prospects in developement will be the completion of the work with the localization to every text in the application. (I’m sorry that the language change doesn’t affect the config window at the moment, this will be changed in 1.2.0). And the next step of the new Look and Feel of TrayRSS will be a redesign of the notifications, to match additional requirements like mark feedentries for later read

Have Fun using TrayRSS!

PS: If you are a Mac User, i would be very glad to get some response on how the application suits to your system, because i don’t have the chance to test it myself right now.

Ähnliche Artikel:

Leeren eines Webformulares

Das leeren eines Webformulars mitsamt einem löschen der Defaultwerte verlangt den Einsatz von Javascript, wie es geht wird in diesem Artikel beschrieben.

Ich denke der Großteil meiner Leser hat bereits das ein oder andere Webformular geschrieben, und wem es ein ebenso großes Mühsal ist wie mir, dem möchte ich hier eine kleine Hilfestellung bieten.

Möchte man dem User die Möglichkeit anbieten alle Daten die er in einem Formular eingegeben hat wieder zu löschen, erreicht man dies über einen zusätzlichen Button (siehe auch http://de.selfhtml.org/html/formulare/formularbuttons.htm):

<input type=”reset” value=”Abbrechen”>

Gleich mal als Beispiel zum selber ausprobieren:

 

Funktioniert auch bestens, solange man dem Besucher der Website nicht noch weiteren Komfort gönnt. Hat man z.B. Pflichtfelder in seinem Formular, und der User hat ein solches nicht ausgefüllt, gehört es eigentlich schon zum guten Ton, dass man dem User das Formular nochmal zum ergänzen anbietet, vorbefüllt mit den vorher von ihm angegebenen Daten. Möchte der User nun all seine Daten aus dem Formular löschen um nochmal von vorne anzufangen funktioniert ein Klick auf den Formular Button nicht mehr. Auch hier ein Beispiel zum gleich testen:

 

Denn der Klick auf den Button leert die Felder nicht, er setzt sie auf den Ursprungszustand zurück, der vom Server geliefert wurde, und damit auf die mitgelieferte Befüllung. Hier muss man sich anderer Wege behelfen, und wie so oft im Web heißt das Zauberwort JavaScript.

Hier eine entsprechende Lösung:

<a onclick="document.forms['default'].elements['nameOfInputField'].value='';” href="#">zurücksetzen</a>

Über einen damit erzeugten Link lässt sich jedes einzelne Feld per JS löschen indem es im Dom-Baum zum Element manövriert und den Value mit nichts ersetzt. Oder im Falle eines DropDowns mit dem 0 Element.

Das ganze funktioniert natürlich auch wunderbar als Button, der ebenfalls per onClick einen JavaScript Aufruf starten kann.

<input type="button" value="zurücksetzen" onClick="document.forms['third'].elements['input'].value='';"/>

Natürlich darf auch hier ein Beispiel zum direkt ausprobieren nicht fehlen:


zurücksetzen

Und schon kann der User alle Daten resetten und mit dem ihm angebotenen Formular von vorne anfangen.
Viel Spaß beim nachprogrammieren ;)

Ähnliche Artikel:

Java 6 SplashScreen in maven

Was es mit einem SplashScreen in Java 6 auf sich hat und wie man ihn über die Manifest Datei eines Jars mit Maven definiert wird in diesem Artikel erklärt.

Ein gut gemachter Splash Screen ist schon lange in diversen Anwendungen das Mittel zum Zweck gewesen um den Anwender zu zeigen, dass das Programm das er eben gestartet hat lädt und bald zum Einsatz bereit steht. Neu in Java 6 wurde die Möglichkeit einen Splash Screen bei Programmaufruf bereits mitzugeben. Früher musste man dazu ein JFrame oder ein JWindow in Java Swing erzeugen, welches jedoch erst nach Start der VM und dem laden der dafür erforderlichen Klassen erfolgte. Schneller geht das nun mittels der von Java 6 bereitgestellten Möglichkeiten, entweder in der Command Line

java –splash:images/splash.jpg MyMainClass

oder in der Manifest Datei einer Jar

Manifest-Version: 1.0Main-Class: MyMainClassSplashScreen-Image: images/splash.jpg

Dabei wird das Bild von Java in einem einfachen nicht dekorierten Fenster dargestellt, d.h. z.B. ohne X zum schließen. Folgendes Beispiel soll nun zeigen wie selbiges über Maven erreicht wird, wenn man eine Jar erzeugen lässt.

Zuerst legt man eine Grafikdatei die als SplashScreen dienen soll unter den Ressourcen des Programms ab. Als Beispiel könnte folgender Pfad dienen:

ProjektName/src/main/resources/images/splash.jpg

Dann fügt man das maven-jar-plugin in sein POM File ein und konfiguriert dieses so, dass es den SplashScreen anzeigt.

            <plugin>
                <artifactid>maven-jar-plugin</artifactid>
                <version>2.3.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <archive>
                        <manifest>
                            <mainclass>my.packages.MyMainClass</mainclass>
                            <adddefaultimplementationentries>
                                true
                            </adddefaultimplementationentries>
                            <addclasspath>true</addclasspath>
                            <classpathprefix>lib/</classpathprefix>
                        </manifest>
                        <manifestentries>
                            <version>
                                ${project.version}
                            </version>
                            <implementation-version>
                                ${project.version}-${buildNumber}
                            </implementation-version>
                            <splashscreen-image>imgages/splash.jpg</splashscreen-image>
                        </manifestentries>
                    </archive>
                </configuration>
            </plugin>

In die <manifestentries> kann man den Eintrag <splashscreen-image> schreiben, der den selben Inhalt hat wie man es in der Manifest Datei der Jar Datei schreiben würde. Der gesamte Pfad wo wir die Datei abgelegt haben (also das ProjektName/src/main/ressources/… ) ist dabei nicht erforderlich da sich hierbei auf den Inhalt der zukünftig generierten Jar Datei bezogen wird.

Bis zum nächsten mal, mit mehr zum Thema SplashScreen.

Ähnliche Artikel:

HOWTO: GUI mit Swing – Teil 5: Concurrency in Swing

Wie entwickelt man eigentlich eine GUI mit Java Swing? Eine mehrteilige Einführung in dieses Thema. Teil 5 beschäftigt sich mit Nebenläufigen prozessen in Swing

Zur Erinnerung die bereits besprochenen und noch geplanten Themen hier noch eine Auflistung selbiger:

      Nachdem wir nun erfolgreich eine GUI gebaut haben, die auf unsere ersten Klicks reagiert wollen wir uns nun mit der Nebenläufigkeit in Swing Anwendungen beschäftigen.

      Aufgabe aus Teil 4

      Aufgabe überspringen

      Aus Teil 4 war noch ein ActionListener für den Menüpunkt beenden zu realisieren.

      Action Listener

      Wir erstellen analog zum EditActionListener eine neue Klasse MenuActionListener. In dieser prüfen wir ob das Event dass der Listener enthält das Beenden Event ist, schließen erst das JFrame und dann die ganze Anwendung.

      package at.nullpointer.guiprototype.listener;
      
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      
      import at.nullpointer.guiprototype.Prototype;
      
      public class MenuActionListener implements ActionListener {
      
      	public void actionPerformed(ActionEvent e) {
      		if(e.getActionCommand().equals("Beenden")){
      			Prototype.getJFrame().dispose();
      			System.exit(0);
      		}
      	}
      }

      Den ActionListener müssen wir nun nur noch dem MenuItem zuweisen. Dies geschieht analog zu der Zuweisung beim JButton. Wir editieren dazu die Klasse PrototypeMenuBar

      		close.addActionListener(new MenuActionListener());

      Damit können wir nun das Programm über den Menüpunkt beenden. Auch das Tastenkürzel ALT+B führt zum Programmende.

      NebenLäufigkeit in Swing

      Die erste Form von Nebenläufigkeit in Swing haben wir bereits in den vorherigen Teilen dieser Serie kennengelernt. Der Event-Dispatcher Thread wurde bereits genutzt um die GUI zu erstellen und anzuzeigen

              //Schedule a job for the event-dispatching thread:
              //creating and showing this application's GUI.
              javax.swing.SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                      createAndShowGUI();
                  }
              });

      Dabei wird im Initial-Thread, der die main Methode ausführt, oben benannter Code ausgeführt. Man übergibt dem Event-Dispatcher Thread ein Runnable Objekt, dass dieser ausführt sobald er soweit ist. Bei invokeLater arbeitet der Initialthread nach der Übergabe gleich weiter und würde nachfolgenden Code behandeln.

      Für den Fall, dass der nachfolgende Code erst ausgeführt werden darf, wenn die GUI erzeugt wurde gibt es noch die invokeAndWait Methode, die das Runnable Objekt ebenfalls übergibt, aber auf dessen Beendung wartet.

      Führt man seine GUI nicht im Event-Dispatcher Thread aus funktioniert sie meist auch, es kann aber zu Speicherverletzungen und somit Fehlverhalten kommen, welche nur schwer zu finden bzw. korrigieren ist. Von diesem Event-Dispatcher Thread ist jedoch die gesamte Swing Oberfläche abhängig, da die meisten Komponenten nicht Thread Safe implementiert sind. Deshalb sollten darauf nur kurze Tasks, wie das feuern von Events, oder z.B. minimale Textkorrekturen ausgeführt werden (zB durch zusätzliche invokeLater Aufrufe) um ein Einfrieren der Applikation zu vermeiden. Ein Umstand dem wir in den bisherigen Teilen dieses Tutorials kaum Rechnung getragen haben.

      Für rechenintensivere Aufgaben, oder Tasks die zB Netzwerkkommunikation erfordern ist es daher notwendig auf eine andere Abwicklung zurückzugreifen. Sogenannte Worker-Threads werden für die Umsetzung dessen verwendet. Man muss dazu mit seinem Objekt die abstrakte Klasse SwingWorker implementieren, welche einige Features zur Kommunikation mit dem Event-Dispatcher Thread beinhaltet.

      Akuell weist unser Prototyp folgendes Verhalten auf: Wenn wir in unserem Prototypen auf der EditView auf OK klicken übermittelt unser Programm die Daten an die Enterprise Software im Hintergrund. Ist diese mit dem Bearbeiten fertig, übersendet sie uns ein OK, welches wir bestätigen müssen. Erst dann schaltet unser Prototyp in den Anzeigemodus. Verzögert sich nun das Absenden der Bestätigung friert unser Programm ein. Dies kann man leicht nachstellen indem man die Mock-Klasse MockCompanySoftware um z.B. eine fette Schleife erweitert.

      	public String setKundendaten(Kundendaten kdata) {
      		for (int x = 0; x < 100000; x++)
      			for (int y = 0; y < 100000; y++){
      				System.currentTimeMillis();
      			}
      	    return "Daten gesandt";
      	}

      Wir müssen nun merklich warten bis unser Programm weiter verwendbar ist. Minimieren und verschieben funktioniert immerhin. Doch der Button bleibt gedrückt, die Ansicht ebenfalls auf der EditView. Um dem zu begegnen müssen wir die Prototype#sendData Methode ändern. Dazu erzeugen wir einen SwingWorker, der das Senden der Daten für uns übernimmt.

      	public static void sendData() {
      		SwingWorker worker = new SwingWorker<Void , Void>() {
      
      			private String answer;
      
      			// Die eigentliche Aufgabe wird bearbeitet
      			@Override
      			protected Void doInBackground() throws Exception {
      				MockCompanySoftware mcs = new MockCompanySoftware();
      				answer = mcs.setKundendaten(null);
      				return null;
      			}
      
      			/* Wenn die Aufgabe fertig ist wird unsere JOptionPane angezeigt
      			   Dazu wird diese Methode aufgerufen wenn der Event-Dispatcher-Thread
      			   bemerkt, dass der HintergrundThread abgearbeitet ist.
      			 */
      			@Override
      			public void done() {
      				JOptionPane.showMessageDialog(null, answer);
      			}
      		};
      
      		//Der Worker wird ausgeführt
      		worker.execute();
      
      	}

      Hier sehen wir den Aufbau des SwingWorker. Er beinhaltet eine doInBackground Methode, die in einem Background-Thread ausgeführt wird. Sobald dieser Fertig ist wird vom Event-Dispatcher-Thread die done Methode aufgerufen. Mit der execute Methode startet man den Background-Thread. Nach erfolgreiches Event könnte von dem Ergebnis mittels get Methode gebrauch machen.

      Probiert den Prototypen nun nochmal aus, der Button wird nun freigegeben.

      Damit haben wir unsere Applikation nebenläufig gemacht und ich beschließe diese Tutorial-Reihe mit den Worten:

      Wenn ihr euer Wissen um Swing erweitern und effektiv einsetzen wollt, setzt euch am besten gleich hin und programmiert, schaut euch fremden Code z.B. auf Open Sourceplattformen an und programmiert dann weiter. Vielleicht baut ihr ja sogar das Beispiel hier aus. Weitere Anregungen oder Fragen dazu sind natürlich gern gesehen.

      Zum Weiterlesen ein paar Buchtipps, sowie Weblinks. Swing wird neben den online Tutorials und spezialisierten Büchern ebenfalls in div. Standardlehrbüchern zu Java behandelt.

      Trail: Creating a GUI With JFC/Swing – von Oracle: http://download.oracle.com/javase/tutorial/uiswing/index.html

      The JFC Swing Tutorial – Addison-Wesley Verlag 2004 Verlag – ISBN 0201914670, 9780201914672

      http://books.google.at/books?id=3rWTX-vjUhEC

      Für Fortgeschrittene: The definitive guide to Java Swing – Apress Verlag 2005 – ISBN 1590594479, 9781590594476

      http://books.google.at/books?id=YPjZNlEgAMcC

      Ähnliche Artikel:

      HOWTO: GUI mit Swing – Teil 4: Interaktion mit der GUI

      Wie entwickelt man eigentlich eine GUI mit Java Swing? Eine mehrteilige Einführung in dieses Thema. Teil 4 versieht den GUI Prototypen mit erster Funktionalität.

      Zur Erinnerung die bereits besprochenen und noch geplanten Themen hier noch eine Auflistung selbiger:

          Aufgabe aus Teil 3

          Aufgabe überspringen

          Aufgabe aus Teil 3 war es, nachdem wir die Anzeige Maske fertiggestellt hatten, auch die Edit Maske zu konstruieren.

          EditJPanel

          Damit wir wahlweise die Daten anzeigen, oder bearbeiten können, habe ich in meiner Lösung folgenden Weg eingeschlagen: Das ShowDataJPanel wurde umgebaut zum DataJPanel, welches im Konstruktor nun einen Boolean Parameter entgegennimmt, durch den entschieden wird ob die Daten mittels Label oder Textfield angezeigt werden. Anhand dieses Booleans wird auch entschieden ob die statistsichen Daten angezeigt werden oder der Absende Button.

          public DataJPanel(boolean useTextfields) { //...

          Unsere Maske wird nun immer noch gleich aufgebaut wie vorher, allerdings instanziert sie nicht von Haus aus ein ShowDataJLabel, sondern überlässt einer Factory Klasse die Entscheidung ob es entweder das JLabel oder aber ein EditDataJTextField erzeugt indem es das useTextfields Boolean daran durchschleust.

          JComponent kdnrContent = ShowOrEditJComponentFactory.getJComponent(
          				"0123456", useTextfields);

          Dabei wird das Wissen um den Aufbau des erhaltenen Objekts bewusst klein gehalten, um nicht zu hohe Abhängigkeiten zu erhalten. Das JComponent wird durch folgende Factory erzeugt:

          package at.nullpointer.guiprototype.showdata;
          
          import java.awt.Color;
          import java.awt.Dimension;
          import java.awt.Font;
          
          import javax.swing.JComponent;
          
          public class ShowOrEditJComponentFactory {
          
          	private static final Font font = new Font("Dialog", Font.PLAIN, 18);
          	private static final Dimension textFieldSize = new Dimension(480, 30);
          
          	private static JComponent createJLabel(String caption) {
          		return new ShowDataJLabel(caption);
          	}
          
          	private static JComponent createJTextField(String caption) {
          		return new EditDataJTextField(caption);
          	}
          
          	public static JComponent getJComponent(String caption, boolean isTextField) {
          		JComponent erg = null;
          		if (isTextField) {
          			erg = createJTextField(caption);
          			erg.setMaximumSize(textFieldSize);
          			erg.setMinimumSize(textFieldSize);
          			erg.setPreferredSize(textFieldSize);
          		} else {
          			erg = createJLabel(caption);
          		}
          
          		// Schriftfarbe
          		erg.setForeground(Color.BLACK);
          		// undurchsichtig (notwendig um einen Hintergrund zu zeichnen)
          		erg.setOpaque(true);
          		// Veränderung der Schrift
          		erg.setFont(font);
          
          		return erg;
          	}
          }

          Die beiden Klassen ShowDataJLabel und EditDataJTextField, die erst von der Factory erzeugt werden und dann anhand des allgemeinen Verhaltens der JComponent etwas an unsere Optik angepasst werden sind selbst relativ simpel gehalten:

          package at.nullpointer.guiprototype.showdata;
          
          import javax.swing.JTextField;
          
          public class EditDataJTextField extends JTextField {
          
          	public EditDataJTextField(String caption) {
          		this();
          		this.setText(caption);
          	}
          
          	public EditDataJTextField() {
          		super();
          	}
          }
          package at.nullpointer.guiprototype.showdata;
          
          import javax.swing.JLabel;
          
          public class ShowDataJLabel extends JLabel {
          
          	public ShowDataJLabel() {
          
          		super();
          	}
          
          	public ShowDataJLabel(String caption) {
          		this();
          		this.setText(caption);
          	}
          }
          Der Button

          Natürlich darf in der DataJPanel der Button zum Absenden nicht fehlen, der jedoch nur angezeigt werden soll, wenn Textfelder genutzt werden.

          if (useTextfields) {
          
          			// Zuletzt aktiv
          			JPanel lastPanel = new JPanel();
          			lastPanel.setLayout(new BoxLayout(lastPanel, BoxLayout.LINE_AXIS));
          			JButton btnOk = new JButton("OK");
          			JButton btnCancel = new JButton("Abbrechen");
          			lastPanel.add(Box.createHorizontalGlue());
          			lastPanel.add(btnOk);
          			lastPanel.add(Box.createRigidArea(rowSmall));
          			lastPanel.add(btnCancel);
          			this.add(lastPanel);
          			this.add(Box.createRigidArea(lineSmall));
          
          		} else {
          Aufruf der Sichten

          Jetzt muss nur noch der Aufruf der Sichten angepasst werden, der analog zum Aufruf der Daten Ansicht erfolgt. Bei Beiden gilt es jedoch nun ein Boolean zu übergeben, damit die Factory entscheiden kann, was angezeigt werden soll. Unsere fertige Eingabemaske sieht nun wie folgt aus:

          Edit Sicht

          Die vollständigen Sourcen dazu findet ihr wie immer am Schluss dieses Artikels, gemeinsam mit der nächsten Aufgabe.

          Ein Button erwacht zum Leben

          Um aufzuzeigen wie man einen Button zum Leben erweckt erzeugen wir uns als erstes eine sehr simple GUI:

          package at.nullpointer.learningswing.demojframe;
          
          import javax.swing.JButton;
          import javax.swing.JFrame;
          
          public class InputDemo {
          	int count = 0;
          	String text = " mal geklickt";
          	JButton btn = null;
          
          	public static void main(String[] args){
          		InputDemo gui = new InputDemo();
          		gui.draw();
          	}	
          
          	public void draw(){
          		JFrame frame = new JFrame();
          		btn = new JButton(count+text);
          		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          		frame.getContentPane().add(btn);
          		frame.pack();
          		frame.setVisible(true);
          	}
          }

          JButton Event Demo Wenn wir diese ausführen bekommen wir folgendes einfach nur einen Button angezeigt, bei dessen Betätigung nichts passiert. Das wollen wir nun ändern. Dafür brauchen wir 2 Dinge, etwas das passieren soll, und einen Weg wie wir rausfinden ob der Button geklickt wurde.

          Unschwer an der Beschriftung des Buttons zu erraten, wollen wir, dass jedes mal wenn er betätigt wird, sich seine Beschriftung ändert und die Anzahl der Klicks korrekt dargestellt wird. Dazu erweitern wir unser Demo um folgende Methode:

          	private void increaseCount(){
          		count++;
          		btn.setText(count+text);
          	}

          Testen lässt sie sich ganz einfach indem wir den Aufruf der Methode am Ende der Main Methode hinzufügen.

          Um nun auf die User Aktion reagieren zu können setzt Java ein Modell ein, das sich Event Handling nennt. Klickt ein User auf den Button wird ein Event (repräsentiert durch ein Event Objekt) abgefeuert. Diese Funktionalität bietet der JButton, ohne dass wir sie selbst implementieren müssten. Jedoch fehlt uns noch ein Weg dieses Event auszulesen. Es gibt verschiedenste Events (nachzusehen im java.awt.event Package) und unser JButton wirft eines vom SubTyp ActionEvent. Jedes dieser Eventtypen kann durch einen eigenen Listener ausgelesen werden. Für unser ActionEvent ist also ein ActionListener notwendig. Dies ist ein Interface, welches wir allerdings schon selbst implementieren müssen. Wir erweitern also unser InputDemo und lassen es das Interface implementieren

          public class InputDemo implements ActionListener {

          Damit wir das Interface vollständig umsetzen, müssen wir auch noch die von ihm geforderte Methode erzeugen. In diesem Fall ist das die actionPerformed Methode, in welcher wir unsere increaseCount methode aufrufen

          	public void actionPerformed(ActionEvent e) {
          		increaseCount();
          	}

          Starten wir nun das Programm sehen wir, dass das existieren eines Listeners alleine noch keine Auswirkungen hat, dem Button muss erst gesagt werden, dass da ein ActionListener auf seine Events wartet. Dazu stellt der JButton wieder eine entsprechende Methode zur Verfügung, welche wir bei der Erzeugung des JButtons aufrufen.

          		btn.addActionListener(this);

          image Und siehe da, unser Count beginnt nun beim Betätigen des Buttons zu steigen und zu steigen!

          ActionListener im Prototypen

          Der Cancel Button

          Unser neu erworbenes Wissen wollen wir jetzt natürlich im Prototypen anwenden. Wir wollen den Abbrechen Button mit Funktionalität belegen, dazu erzeugen wir uns zuerst im Prototypen entsprechende Methoden, die dazu führen dass statt der Editansicht die Showansicht angezeigt wird.

          Eine Methode die die Ansichten zeichnet haben wir ja bereits geschrieben: fillFrameWithDataContent

          Also benötigen wir nur noch eine Methode die das Frame von seinem alten Inhalt befreit:

          	public static JFrame removeJPanel(JFrame frame){
          		Component[] components = frame.getContentPane().getComponents();
          		for(Component component : components){
          			if (component instanceof JPanel){
          				frame.remove(component);
          			}
          		}
          		return frame;
          	}

          Danach erzeugen wir eine eigene Klasse, die wir EditActionListener taufen. Diese wird auf den Klick mit der Maus reagieren. Dabei arbeiten wir der Einfachheit halber in diesem Beispiel mit den static Methoden der Prototype Class. Ein Vorgehen welches ich ansonsten nicht befürworten würde.

          package at.nullpointer.guiprototype.listener;
          
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;
          
          import at.nullpointer.guiprototype.Prototype;
          
          public class EditActionListener implements ActionListener {
          
          	public void actionPerformed(ActionEvent e) {
          		Prototype.removeJPanel(Prototype.getJFrame());
          		Prototype.fillFrameWithDataContent(Prototype.getJFrame(), false).setVisible(true);
          	}
          }

          Zuerst wird unsere neue Methode aufgerufen, dannach befüllen wir das JFrame wieder. Achtung, das JFrame wird dann mittels Aufruf der setVisible Methode erneut für den Benutzer dargestellt, um die Änderungen sichtbar zu machen.

          Nun noch in der Klasse DataJPanel den EditActionListener dem Cancelbutton hinzugefügt und schon reagiert unser Prototyp richtig bei einem Klick auf den Abbrechen Button!

          Der OK Button

          Wie ihr vielleicht an der Benennung des EditActionListener erkannt habt, soll dieser nicht nur für den Cancel Button zuständig sein, sondern auch für den OK Button. Wir lassen ihn daher auch auf Events des OKButtons anhand der addActionListener Methode lauschen.

          Klicken wir nun auf den OK Button sehen wir unser ActionListener nicht zwischen den zwei Buttons unterscheiden kann. Der Klick führt zum selben Ergebnis wie ein Klick auf den Cancel Button. Damit der ActionListener differenzieren kann, nutzen wir die Informationen aus, die das Event, welches der actionPerformed Methode mitgegeben wurden, enthält. Folgende Methoden stehen dabei zur Verfügung:

          getActionCommand() liefert den CommandString der der Action entspricht
          getModifiers() liefert ein int, welches die Kontrolltasten die dabei gedrückt wurden repräsentiert
          getSource() liefert das Objekt auf dem das Event durchgeführt wurde
          getWhen() liefert den Zeitpunkt des Events zurück

          Wir verwenden die getActionCommand() Methode um unser Button Objekt zu identifizieren. Dieses liefert uns den ID-String zurück, den wir bei der Buttonerzeugung angegeben haben, also hierbei “OK”. Nur im falle eines Clicks auf OK führen wir zusätzlich das Absenden der Daten aus.

          	public void actionPerformed(ActionEvent e) {
          		if(e.getActionCommand().equals("OK")){
          			Prototype.sendData();
          		}
          		Prototype.removeJPanel(Prototype.getJFrame());
          		Prototype.fillFrameWithDataContent(Prototype.getJFrame(), false).setVisible(true);
          	}

          Die Methode sendData() würde nun auf den Firmenserver zurückgreifen und Daten an die Datenbank senden. Da dies den Rahmen des Tutorials sprengen würde wollen wir hier nur die Stringbestätigung ausgeben, die unsere Mocksoftware für die Gesendeten Daten retourniert.

          	public static void sendData() {
          		MockCompanySoftware mcs = new MockCompanySoftware();
          		JOptionPane.showMessageDialog(null, mcs.setKundendaten(null));
          	}

          Auch der OK Button wurde nun mit Funktionalität ausgestattet.

          Vorschau und Aufgabenstellung

          Nun da die beiden Buttons reagieren fehlt uns noch das Menü. Hierfür ist ebenfalls ein ActionListener zu implementieren. Hier noch die Ausgangs-Sourcen für diese Aufgabenstellung.

          Viel Erfolg dabei!

          Im nächsten und abschließenden Teil dieser kleinen Serie möchte ich noch kurz die Möglichkeiten für Nebenläufigkeit in Java Swing aufzeigen.

          Ähnliche Artikel: