TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 7 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Grafiskt användargränssnitt, Swing Layout och komponenter Göra egna komponenter Lyssnare och händelser Dialogrutor 1
Fönster Rätt snart vill man rita upp egna typer av fönster Lösning: Klassen JFrame implementerar ett fönster För att skapa ett eget, skriv en klass som ärver från denna. Fyll sedan fönstret med de komponenter du vill ha. JFrame, m.fl. finns I paketet javax.swing Bygger på det äldre paketet java.awt. Vissa delar av det kan behövas. 2
Fönster, exempel public class MyFrame extends JFrame { public MyFrame() { super("välkomstfönster"); JLabel text = new JLabel("Hej allesammans!"); getcontentpane().add(text); setsize(new Dimension(300, 200)); setdefaultcloseoperation(jframe.exit_on_close); Jlabel är en komponent Komponenter läggs till, med metoden add public static void main(string[] args) { JFrame thewindow = new MyFrame(); thewindow.setvisible(true); 3
Komponenter (ex.) 4
Layouthanterare Problem: Om två eller flera komponenter läggs till, var placeras de? Lösning: Använd en layouthanterare Andra fördelar: Layouthanteraren bestämmer hur saker förstoras/förminskas då man drar i fönstret. getcontentpane().setlayout(new FlowLayout()); En enkel layouthanterare som helt enkelt lägger komponenterna på rad. Vi tar ett litet exempel... 5
Layouthanterare(2) BorderLayout. Vi tar ett litet exempel... - Layouten blir ofta ganska grov + Enkel att använda Förfina med under-layouter! 6
Layouthanterare(3) BoxLayout Container c = getcontentpane(); c.setlayout(c, BoxLayout.Y_AXIS); JPanel p = new Jpanel(); p.setlayout(p, BoxLayout.Y_AXIS); c.add(p); Box b = new Box(BoxLayout.Y_AXIS); c.add(b); Box b2 = new Box(BoxLayout.X_AXIS); b.add(b2); b2.add(new JLabel( Author )); b2.add(new JTextField()); - Mycket jobb... + Lätt att förstå + Kan bli hur detaljerad som helst + Använd Glue och Strut för utfyllnad... Box b3 = new Box(BoxLayout.X_AXIS); b.add(b3); b3.add(box.createhorizontalglue()); b3.add(new Jbutton( Search )); b3.add(box.createhorizontalglue()); 7
Layouthanterare(4) En sammanfattning: FlowLayout GridLayout(r, k) BorderLayout BoxLayout(riktning) finns fler... Komponenterna placeras från vänster till höger i rader, uppifrån och ner Delar upp fönstret i rutmönster om r rader och k kolumner. Alla rutor (d.v.s. komponenter) blir lika stora Delar upp fönstret i fem delar: längs sidorna och i mitten: NORTH, SOUTH, WEST, EAST, CENTER En gör-det-själv layout. Placerar komponenterna bredvid varandra antingen i x-led eller y-led. Lätt att förstå, mycket att skriva. 8
Egna komponenter (1) Antag att vi vill göra ett GUI för en bil... Egengjord komponent! Egengjord komponent! JLabel lab = new JLabel(); lab.seticon(new ImageIcon(ImageIO.read( new File("speedometer.jpg")))); this.add(lab); 9
Egna komponenter (2) Vi gör en egen klass FuelGuage, som ärver från JComponent och överlagrar metoden paintcomponent. paintcomponent är en metod som kommer att anropas då fönstret ritar ut sig själv. Fönstret bestämmer själv då detta behövs och ser till att allting ritas i rätt ordning. Vi kan trigga en omritning genom att anropa repaint(). 10
Egna komponenter (3) Vi gör en egen klass FuelGuage, som ärver från JComponent och överlagrar metoden paintcomponent. y x paintcomponent kommer anropas med ett Graphics-objekt som man kan använda för att rita ut med. Finns metoder för att rita bilder, text och geometriska figurer. Komponenten håller reda på hur stor den är. Vi kan ta reda på det med metoderna getwidth() och getheight(). Vi tar ett litet exempel... 11
Egna komponenter (4) Hur gör vi nu så att man kan öka/minska bränslemätaren med piltangenterna? Vi skulle kunna polla tangentbordet. i main: x y while (true) { if (keyboarduppressed()) { // increase fuel 1%. else if (keyboarddownpressed()) { // decrease fuel 1%. Problem? busy-loop (vi kan lägga in en sleep). Vi kan inte göra något annat under tiden. 12
Egna komponenter (5) Hur gör vi nu så att man kan öka/minska bränslemätaren med piltangenterna? Vi skulle kunna registera en lyssnare hos vår komponent. this.setfocusable(true); this.addkeylistener(new MyKeyListener()); public class MyKeyListener extends KeyListener() { public void keypressed(keyevent ev) {... public void keyreleased(keyevent ev) {... public void keytyped(keyevent ev) {... Vi tar ett litet exempel... Runtime-systemet håller då reda på om någon har tryckt på en knapp och meddelar vår lyssnare. 13
Händelser och lyssnare För att programmet ska kunna reagera på händelser kopplar man på olika typer av lyssnare till komponenter i fönstret Lyssnarna kan fånga upp händelser som knapptryckningar och musrörelser Observera att lyssnare är interfaces, du måste själv implementera dem (all dess metoder). Händelse ActionEvent MouseEvent KeyEvent MenuEvent Lyssnare ActionListener, för knappar m.m. MouseListener, MouseMotionListener KeyListener MenuListener 14
Händelser och lyssnare (2) Vi skapade en lyssnar-klass som vi egentligen bara vill använda en gång, just vid ett anrop... Här kan det vara lämpligt med en anonym inre klass: this.setfocusable(true); this.addkeylistener(new KeyListener() { public void keypressed(keyevent ev) {... public void keyreleased(keyevent ev) {... public void keytyped(keyevent ev) {... ); Blir direkt en implementation till KeyEvent! 15
Händelser och lyssnare (3) Om vi bara vill implementera en metod så finns det en smidig Adapter-klass: this.setfocusable(true); this.addkeylistener(new KeyAdapter() { public void keypressed(keyevent ev) {... ); KeyListener <<interface>> +keypressed() +keyreleased() +keytyped() KeyAdapter +keypressed() +keyreleased() +keytyped() Vår anonyma klass +keypressed() 16
Händelser och lyssnare(4) Sätta bränslet till exakt där man klickar med musen... y x this.setfocusable(true); this.addmouselistener(new MouseAdapter() { public void mousepressed(mouseevent ev) {... ); Vi tar ett litet exempel... 17
Dialogrutor JOptionPane används för att visa dialogrutor Ett urval av de statiska metoderna: showconfirmationdialog showinputdialog showmessagedialog String name = JoptionPane.showInputDialog("Logga in:"); if (name!= null) { // null if user cancels JOptionPane.showMessageDialog(null, "Hej " + namn); 18
Dialogrutor (3) JFileChooser kan användas för att låta användaren öppna/spara en fil. Objektet kan öppna en dialogruta. När rutan stängs ner returneras ett heltal som anger hur dialogrutan stängdes. JFileChooser chooser = new JfileChooser(CarGui.this); int result = chooser.showopendialog(); if (result == JFileChooser.APPROVE_OPTION) { File f = chooser.getselsectedfile(); 19 Finns t.ex, CANCEL_OPTION, och några till.