INE2 Ereignisse, MVC, Swing ■ Merkmale eines ereignisgesteuerten Programms ■ Aufbau eines ereignisgesteuerten Programms ■ Entwicklung eines ereignisgesteuertes Programms in Java ■ Allgemeines zur Benutzerschnittstelle, MVC ■ Unterteilung in Model, View und Controller ■ Graphische Komponenten Ereignisse School of Engineering That's That'sone onesmall smallstep step for for[a] [a]man, man,aagiant giant leap leapfor formankind mankind © G. Burkert, K. Rege, ZHAW 2 von 49 Sequentielle Programme ■ Hauptprogramm steuert den gesamten Programmablauf: in Java schreibt man dafür sog. Applikationen: die main Methode ist dort die Einsprungstelle (später) public class App { static foo() {... } public static void main(String args) { foo(); } } ■ Hauptprogramm ruft Unterprogramm(e) auf. ■ Diese geben am Ende jeweils die Kontrolle wieder an das Hauptprogramm zurück. ■ Verlangt an bestimmten Stellen Benutzereingaben ■ Zeitlicher Ablauf des Programms ist vor dem Start festgelegt ■ User kann nur an den vorbestimmten Stellen auf den Programmablauf Einfluss nehmen, nämlich dort, wo das Programm eine Eingabe verlangt School of Engineering © G. Burkert, K. Rege, ZHAW 3 von 49 Beispiele sequentieller Programme ■ Compiler, Batch-Processing, Scripts, Kommandozeilenbefehle (cd, dir, more), ■ JFrames ohne graphische Benützeroberfläche (Methode paint ist dort Einsprungstelle) ■ Programmablauf wird beim Programmieren festgelegt Æ weniger geeignet für wirklich interaktive Programme School of Engineering © G. Burkert, K. Rege, ZHAW 4 von 49 Ereignisgesteuertes Programm ■ Interaktive Anwendungen werden in Java mit ereignisgesteuerten Programmen (event-driven programs) geschrieben ■ Für die Benutzerschnittstelle wird von Java eine graphische Oberfläche zur Verfügung gestellt Æ GUI Graphical User Interface (AWT, JFC) School of Engineering © G. Burkert, K. Rege, ZHAW 5 von 49 Ereignisgesteuerte Programme ■ Hauptmerkmal: Programmablauf ist nicht fix vorgegeben, sondern wird durch externe Ereignisse (events) gesteuert: ■ ■ ■ ■ Mausklick Menuauswahl Tastendruck Betriebssystem, andere Programme Ereignisschleife (event loop) ■ Das Hauptprogramm besteht aus einer Ereignisschleife ■ Diese wartet auf Ereignisse und läuft bis zum Abbruch des Programms kontinuierlich ■ Der Programmierer schreibt für jedes Ereignis eine entsprechende Methode ■ Beim Eintreffen eines Ereignisses ruft die Ereignisschleife die entsprechende Methode auf, um das eingetroffene Ereignis zu behandeln School of Engineering Ereignis(endlos)schleife Methoden im UserProgramm Taste Taste gedrückt gedrückt ?? Methode1 Methode1 Maus Maus bewegt? bewegt? Methode2 Methode2 Maustaste Maustaste betätigt? betätigt? Methode3 Methode3 ….? ….? Methode4 Methode4 ….? ….? : : © G. Burkert, K. Rege, ZHAW 6 von 49 Ereignisschleife und Events in Java ■ Java Laufzeitsystem implementiert eine Ereignisschleife bereits ■ Der Programmierer muss nur noch die Methoden schreiben, die die Ereignisse behandeln ■ Die Ereignisschleife verarbeitet zusammen mit dem Betriebssystem die Elementarereignisse des Systems ■ ■ Benutzer drückt auf Taste oder klickt mit der Maus Benutzer klickt eine Schaltfläche, eine Menuoption usw. an ■ Die Java GUI Komponenten (z.B. JButton) bereiten diese Elementarereignisse auf ■ Sie nehmen Elementarereignisse, die sie betreffen, entgegen ■ Sie erzeugen daraus Java Ereignisse School of Engineering © G. Burkert, K. Rege, ZHAW 7 von 49 Java Event Model Ereignisquelle (Source Object), z.B. JButton ■ Definiert Ereignisse, die es erzeugen kann ■ Führt eine Liste der Ereignissenken (Listener-Objekte), z.B. JFrame ■ bietet Methoden zum An- und Abmelden von Listener an. z.B. addActionListener ■ Informiert Listener-Objekte, sobald ein Ereignis eingetreten ist: ■ ■ Das Source-Objekt ruft die entsprechende Methode beim Listener-Objekt auf Alle Informationen über das Ereignis (z.B. wer ist der Verursacher) werden dabei in einem Ereignis-Objekt übergeben School of Engineering © G. Burkert, K. Rege, ZHAW 8 von 49 …Java Event Model Listener, z.B. JFrame ■ Registriert sich beim Source-Objekt als Listener ■ Gibt damit an, an welchen Ereignissen es interessiert ist (Bsp. ActionEvent). ■ Stellt je eine Methode zur Behandlung der entsprechenden Ereignisse bereit ■ Interface bestimmt die Behandlungsmethode, z.B.ActionListener SourceObj.addActionListener(ListenerObj) Delegation-Event-Modell ■ Auftretende Ereignisse werden nicht zentral behandelt ■ Behandlung jedes Ereignisses wird vielmehr an ein oder mehrere Objekte delegiert School of Engineering © G. Burkert, K. Rege, ZHAW 9 von 49 Beispiel Interface Interface->->Klasse Klasseenthält enthält Methode addActionListener Methode addActionListener import java.awt.*; import java.awt.event.*; public class DrueckMich extends JFrame implements ActionListener { private JButton tester; private boolean gedrueckt = false; @Override Sich Sichselber selberanmelden anmeldenan anKnopf, Knopf, dass an ActionEvents interessiert dass an ActionEvents interessiert public void initComponents() { tester = new JButton("Hier drücken"); // GUI-Obj. erzeugen getContentPane().add (tester); // zur GUI hinzufügen tester.addActionListener(this); // Listener registrieren } Bearbeitungsmethode Bearbeitungsmethode public void actionPerformed(ActionEvent event) { gedrueckt = true; paint(getGraphics()); } Ereignis Ereignis @Override public void paint(Graphics g) { if(gedrueckt) { g.drawString ("Danke!", 100,50); } } School of Engineering © G. Burkert, K. Rege, ZHAW 10 von 49 Anmeldung: z.B. addActionListener ■ Dem JButton tester wird ein Objekt als Listener für ActionEvents zugeordnet. tester.addActionListener(this); ■ Mit this wird hier das aktuelles Objekt (JFrame) beim JButton tester als Listener registriert; Æ d.h. die Methode für die Ereignisbehandlung (actionPerformed) befindet sich in diesem JFrame !! ■ Man hätte aber auch andere Objekte im Programm mit der Ereignissbehandlung "beauftragen" können. ■ Die Registrierungsmethoden für Listener-Objekte folgen einer einheitlichen Namensgebung. Ein Listener für ein Ereignis XXX hat den Namen SourceObjekt.addXXXListener(Listener-Obj.); School of Engineering © G. Burkert, K. Rege, ZHAW 11 von 49 Bearbeitung bei Ereignis: z.B. actionPerformed ■ Die Methode actionPerformed(ActionEvent e) wird vom JButton tester jedesmal bei allen registrierten Listeners aufgerufen, wenn der JButton gedrückt wird ■ In dieser Methode stehen die Anweisungen, die dieses Ereignis behandeln ■ Wenn die Betätigung des Buttons eine Veränderung der GUI zur Folge hat (im Bsp.: drawString…), dann muss das JFrame muss neu gezeichnet werden, um dem Benutzer die Reaktion des Programms anzuzeigen: z.B. paint(getGraphics()) wird das JFrame neu gezeichnet School of Engineering © G. Burkert, K. Rege, ZHAW 12 von 49 Ereignisklassen: z.B. ActionEvent ■ Es gibt zahlreiche Ereignisse, welche von Komponenten erzeugt werden können und an denen andere Objekte interessiert sind (Komponente = GUI-Objekte) ■ Dieselbe Ereignisklasse wird von mehreren Komponenten verwendet. Z.B. ActionEvent Æ verwendet von JButton, JTextField,... School of Engineering © G. Burkert, K. Rege, ZHAW 13 von 49 Mehrere Buttons ActionEvent Object Mehrere Buttons public void initComponents { JPanel panel = getContentPane(); smaller= new JButton("smaller"); // GUI-Obj. erzeugen panel.add (smaller); // zur GUI addieren smaller.addActionListener(this);// Listener registrieren bigger= new JButton("bigger"); // GUI-Obj. erzeugen panel.add (bigger); // zur GUI addieren bigger.addActionListener(this); // Listener registrieren } ■ Problem: Alle Buttons erzeugen ein Ereignis der gleichen Klasse ActionEvent und es wird die gleiche Methode ActionPerfomed aufgerufen . ■ Wie kann man herausfinden, welcher JButton das Ereignis erzeugt hat? ■ Lösung: Das an die Methode actionPerformed(ActionEvent e) übergebene Ereignis-Objekt e enthält verschiedene Informationen zum Ereignis: z.B. Quelle des Ereignisses School of Engineering © G. Burkert, K. Rege, ZHAW 14 von 49 … mehrere Buttons ActionEvent Object … Mehrere Buttons ■ Mit der Methode e.getSource() kann das Source-Objekt abgefragt werden JButton smaller, larger; public void actionPerformed(ActionEvent event) { if (event.getSource() == smaller){ diameter -= 10; Referenzvergleich Referenzvergleich } if (event.getSource() == larger){ diameter += 10; } paint(getGraphics()); } School of Engineering © G. Burkert, K. Rege, ZHAW 15 von 49 Entwurf von interaktiven Anwendungen Model, View, Controller - MVC School of Engineering © G. Burkert, K. Rege, ZHAW 16 von 49 Direkte Verarbeitung von Events in JFrame ■ Bearbeitung des Ereignisses in JFrame: ■ ■ Einfach ausreichend für einfache Aufgaben addXXListner(this) addXXListner(this) ■ Nachteile: ■ Verarbeitung ans JFrame gebunden -> bei Wechsel auf andere GUI Klassenbibliothek neu programmieren ■ Vermischung von Darstellungslogik und Verarbeitungslogik -> Übersichtlichkeit leidet ■ Nicht möglich gleiches Ereignis durch mehrere GUI Elemente auszulösen School of Engineering © G. Burkert, K. Rege, ZHAW 17 von 49 Trennung GUI und Verarbeitung ■ Wichtiges Entwurfsprinzip: Trennung und Entkopplung von Benutzerschnittstelle und „technischen Innereien“ (Verarbeitung, Modell) ■ Beispiel: Automobil ■ ■ Benutzerschnittstelle: Gaspedal, Kupplungspedal, Ganghebel, Steuerrad, Tachometer, Tourenzähler, Benzinanzeige... Technische Innereien: Motor, Getriebe, Kupplung, Lenkung, ABS, Lichtanlage ■ Vorteile: ■ ■ ■ Einfache und sichere Bedienung und Überwachung durch User Verstecken der Komplexität vor dem User Getrennte und damit einfachere Entwicklung und Wartung der Teilsysteme ■ Man unterscheidet 3 Teile: Model, View und Controller School of Engineering © G. Burkert, K. Rege, ZHAW 18 von 49 MVC: Beispiel Auto Control Control View View Control Control View View Steuerungsinformation Steuerungsinformation Sensorinformation Sensorinformation Model Model 5967 cc 400 hp 15 l/100km School of Engineering © G. Burkert, K. Rege, ZHAW 19 von 49 Aufgabenteilung nach dem MVC Paradigma ■ Bearbeitung/Daten von Darstellung und Auslösen der Verarbeitung trennen ■ ■ verschiedene Eingaben (Buttons, etc.) verschiedene Darstellungen (gleichzeitig) ■ Klare Aufgabenteilung (Separation of Concerns) BenutzerereignisVerarbeitung Darstellung Controller 1) initiiert Änderung der Daten View 2) benachrichtigt über Datenänderung Model 3) liest neue Daten und stellt diese dar Datenbehälter, inkl. Veränderungsmethoden School of Engineering © G. Burkert, K. Rege, ZHAW 21 von 49 Vereinfachte Implementierung ■ Controller und View sind meist miteinander gekoppelt bzw. in einer Klasse implementiert ■ ■ Controller delegiert Verarbeitung nur wird deshalb meist nicht als separaten Klasse implementiert Controller 1) initiiert Änderung der Daten Viewer 2) benachrichtigt über Datenänderung 3) liest neue Daten und stellt diese dar Model School of Engineering © G. Burkert, K. Rege, ZHAW 22 von 49 Beispiel ■ Ein veränderbarer Kreis mit Methoden grow und shrink ■ View-Controller als JFrame implementiert View-Controller CircleModel int value grow() shrink() School of Engineering Model © G. Burkert, K. Rege, ZHAW 23 von 49 Einfache View import java.awt.*; import java.awt.event.*; import java.JFrame.*;import java.beans.*; public class JFrame1 extends JFrame implements ActionListener, PropertyChangeListener { CircleModel model; JButton grow; Modelle Modellehaben haben oft Properties oft Properties ==Werte Werte public void init() { grow = new JButton("Grow"); grow.addActionListener(this); getContentPane().add(grow); model = new CircleModel(50); model.addPropertyChangeListener(this); } public void actionPerformed(ActionEvent ev) { model.grow(); } public void paint(Graphics g) { int r = model.getValue(); g.drawOval(100-r,100-r,2*r,2*r); } Controller View public void propertyChange(PropertyChangeEvent ev) { repaint(); } } School of Engineering © G. Burkert, K. Rege, ZHAW 24 von 49 0) Anmeldung der View ans Model Controller 1) initiiert Änderung der Daten Viewer 0) Anmeldung 2) benachrichtigt über Datenänderung 3) liest neue Daten und stellt diese dar Model ■ 0) View meldet sich beim Model an, dass es an bestimmten Ereignissen interessiert ist ■ einmalig, bei der Initialisierung ■ Model merkt sich die View(s), die sich angemeldet haben (subscribe) ■ für den späteren Rückruf (call-back) ■ addPropertyChangeListener(this) School of Engineering © G. Burkert, K. Rege, ZHAW 25 von 49 1) Initiieren der Datenänderung Controller 1) initiiert Änderung der Daten Viewer 2) benachrichtigt über Datenänderung 3) liest neue Daten und stellt diese dar Model ■ der Controller ruft die entsprechende Methode vom Model auf public void actionPerformed(ActionEvent ev) { model.grow(); // nur noch Methodenaufruf } School of Engineering © G. Burkert, K. Rege, ZHAW 26 von 49 2) Benachrichtigung über Datenänderungen Controller 1) initiiert Änderung der Daten Viewer 2) benachrichtigt über Datenänderung 3) liest neue Daten und stellt diese dar Model ■ 2) Ereignisbearbeiter-Methode wird aufgerufen ■ propertyChange School of Engineering © G. Burkert, K. Rege, ZHAW 27 von 49 3) Lesen der Daten und Darstellung Controller 1) initiiert Änderung der Daten Viewer 2) benachrichtigt über Datenänderung 3) liest neue Daten und stellt diese dar Model ■ Lesen der Daten via Getter-Methode von Model ■ model.getValue() ■ Anzeigen ■ z.B. repaint() aufrufen School of Engineering © G. Burkert, K. Rege, ZHAW 28 von 49 Verschiedene Ereignisquelle ■ Graphisches Element als Ereignisquelle ■ JButton, etc Benutzereingabe Ereignisquelle Delegiere Verarbeitung Ereignis (Event) erzeuge Ereignis Objekt, z.B ActionEvent Ereignisverarbeiter verarbeitet z.B. in Methode actionPerformed ■ Model als Ereignisquelle ■ Zustandsänderung als Ereignis Zustandsänderung Ereignisquelle (Model) Ereignis (Event) Ereignisverarbeiter (View) erzeuge Ereignis Objekt School of Engineering © G. Burkert, K. Rege, ZHAW 29 von 49 1) CircleModel Klasse grow() Methode import java.awt.event.*; public class CircleModel { private int value; public CircleModel(int value) { this.value = value; } public void setValue(int val) { value = val; } public void grow() { setValue(value+1); } Methode um Werte zu ändern } School of Engineering © G. Burkert, K. Rege, ZHAW 30 von 49 2a) Anmelden von View an CircleModel ■ Verwaltung von PropertyChangeListeners mit Klasse PropertyChangeSupport import java.beans.*; import java.awt.event.*; public class CircleModel{ private int value; private PropertyChangeSupport props; public CircleModel(int value) { this.value = value; props = new PropertyChangeSupport(this); } Anmeldemethode, dass an PropertyChangeEvents interessiert public void addPropertyChangeListener(PropertyChangeListener list) { props.addPropertyChangeListener(list); } } School of Engineering © G. Burkert, K. Rege, ZHAW 31 von 49 2b) Benachrichtigung von View bei Änderung ■ Methode setValue anpassen, dass PropertyChangeEvent bei Änderung ausgelöst wird; firePropertyChange(String name, Object oldVal, Object newVal); import java.beans.*; import java.awt.event.*; public class CircleModel { …… public void setValue(int val) { int old = value; value = val; props.firePropertyChange("value",old,val); } …… } School of Engineering © G. Burkert, K. Rege, ZHAW 32 von 49 3) Auslesen von Wert ■ Auslesen des Werts mittels getValue-Methode public class CircleModel { ……… public int getValue() { return value; } } School of Engineering © G. Burkert, K. Rege, ZHAW 33 von 49 CircleModel komplett import java.beans.*; import java.awt.event.*; public class CircleModel { private int value; PropertyChangeSupport props; public CircleModel(int value) { this.value = value; props = new PropertyChangeSupport(this); } public void setValue(int val) { int old = value; value = val; props.firePropertyChange("value",old,val); } public int getValue() {return value;} public void grow() {setValue(value+1);} public void addPropertyChangeListener(PropertyChangeListener list){ props.addPropertyChangeListener(list); } } School of Engineering © G. Burkert, K. Rege, ZHAW 34 von 49 Zusammenfassung: MVC ■ Model: der Datenbehälter ■ View: zur Darstellung der Daten ■ Controller: zur Verarbeitung von Benutzerereignis, Auslösen der Datenänderung ■ PropertyChangeSupport: Hilfsklasse für die Verarbeitung von Properties ■ ■ ■ PropertyChangeEvent: Event der geschickt wird addPropertyChangeListener () firePropertyChange(String, Object, Object) School of Engineering © G. Burkert, K. Rege, ZHAW 35 von 49 GUI Komponenten School of Engineering © G. Burkert, K. Rege, ZHAW 36 von 49 GUI Komponenten ■ Mittels Komponenten lassen sich einfache GUIs erstellen ■ primär für JFrames ■ Der Event Mechanismus definiert: import java.awt.event.* ■ Dieser wird in Swing bzw. JFC verwendet ■ JFC enthält einen wesentlich reichhaltigeren Satz von GUI Komponenten als der AWT ■ Verschiedenen graphischen Komponenten ■ ■ ■ ■ JButton JTextField JLabel JScrollBar School of Engineering JList ■ JTextArea ■ JCheckBox ■ JComboBox ■.. ■ © G. Burkert, K. Rege, ZHAW 37 von 49 JFC Klassenhierarchie (vereinfacht) Object gemeinsame gemeinsameOberklasse Oberklasse (auch (auchfür fürAWT) AWT) Component "Behälter" "Behälter"für fürandere andere Komponenten Komponenten Container einfache JFC Komponenten JButton JCheckBox Oberklasse Oberklassefür füreigene eigeneJFC JFC Komponenten Komponenten JComponent JScrollbar JLabel JRadioButton JMenu JTextComponent JTextField JTextArea FlowLayout Hilfsklassen zur Anordnungssteuerung School of Engineering Window BorderLayout JPanel JApplet BoxLayout JFrame JDialog auf dem Desktop darstellbare Behälter © G. Burkert, K. Rege, ZHAW 38 von 49 Abstrakte Oberklasse: Component ■ Component ist die abstrakte Oberklasse der meisten GUIKomponenten des AWT Klassenhierarchie der GUIKomponenten: ■ Component enthält viele Methoden, die von den GUI Komponenten geerbt bzw. überschrieben werden: ■ setBackground(Color farbe) setzt Hintergrundfarbe einer Komponente auf farbe ■ setForeground(Color farbe) setzt Vordergrundfarbe einer Komponent auf farbe ■ setFont(Font font) setzt Font einer Komponente auf font ■ Component ■ ■ ■ ■ ■ ■ JButton Container ■ JPanel ■ JFrame JLabel JList JScrollBar JTextComponent ■ JTextArea ■ JTextField ■ Color getBackground() gibt die entsprechenden Werte der Komponente aus ■ Color getForeground() ■ Font getFont() ■ paint(Graphics g) zeichnet die Komponente repaint() veranlasst AWT, die Methode update() der Komponente (sobald als möglich) aufzurufen ■ update() löscht den Bildschirmausschnitt, der der Komponente entspricht, und ruft dann paint() auf ■ setVisible(boolean b) macht entsprechende Komponente (un)sichtbar School of Engineering © G. Burkert, K. Rege, ZHAW 39 von 49 JScrollBar School of Engineering © G. Burkert, K. Rege, ZHAW 40 von 49 Schieberegler (JScrollBar) ■ Der Scrollbar kann durch das Verschieben des Balkens oder durch Drücken auf die Pfeile betätigt werden. Dabei verschiebt er sich mit der konstanten Schrittweite 1 pro Ereignis. ■ Beim Erzeugen eines JScrollBars kann die Ausrichtung des Scrollbars, der Minimal- und Maximalwert, der Startwert sowie die Grösse der Schrittweite angegeben werden ■ Im Gegensatz zu Buttons und Textzeilen erzeugen Scrollbar Ereignisse der Klasse AdjustmentEvent ■ JScrollBar ruft bei jeder Verschiebung der Balkens die Methode adjustmentValueChanged(AdjustmentEvent e) auf ■ Das JFrame muss das AdjustmentListener Interface implementieren ■ Aktueller Wert kann mit der Methode getValue() abgefragt werden School of Engineering © G. Burkert, K. Rege, ZHAW 41 von 49 Schieberegler Graphik ■ Beispiel: Programm ScrollbarValues public void adjustmentValueChanged(AdjustmentEvent e) { Graphics g = getGraphics(); currentX = slider.getValue(); g.drawLine(0, currentY, currentX, currentY); currentY = currentY+5; } School of Engineering © G. Burkert, K. Rege, ZHAW 42 von 49 Schieberegler JScrollbar (Auszug aus der Klassenbibliothek: Constructor) public JScrollbar (int int int int int Parameters: orientation, value, visible, minimum, maximum) orientation - indicates the orientation of the scroll bar. (Scrollbar.HORIZONTAL, or Scrollbar.VERTICAL) value - the initial value of the scroll bar visible - the size of the scroll bar's bubble, representing the visible portion minimum - the minimum value of the scroll bar Achtung: Achtung:nur nurBereich Bereich maximum - the maximum value of the scroll bar 0..90 (da 100-10) 0..90 (da 100-10) ■ Beispiel: (Skript, Schieberegler.java) slider = new Scrollbar(Scrollbar.HORIZONTAL,0,10,0,100); School of Engineering © G. Burkert, K. Rege, ZHAW 43 von 49 …Schieberegler : Anwendungsbeispiel public class L8_Scrollbar extends JFrame implements AdjustmentListener{ private JScrollBar slider; // Instanzvariablen private int sliderValue = 0; public void initComponents() { // GUI aufbauen getContentPane().setLayout(null); // kein Layout slider = new JScrollBar(Scrollbar.HORIZONTAL, 0, 10, 0, 110); slider.setBounds(100,10, 200, 20); // Slider-Grösse. x,y,width, height getContentPane().add(slider); slider.addAdjustmentListener(this); } public void paint(Graphics g) { super.paint(); g.drawString("Aktueller Schiebereglerwert: "+sliderValue, 100, 100); g.setColor(Color.GREEN); g.fillRect(100,150,sliderValue*2, 30); // Slider-Wert als Balken } public void adjustmentValueChanged(AdjustmentEvent e){ sliderValue = slider.getValue(); repaint(); } } School of Engineering © G. Burkert, K. Rege, ZHAW 44 von 49 … Skalierung des Schiebereglerwertes ■ Schieberegler Werte in Ganzzahlen ■ Falls zwischenwerte gewünscht werden, müssen diese "skaliert" werden ■ Beispiel: Der gewünschte Scrollbar-Bereich im Progamm InchesToCm soll 0.0-10.0 sein mit einer Schrittweite von 0.1 ■ Minimum, Maximum und Inkrement des Scrollbars auf 0, 100 bzw. 1 setzen: slider = new Scrollbar(Scrollbar.HORIZONTAL,0,10,0,110); ■ Ausgelesener Scrollbar-Wert jeweils durch 10 dividieren: sliderValue = (double) slider.getValue()/10; School of Engineering © G. Burkert, K. Rege, ZHAW 45 von 49 Einführung Anordnung, Layouts School of Engineering © G. Burkert, K. Rege, ZHAW 46 von 49 Einfache Anordnung von GUI-Komponenten ■ Java ordnet die GUI Komponenten automatisch an (=Layout) ■ Layout definiert "Strategie", wie die Komponenten angeordnet werden ■ ■ Die Komponenten werden zeilenweise zentriert aufgereiht Wenn eine Zeile voll ist, werden die restlichen Komponenten auf einer neuen Zeile dargestellt ■ FlowLayout nicht für "hochwertige" GUIs geeignet ■ z.B. FlowLayout skaliert die Scrollbars automatisch Æ werden sehr klein Abhilfe: andere Layouts definieren (z.B. Border- oder GridLayout Æ später) oder einfach "null"-Layout verwenden School of Engineering © G. Burkert, K. Rege, ZHAW 47 von 49 Null Layout ■ Mittels setLayout(null) kann der Layoutmanager entfernt werden ■ Wird kein Layout angegeben, dass müssen die Komponenten Komponenten von Hand positioniert und skaliert werden public void initComponents() { // GUI aufbauen getContentPane().setLayout(null); // kein Layout slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 1, 100); slider.setBounds(100,10, 200, 20); // Slider-Grösse. x,y,width, height getContentPane().add(slider); slider.addAdjustmentListener(this); } School of Engineering © G. Burkert, K. Rege, ZHAW 48 von 49 Noch Fragen? School of Engineering © G. Burkert, K. Rege, ZHAW 49 von 49