|
Warning: array_merge() [function.array-merge]: Argument #1 is not an array in /home/www/web165/html/silverstrike/lib/plugins/meta/syntax.php on line 91 Inhaltsverzeichnis
Wie Sie mit SwiXML Zeit bei der Entwicklung von Java-GUIs sparen könnenIn diesem Artikel werden Sie erfahren, wie Sie
können. Das ProblemStellen Sie sich vor, Sie wollen eine Dialogbox erstellen, die folgendermassen aussieht: Wie sieht der Java-Source-Code aus, den man benötigt, um eine solche Dialogbox anzuzeigen? Eine mögliche Lösung ist folgende: /** * Copyright (c) Dmitri Pissarenko * http://sw-dev.at */ package at.swDev.swixml; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.WindowConstants; import javax.swing.border.TitledBorder; /** * This class is used for demonstrating how a simple form can be programmed in * Java. * * @author Dmitri Pissarenko */ public class SampleFormJava extends JFrame { /** * Grid width of button panel (OK, Cancel). Necessary for laying out with * GridBagLayout. */ private static final int OK_CANCEL_BUTTON_PANEL_GRIDWIDTH = 2; /** * Y coordinate of button panel (OK, Cancel). Necessary for laying out with * GridBagLayout. */ private static final int OK_CANCEL_BUTTON_PANEL_GRID_Y = 6; /** * X coordinate of button panel (OK, Cancel). Necessary for laying out with * GridBagLayout. */ private static final int OK_CANCEL_BUTTON_PANEL_GRID_X = 0; /** * Grid width of "subscribe to course" checkbox. Necessary for laying out * with GridBagLayout. */ private static final int SUBSCRIBE_CHECKBOX_GRIDWIDTH = 2; /** * Y coordinate of "subscribe to course" checkbox. Necessary for laying out * with GridBagLayout. */ private static final int SUBSCRIBE_CHECKBOX_GRID_Y = 5; /** * X coordinate of "subscribe to course" checkbox. Necessary for laying out * with GridBagLayout. */ private static final int SUBSCRIBE_CHECKBOX_GRID_X = 0; /** * Y coordinate of "e-mail" text field. Necessary for laying out * with GridBagLayout. */ private static final int EMAIL_TEXT_FIELD_GRID_Y = 4; /** * X coordinate of "e-mail" text field. Necessary for laying out * with GridBagLayout. */ private static final int EMAIL_TEXT_FIELD_GRID_X = 1; /** * Y coordinate of "e-mail" label. Necessary for laying out * with GridBagLayout. */ private static final int EMAIL_LABEL_GRID_Y = 4; /** * X coordinate of "e-mail" label. Necessary for laying out * with GridBagLayout. */ private static final int EMAIL_LABEL_GRID_X = 0; /** * Y coordinate of "country" combo box. Necessary for laying out * with GridBagLayout. */ private static final int COUNTRY_COMBO_GRID_Y = 3; /** * X coordinate of "country" combo box. Necessary for laying out * with GridBagLayout. */ private static final int COUNTRY_COMBO_GRID_X = 1; /** * Y coordinate of "country" label. Necessary for laying out * with GridBagLayout. */ private static final int COUNTRY_LABEL_GRID_Y = 3; /** * X coordinate of "country" label. Necessary for laying out * with GridBagLayout. */ private static final int COUNTRY_LABEL_GRID_X = 0; /** * This constant is used for initializing column count in text fields. */ private static final int FIFTY_CHARACTERS = 50; /** * This constant is used for initializing column count in text fields. */ private static final int FORTY_CHARACTERS = 40; /** * This constant represents insets object with a distance of 5 pixels on * each side. */ private static final Insets FIVE_PIXEL_INSETS = new Insets(5, 5, 5, 5); /** * Default serial version ID. */ private static final long serialVersionUID = 1L; /** * Layout manager used in the form. */ private GridBagLayout layout; /** * Text field for entering first name. */ private JTextField firstNameTextField; /** * Text field for entering surname. */ private JTextField surNameTextField; /** * Radio button "male" for selecting gender. */ private JRadioButton maleRadioButton; /** * Radio button "female" for selecting gender. */ private JRadioButton femaleRadioButton; /** * Combo box for selecting country. */ private JComboBox countryComboBox; /** * Text field for entering e-mail. */ private JTextField emailTextField; /** * Check box "subscribe to course". */ private JCheckBox subscribeCheckBox; /** * Constructor. Creates the form, fills "country" combo box with values and * packs the frame. */ public SampleFormJava() { super(); // Create user interface elements this.setupUI(); // Fill "country" combo box with values this.fillComboBox(); this.pack(); } /** * This method creates all the user interface elements of the form. */ protected final void setupUI() { GridBagConstraints constraints = null; JLabel firstNameLabel = null; JLabel surNameLabel = null; JLabel countryLabel = null; JLabel emailLabel = null; JButton okButton = null; JButton cancelButton = null; JPanel genderPanel = null; JPanel buttonPanel = null; ButtonGroup genderButtonGroup = null; layout = new GridBagLayout(); this.setLayout(layout); firstNameLabel = new JLabel("First name:"); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 0; constraints.gridy = 0; constraints.insets = FIVE_PIXEL_INSETS; this.add(firstNameLabel, constraints); firstNameTextField = new JTextField(); firstNameTextField.setColumns(FORTY_CHARACTERS); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 1; constraints.gridy = 0; constraints.insets = FIVE_PIXEL_INSETS; this.add(firstNameTextField, constraints); surNameLabel = new JLabel("Surname:"); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 0; constraints.gridy = 1; constraints.insets = FIVE_PIXEL_INSETS; this.add(surNameLabel, constraints); surNameTextField = new JTextField(); surNameTextField.setColumns(FIFTY_CHARACTERS); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 1; constraints.gridy = 1; constraints.insets = FIVE_PIXEL_INSETS; this.add(surNameTextField, constraints); genderButtonGroup = new ButtonGroup(); maleRadioButton = new JRadioButton("Male"); femaleRadioButton = new JRadioButton("Female"); genderButtonGroup.add(maleRadioButton); genderButtonGroup.add(femaleRadioButton); genderPanel = new JPanel(); genderPanel.setBorder(new TitledBorder("Gender")); genderPanel.add(maleRadioButton); genderPanel.add(femaleRadioButton); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = 0; constraints.gridy = 2; constraints.gridwidth = 2; constraints.insets = FIVE_PIXEL_INSETS; this.add(genderPanel, constraints); countryLabel = new JLabel("Country"); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = COUNTRY_LABEL_GRID_X; constraints.gridy = COUNTRY_LABEL_GRID_Y; constraints.insets = FIVE_PIXEL_INSETS; this.add(countryLabel, constraints); countryComboBox = new JComboBox(); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = COUNTRY_COMBO_GRID_X; constraints.gridy = COUNTRY_COMBO_GRID_Y; constraints.insets = FIVE_PIXEL_INSETS; this.add(countryComboBox, constraints); emailLabel = new JLabel("E-Mail:"); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = EMAIL_LABEL_GRID_X; constraints.gridy = EMAIL_LABEL_GRID_Y; constraints.insets = FIVE_PIXEL_INSETS; this.add(emailLabel, constraints); emailTextField = new JTextField(); emailTextField.setColumns(FIFTY_CHARACTERS); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = EMAIL_TEXT_FIELD_GRID_X; constraints.gridy = EMAIL_TEXT_FIELD_GRID_Y; constraints.insets = FIVE_PIXEL_INSETS; this.add(emailTextField, constraints); subscribeCheckBox = new JCheckBox("Subscribe to course"); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.WEST; constraints.gridx = SUBSCRIBE_CHECKBOX_GRID_X; constraints.gridy = SUBSCRIBE_CHECKBOX_GRID_Y; constraints.gridwidth = SUBSCRIBE_CHECKBOX_GRIDWIDTH; constraints.insets = FIVE_PIXEL_INSETS; this.add(subscribeCheckBox, constraints); buttonPanel = new JPanel(); okButton = new JButton("OK"); cancelButton = new JButton("Cancel"); buttonPanel.add(okButton); buttonPanel.add(cancelButton); constraints = new GridBagConstraints(); constraints.anchor = GridBagConstraints.CENTER; constraints.gridx = OK_CANCEL_BUTTON_PANEL_GRID_X; constraints.gridy = OK_CANCEL_BUTTON_PANEL_GRID_Y; constraints.gridwidth = OK_CANCEL_BUTTON_PANEL_GRIDWIDTH; constraints.insets = FIVE_PIXEL_INSETS; this.add(buttonPanel, constraints); this.setTitle("\"Efficient Java UI development with " + "SwiXML\" by Dmitri Pissarenko"); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.setResizable(false); } /** * This method fills the combobox "Country" with values. */ protected final void fillComboBox() { this.countryComboBox.addItem("Russia"); this.countryComboBox.addItem("Austria"); this.countryComboBox.addItem("Germany"); this.countryComboBox.addItem("Belarus"); this.countryComboBox.addItem("Ukraine"); this.countryComboBox.addItem("Other"); } /** * This main method displays a sample form with user interface elements like * textfield, radio box, combo box, check box and push buttons. * * @param args The arguments are not used in the program. */ public static void main(final String[] args) { SampleFormJava form = null; form = new SampleFormJava(); form.setVisible(true); } } Diese Methode hat jedoch mehrere Nachteile. Zum einen die Code-Grösse - um ein kleines Formular zu erzeugen, werden 5 Seiten an Source-Code benötigt (hier finden Sie die PDF-Darstellung des Codes, um die Seiten zählen zu können). Zum anderen, ist der Code unübersichtlich. Stellen Sie sich vor, Sie schreiben dieses Programm jetzt und vergessen darüber für 5 Jahre. Dann, nach 5 Jahren müssen Sie das Formular ändern. Wieviel Zeit werden Sie benötigen, um herauszufinden, welche Änderungen Sie vornehmen müssen? Wenn Sie irgendwo in diesen 5 Seiten einen Fehler machen, wieviel Zeit werden Sie benötigen, um den Fehler zu finden (besonders wenn Sie in Eile sind) ? Im nächsten Abschnitt werden Sie sehen, wie dieses Problem gelöst werden kann. Die LösungWie können wir das Problem lösen? Zuerst unterteilen wir den gesamten Code in zwei Teile 1. Definition der GUI und 2. alle anderen Aufgaben. Teil 1 besteht in unserem Fall aus der Methode SampleFormJava.setupUI(). Sie macht den größten Teil des Programms aus. Wir refakturieren den Code, sodass diese Methode so aussieht: /** * This method creates a JFrame from the XML UI descriptor. */ protected final void setupUI() { try { (new SwingEngine(this)).render(this.getClass().getClassLoader() .getResource(UI_DEF_FILE_NAME)); } catch (Exception exception) { LOGGER.log(Level.SEVERE, "An error occured when " + "setting up the user interface.", exception); } } Diese Methode tut Folgendes:
Ab jetzt kann die erzeugte JFrame auf die gleiche Art und Weise benutzt werden, als wäre sie „normal“ programmiert worden. Sehen wir uns jetzt den XML-GUI-Deskriptor an: <?xml version="1.0" encoding="UTF-8"?> <frame id="frame" title=""Efficient Java UI development with SwiXML" by Dmitri Pissarenko" layout="GridBagLayout" resizable="true" defaultCloseOperation="WindowConstants.EXIT_ON_CLOSE"> <label id="firstNameLabel" text="First name:"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="0" anchor="GridBagConstraints.WEST"/> </label> <textfield id="firstNameTextField" columns="40"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="0" anchor="GridBagConstraints.WEST"/> </textfield> <label id="surNameLabel" text="Surname:"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="1" anchor="GridBagConstraints.WEST"/> </label> <textfield id="surNameTextField" columns="50"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="1" anchor="GridBagConstraints.WEST"/> </textfield> <panel id="genderPanel" border="TitledBorder(Gender)"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="2" gridwidth="2" anchor="GridBagConstraints.WEST"/> <buttongroup id="genderButtonGroup"> <radiobutton id="maleRadioButton" text="Male"/> <radiobutton id="femaleRadioButton" text="Female"/> </buttongroup> </panel> <label id="countryLabel" text="Country:"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="3" anchor="GridBagConstraints.WEST"/> </label> <combobox id="countryComboBox"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="3" anchor="GridBagConstraints.WEST"/> </combobox> <label id="emailLabel" text="E-Mail:"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="4" anchor="GridBagConstraints.WEST"/> </label> <textfield id="emailTextField" columns="50"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="4" anchor="GridBagConstraints.WEST"/> </textfield> <checkbox id="subscribeCheckBox" text="Subscribe to course"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="5" gridwidth="2" anchor="GridBagConstraints.WEST"/> </checkbox> <panel layout="GridBagLayout"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="6" gridwidth="2" anchor="GridBagConstraints.CENTER"/> <button id="okButton" action="okButtonAction" text="OK"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="0" anchor="GridBagConstraints.WEST"/> </button> <button id="cancelButton" action="cancelButtonAction" text="Cancel"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="0" anchor="GridBagConstraints.WEST"/> </button> </panel> </frame> Jetzt haben wir das ursprüngliche Programm in zwei Teile zerlegt:
Beide Dateien sind jeweils 2 Seiten lang. Dadurch sparen wir uns ca. 1 Seite. Das ist aber nicht der wichtigste Vorteil dieser Lösung. Wir können jetzt den XML-GUI-Deskriptor mit Copy/Paste wiederverwenden - JPanel mit OK- und Cancel-Schaltflächen werden Sie vermutlich des Öfteren benötigen. Auch das ist aber nicht das Wichtigste. Diese Lösung gibt uns eine Chance, den Code zur Präsentation der Daten (auch View genannt), vom
sauber zu trennen (im Sinne des Entwurfsmusters Model-View-Controller). Welche Vorteile bringt diese Trennung? Nehmen wir an, Sie wollen das Aussehen der Dialogbox ein wenig ändern - ein Textfeld soll kleiner/grösser gemacht werden, Text in einem Label soll verändert werden und Ähnliches. Solche Änderungen betreffen nur die Präsentationsschicht. Wenn die Präsentation in einer separaten XML-Datei gekapselt ist, dann brauchen Sie nur diese XML-Datei zu verändern. Dadurch wissen Sie sofort, wo Sie die Änderungen vornehmen müssen. Wenn Präsentation, Datenhaltung und Programmsteuerung in einer Java-Datei zusammengewürfelt sind (wie im Beispiel am Beginndieses Artikels), dann müssen Sie zuerst die Stelle finden, an der dieGUI erzeugt wird. Das kann mühsam werden, besonders bei komplexen GUIs. Weiters brauchen Sie nur zu wissen, wie die GUI aussieht - nicht aber, wie sie mit Datenhaltung und Programmsteuerung verbunden ist. Wenn es keine Trennung zwischen Präsentation, Datenhaltung undProgrammsteuerung gibt, ist es notwendig zu wissen, wie und wo (an welchen Codestellen) sie miteinander verbunden sind - sonst kann man einen Fehler machen. Last but not least ist die XML-Datei eine Baumstruktur, also etwas Hierarchisches. Wenn man die XML-Datei anschaut, sieht man sofort, dass z. B. maleRadioButton und femaleRadioButton „Kinder“ von genderPanel sind. Der Java-Code für die Erzeugung derselben GUI ist dagegen linear aufgebaut. Ein Statement folgt dem anderen und es gibt keine Chance, durch Anschauen des Codes herauszufinden, wie die GUI in etwa aussieht. SwiXMLDie GUIs werden von SwingEngine generiert. Diese ist Teil des Open Source-Produkts SwiXML von Wolf Paulus. Die Lizenz des SwiXML erlaubt die Verwendung von SwiXML in kommerziellen Anwendungen. Sie können SwiXML also problemlos in Ihre Anwendungen einbauen. Vorschau von XML-GUI-Deskriptoren mit xml-ui-viewerWenn Sie gerade einen XML-GUI-Deskriptor entwickeln und sehen wollen, ob er richtig ist, dann haben Sie zwei Möglichkeiten:
Wie die erste Option funktioniert, wissen Sie bereits. Um den zweiten Weg zu gehen, ist es notwendig, folgende Schritte zu machen:
Es wird ein Fenster erscheinen, das so aussieht, wie im Screenshot am Beginn dieses Artikels. Auf diese Weise können Sie mit wenig Aufwand eine Vorschau Ihrer GUI machen - ohne eine einzige Zeile programmieren zu müssen. Wie Sie auf SwiXML-generierte Steuerelemente aus Ihrem Programm zugreifen könnenUm SwiXML in richtigen Anwendungen einsetzen zu können, müssen wir wissen wie man auf die von SwiXML generierten Steuerelemente zugreifen kann. Nehmen wir an, wir wollen den Text in einem Textfeld auf einen vorgegebenen Wert setzen. Dieser Wert wird zur Laufzeit bestimmt. Um dies machen zu können, müssen wir zwei Dinge tun:
Nehmen wir an, wir wollen den Text des Textfeldes firstName in unserer Beispiel-GUI auf einen bestimmten Wert setzen. Sehen Sie sich zunächst den XML-GUI-Deskriptor an, vor allem jenen Teil, wo firstName-Textfeld definiert wird: <?xml version="1.0" encoding="UTF-8"?> <frame id="frame" title=""Efficient Java UI development with SwiXML" by Dmitri Pissarenko" layout="GridBagLayout" resizable="true" defaultCloseOperation="WindowConstants.EXIT_ON_CLOSE"> ... <textfield id="firstNameTextField" columns="40"> <gridbagconstraints insets="5,5,5,5" gridx="1" gridy="0" anchor="GridBagConstraints.WEST"/> </textfield> ... </frame> Wie Sie sehen, hat das Textfeld die ID firstNameTextField. Um auf dieses Textfeld zugreifen zu können, müssen wir in der Klasse eine Member-Variable mit dem gleichen Namen anlegen: public class SampleFormSwiXML2 { ... private JTextField firstNameTextField; ... } Wenn SwiXML die GUI generiert (das passiert beim Aufruf der Methode SwingEngine.render), „verbindet“ es
Das bedeutet: Wenn Sie im Java-Programm auf ein Steuerelement zugreifen wollen, müssen Sie zwei Dinge tun:
Wenn diese zwei Dinge gemacht sind, können Sie auf das Steuerelement zugreifen nachdem SwingEngine.render aufgerufen wurde. Der Konstruktor sieht in unserem Fall also folgendermassen aus: public SampleFormSwiXML2() { this.setupUI(); this.fillComboBox(); this.initFirstName(); this.frame.pack(); } Die Methode initFirstName ist relativ einfach: private void initFirstName() { this.firstNameTextField.setText("default value, generated at " + (new Date())); } Sobald das gemacht ist, kann das Programm kompiliert werden. Das Ergebnis wird etwa so aussehen, wie im Screenshot unten. Übrigens - den Code dazu finden Sie in dieser Zip-Datei, unter SampleFormSwiXML2. XML-GUI-Deskriptoren aus JAR-Dateien ladenWenn Sie die Methode setupUI ansehen, werden Sie sich möglicherweise fragen, wieso wir hier einen Classloader verwenden. protected final void setupUI() { try { (new SwingEngine(this)).render(this.getClass().getClassLoader() .getResource(UI_DEF_FILE_NAME)); } catch (Exception exception) { System.err.println("An error occured when " + "setting up the user interface."); } } Natürlich könnte man den XML-GUI-Deskriptor wie jede andere Datei laden (ohne Classloader). Dieser Code hat jedoch einen wichtigen Vorteil - er funktioniert auch dann, wenn die Anwendung und der XML-GUI-Deskritptor in einer JAR-Datei verpackt sind. Classloader-TricksSehen wir uns die setupUI-Methode nochmal an: protected final void setupUI() { try { (new SwingEngine(this)).render(this.getClass().getClassLoader() .getResource(UI_DEF_FILE_NAME)); } catch (Exception exception) { System.err.println("An error occured when " + "setting up the user interface."); } } In einigen seltenen Fällen wird diese Methode nicht funktionieren - der XML-GUI-Deskriptor wird für den Classloader nicht sichtbar sein. Das kann passieren, wenn Sie versuchen, SwiXML in einer eclipse RCP-Anwendung zu verwenden. In einer eclipse RCP-Anwendung gibt es allerdings mehrere Classloader - und einige davon sehen den XML-GUI-Deskriptor sehr wohl. Um SwiXML auch innerhalb einer eclipse RCP-Anwendung verwenden zu können, muss man dem Konstruktor einen passenden Classloader übergeben. Wir refakturieren den Code folgendermassen: public SampleFormSwiXML2(ClassLoader cl) { this.setupUI(cl); this.fillComboBox(); this.initFirstName(cl); this.frame.pack(); } protected void setupUI(ClassLoader cl) { try { (new SwingEngine(this)).render(cl.getResource(UI_DEF_FILE_NAME)); } catch (Exception exception) { System.err .println("An error occured when setting up the user interface."); } } Jetzt können Sie die Dialogbox mit folgendem Code anzeigen: public SomeClass { public void showUi() { // UI_DEF_FILE_NAME is visible to the class loader of SomeClass SampleFormSwiXML2 ui = null; ui = new SampleFormSwiXML2(this.getClass().getClassLoader()); ui.getFrame().setVisible(true); } } Wenn der Classloader von SomeClass den XML-GUI-Deskriptor (UI_DEF_FILE_NAME) sieht, wird die Dialogbox korrekt angezeigt werden, auch wenn der Classloader von SampleFormSwiXML2 UI_DEF_FILE_NAME nicht sieht. Event-Handling in SwiXMLUm SwiXML in richtigen Anwendungen einsetzen zu können, müssen wir in der Lage sein, auf Aktionen des Benutzers zu reagieren. Zum Beispiel wollen wir, dass eine Message-Box erscheint, wenn der Benutzer die OK-Schaltfläche betätigt. Sehen wir uns zunächst einmal den XML-GUI-Deskriptor an: <button id="okButton" action="okButtonAction" text="OK"> <gridbagconstraints insets="5,5,5,5" gridx="0" gridy="0" anchor="GridBagConstraints.WEST"/> </button> In der ersten Zeile steht das Tag action. Der Wert dieses Tags ist der Name der Instanzvariable, in der jene Aktion steht, die beim Drücken des Buttons ausgeführt werden soll. Hier heisst die Aktion okButtonAction. Daher muss unsere Klasse SampleFormSwiXML3 eine entsprechende Instanzvariable haben. /** * This is the action, which is invoked whenever the user * presses the OK button. * * We need to make it public, otherwise it doesn't work with SwiXML, sorry. */ public Action okButtonAction = new AbstractAction() { /** * Default serial version ID. */ private static final long serialVersionUID = 1L; public void actionPerformed(final ActionEvent event) { JOptionPane.showMessageDialog(null, "OK button pressed"); } }; Jetzt wird bei jedem Drücken des OK-Buttons eine Message-Box angezeigt. Weitere SchritteAlle Beispiele (inkl. Quellcode), die in diesem Artikel präsentiert wurden, können Sie hier gratis downloaden. Wenn Sie SwiXML in Ihren eigenen Anwendungen einsetzen wollen, empfehle ich Ihnen, einen Blick auf die wahrscheinlich grösste Sammlung von SwiXML-Deskriptoren im deutschsprachigen Raum zu werfen. Dort finden Sie über 30 kostenlose SwiXML-Deskriptoren, die Sie in Ihren Anwendungen verwenden können. Last but not least können Sie für SwiXML-bezogene Fragen auch mit uns Kontakt aufnehmen. NewsletterDiese Website wird laufend aktualisiert und es kommen regelmässig neue Artikel hinzu. Wenn Ihnen dieser Artikel gefallen hat, können wir Sie benachrichtigen (höchstens ein Mal im Monat) sobald neue Informationen veröffentlicht werden. Melden Sie sich dazu bei unserem Newsletter an. |