15 Frames, menyer och GUI-program Frames En frame-klass Om konstruktorer - igen Funktionella fönster Menyer Popupmenyer GUI-applikationer Dialogrutor Printerutskrift Kap 15: Sid 2 Vi börjar med att skapa Frames (fönster) från applets. Vi lär oss att stänga fönster, och att förse dem med knappar och menyer. Sedan skapar vi i stället Frames från konsolprogram. En Frame blir då en GUI-applikation, ett fristående javaprogram med grafiskt gränssnitt. Vi lär oss också hur man konverterar applets till fristående javaprogram. Du bör komma så långt så att du utan större svårighet kan skriva om dina gamla applets till GUI-applikationer. 265341520 © Ove Lundgren 2 Kap 15: Sid 3 Frames Redan i kapitel 3 skapade vi en Frame Dags att återuppta bekantskapen! En frame är ett fönster med en titellist och en ram. Vi kan använda frames som komponenter i applets. Mest används de för att bygga fristående applikationer. Vi ska se på båda tillämpningarna. Vi börjar med en applet med en knapp. När man trycker på knappen ska en frame visas. import java.applet.*; import java.awt.*; import java.awt.event.*; public class FrameTest extends Applet implements ActionListener { Frame f; Button b; Label l; public void init() { b = new Button("Visa en frame!"); add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent e) { f = new Frame(); f.setTitle("Min första frame"); l=new Label("Detta är en frame!"); f.add(l); f.setSize(300,200); f.setResizable(true); f.setVisible(true); } } När man trycker på knappen instansieras ett frame-objekt ur klassen Frame. Med setTitle() kan man bestämma vad som ska stå i titellisten. På raden därefter adderas labeln till vår frame. Man måste alltid sätta storlek på en frame (sker med setSize() ) Vår frame får storleken 200x300 pixels. Vi kommer att kunna ändra storlek på den ( setResizable(true) ) Slutligen görs komponenten synlig med setVisible(true) Övning: Visa en Frame Provkör ovanstående applet. Tryck på knappen – skapa en frame. Flytta på den. Tryck igen – skapa fler frames. Testa att ändra storlek (fungerar) Testa att minimera, maximera, stänga (allt fungerar – utom stängning) När du stänger appleten stängs alla öppnade frames. Övning: Hur ärver klassen Frame ? Gå in i dokumentationen och studera hur klassen Frame ärver. ( Frame ärver från Window som ärver från Container som ärver från Component som ärver från Object ) När vi i fortsättningen använder det svenska ordet ”fönster” avses ”frame” (och inte ”window”) om inget annat anges. 265341520 © Ove Lundgren 3 Kap 15: Sid 4 En frame-klass Vi gör en variant på förra övningen. Denna gång ska vi skapa en egen, fristående, frame-klass, en klass som ärver från Frame, alltså. Övning: En mycket enkel frame Skriv in, spara och kompilera filen MinFrame.java import java.awt.*; class MinFrame extends Frame { } Skriv in, spara och kompilera filen VisaFrame.java import java.applet.*; import java.awt.*; import java.awt.event.*; public class VisaFrame extends Applet implements ActionListener { MinFrame f; //Här deklareras ett objekt av typ MinFrame Button b; public void init() { b = new Button("Tryck här"); add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent e) { if (f!=null) // Här testas om en frame redan är öpppen { f.setVisible(false); // Om den är det så stängs den! f.dispose(); // Du kan bara öppna ett fönster åt gången } // i den här versionen! f = new MinFrame(); f.setSize(200,200); f.setLocation(200,200); f.setResizable(true); f.setVisible(true); // // // Här instansieras ett objekt av typen MinFrame Bestämmer plats på skärmen } } Skriv också en VisaFrame.html -fil och provkör. Vi får ungefär samma funktion som i förra övningen. Den här gången kan vi dock bara öppna en frame åt gången på grund av testen som görs i VisaFrame. Fönstret hamnar med sitt övre vänstra hörn i skärmposition (200,200) Det går fortfarande inte att stänga fönstret. För att göra det måste vi skriva lite kod. Nu när vi har skapat en egen frame-klass har vi alla möjligheter att bygga in önskad funktionalitet i vår frame! I nästa övning ska vi se till att vår frame går att stänga. Dessutom vill vi ha en text i titellisten 265341520 © Ove Lundgren 4 Kap 15: Sid 5 Övning: Stäng fönstret! Skriv om klassen MinFrame enligt nedan. Läs kommentarerna! WindowListener är ett gränssnitt som gör att vi kan implementera metoderna (händelsehanterarna) som har med fönsterhantering att göra. import java.awt.event.*; import java.awt.*; class MinFrame extends Frame implements WindowListener { public MinFrame() // konstruktor { Vår frame kommer att få titeln ”Min Frame” setTitle("Min Frame"); Här ”klistrar” vi även på en fönsterlyssnare. addWindowListener(this); } public void windowClosing(WindowEvent e) { setVisible(false); Anropas när fönstret stängs dispose(); } public void windowClosed(WindowEvent e){ } public void windowOpened(WindowEvent e){ } Vi måste ”släpa” på alla public void windowIconified(WindowEvent e){ } metoderna som gränssnittet public void windowDeiconified(WindowEvent e){ } hanterar – även om vi inte public void windowActivated(WindowEvent e){ } använder dem! public void windowDeactivated(WindowEvent e){ } } Spara filen MinFrame.java. Kompilera. Kör VisaFrame och klicka på knappen. Ett fönster öppnas. Fönstret har en titeltext och, framför allt, fönstret går att stänga! Som du ser är det många metoder som ska vara med i koden när vi implementerar gränssnittet WindowListener. Kommer du ihåg vad en adapterklass är? (Om inte: Läs/Repetera avsnittet om adapterklasser i kapitel 10 ) Naturligtvis finns det en adapterklass för metoderna i gränssnittet WindowListener. Adapterklassen heter WindowAdapter Om vi använder adapterklasser kan klassen ovan skrivas så här: import java.awt.event.*; import java.awt.*; class MinFrame extends Frame { public MinFrame() // konstruktor { setTitle("Min Frame"); addWindowListener(new FonsterLyssnare() ); } class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); } } Inre klass som ärver WindowAdapter } Ändra så att MinFrame använder adapterklassen WindowAdapter. Spara – kompilera – kör! 265341520 © Ove Lundgren 5 Kap 15: Sid 6 Välj själv om du vill implementera WindowListener (och ta med alla metoderna i koden) eller om du vill arbeta med inre klasser som ärver adapterklassen WindowAdapter. (I detta kapitel används genomgående adapterklassen för fönsterhändelserna) Övning: Två konstruktorer Ändra i MinFrame så att klassen får dessa båda konstruktorer: public MinFrame() // Samma konstruktor som förut { // Inget argument setTitle("Min Frame"); addWindowListener(new FonsterLyssnare()); } public MinFrame(String s, Color c) // Ny konstruktor: { // Ett argument av typen String setTitle(s); // och ett av typen Color setBackground(c); addWindowListener(new FonsterLyssnare()); } Spara MinFrame.java och kompilera. I VisaFrame, i actionPerformed, byt ut f = new MinFrame() mot f = new MinFrame("Heja Åmål", Color.blue); Nu kommer den andra, den nya, konstruktorn att användas eftersom den "matchar" instansieringssatsen: Spara - Kompilera -Testa! Fönstret visas. Den sträng som var argument vid instansieringen står på titellisten. 265341520 © Ove Lundgren 6 Kap 15: Sid 7 Funktionella fönster Nu ska vi bygga in lite funktionalitet i ett fönster. Vi lägger in tre knappar. Genom att trycka på dem kan vi ändra fönstrets bakgrundsfärg. Observera att frames automatiskt har borderlayout! Övning: Ett fönster med knappar Skriv koden. Spara som KnappFrame.java. Kompilera. import java.awt.event.*; import java.awt.*; class KnappFrame extends Frame implements ActionListener { Button b1, b2, b3; public KnappFrame() // konstruktorn! { setTitle("Min Frame"); b1=new Button("Rött"); b1.addActionListener(this); b2=new Button("Grönt"); b2.addActionListener(this); b3=new Button("Blått"); b3.addActionListener(this); add("West",b1);add("South",b2);add("East",b3); addWindowListener(new FonsterLyssnare() ); } public void actionPerformed(ActionEvent e) { if (e.getSource()==b1) setBackground(Color.red); else if (e.getSource()==b2) setBackground(Color.green); else if (e.getSource()==b3) setBackground(Color.blue); repaint(); } class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); } } } Gå igenom koden noga. (Du bör känna igen allt.) Ändra i VisaFrame.java så att fönsterobjekt av typ KnappFrame skapas och visas då man trycker på knappen. När du trycker på knapparna i fönstret ändras bakgrundsfärgen… 265341520 © Ove Lundgren 7 Kap 15: Sid 8 Menyer I frames kan man använda menyer Övning: Menyer Skriv in filen nedan. Spara den som MenyFrame.java och kompilera. Ändra så att VisaFrame kan visa fönstret MenyFrame. Spara - kompilera - provkör. Läs kommentarerna efter koden. import java.awt.event.*; import java.awt.*; class MenyFrame extends Frame implements ActionListener { MenuBar mbar; Menu fargmeny; MenuItem rod, gro, bla, gul; Menu svmeny; MenuItem sva, vit, gra; public MenyFrame() // konstruktorn { setTitle("En frame med menyer"); mbar = new MenuBar(); fargmeny = new Menu("Färger"); rod = new MenuItem("Rött"); fargmeny.add(rod); rod.addActionListener(this); gro = new MenuItem("Grönt"); fargmeny.add(gro); gro.addActionListener(this); bla = new MenuItem("Blått"); fargmeny.add(bla); bla.addActionListener(this); gul = new MenuItem("Gult"); fargmeny.add(gul); gul.addActionListener(this); mbar.add(fargmeny); svmeny = new Menu("SvartVitt"); sva = new MenuItem("Svart"); svmeny.add(sva); sva.addActionListener(this); vit = new MenuItem("Vitt"); svmeny.add(vit); vit.addActionListener(this); gra = new MenuItem("Grått"); svmeny.add(gra); gra.addActionListener(this); mbar.add(svmeny); this.setMenuBar(mbar); addWindowListener(new FonsterLyssnare() ); } public void actionPerformed(ActionEvent e) { if (e.getSource()==rod) setBackground(Color.red); else if (e.getSource()==gro)setBackground(Color.green); else if (e.getSource()==bla) setBackground(Color.blue); else if (e.getSource()==gul) setBackground(Color.yellow); else if (e.getSource()==sva)setBackground(Color.black); else if (e.getSource()==vit) setBackground(Color.white); else if (e.getSource()==gra) setBackground(Color.gray); repaint(); } class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); } } } 265341520 © Ove Lundgren 8 Kap 15: Sid 9 Högst upp i fönstret ser vi nu en "menylist" (MenuBar) På denna finns två menyer (Menu) med texterna "Färger" respektive "SvartVitt". Den vänstra menyn har fyra menyalternativ (MenuItem) den högra har tre. MenuBar Menu Menu Item Vår menylist (MenuBar) refererar vi till som mbar. Menyerna kallar vi fargmeny respektive svmeny. fargmeny har menyalternativen rod, gro, bla, gul. svmeny har menyalternativen sva, vit, gra I konstruktorn instansieras objekten: Menylisten: mbar = new MenuBar(); Första menyn: fargmeny = new Menu("Färger"); De alternativ som hör till denna meny instansieras, adderas till menyn och förses med en lyssnare: rod = new MenuItem("Rött"); fargmeny.add(rod); rod.addActionListener(this); (på samma sätt för övriga alternativ…) Sedan adderas den "färdigkomponerade" menyn till menylisten: mbar.add(fargmeny); Andra menyn (svmeny) och dess objekt behandlas på motsvarande sätt… Slutligen måste den kompletta menylisten anknytas till vår frame och det sker med: this.setMenuBar(mbar); Händelsehanteraren som används vid menyhantering är actionPerformed(AvtionEvent e) (samma som för Buttons alltså) så vi använder addActionListener när vi adderar lyssnare. Metoden actionPerformed() i denna frame är mycket lik motsvarande metod i föregående övning (den med knappar) 265341520 © Ove Lundgren 9 Kap 15: Sid 10 Övning: Undermenyer. Vi vill skapa en undermeny under alternativet "Grått", så här: Det är enkelt: Vi definierar gra som en Menu och skapar tre nya MenuItems: ljugra, melgra, morgra De nya menyalternativen adderas förstås till menyn gra. När menyn gra är färdigkomponerad adderas den till menyn svmeny Gör alltså tillägg och ändringar enligt följande: Menu svmeny; MenuItem sva, vit; Menu gra; MenuItem ljugra, melgra, morgra; svmeny = new Menu("SvartVitt"); sva = new MenuItem("Svart"); svmeny.add(sva); sva.addActionListener(this); vit = new MenuItem("Vitt"); svmeny.add(vit); vit.addActionListener(this); gra = new Menu("Grått"); ljugra = new MenuItem("Ljusgrått"); gra.add(ljugra); ljugra.addActionListener(this); melgra = new MenuItem("Mellangrått"); gra.add(melgra); melgra.addActionListener(this); morgra = new MenuItem("Mörkgrått"); gra.add(morgra); morgra.addActionListener(this); svmeny.add(gra); mbar.add(svmeny); Komplettera i actionPerformed-metoden så att bakgrunden kan få någon de grå nyanserna. Spara, kompilera och kör VisaFrame. 265341520 © Ove Lundgren 10 Kap 15: Sid 11 Popupmenyer Popupmenyer fungerar som vanliga menyer men man behöver ju inte någon MenuBar. Popupmenyn adderas direkt till fönstret. Så måste man förstås ha en muslyssnare som känner av om man klickar… Övning: Popup Testa gärna detta fönster. (Provkör det med VisaFrame.) import java.awt.event.*; import java.awt.*; class PopupMenyFrame extends Frame implements ActionListener, MouseListener { PopupMenu fargmeny; MenuItem rod, gro, bla, gul; public PopupMenyFrame() // konstruktorn { setTitle("En frame med popupmeny"); fargmeny = rod = new gro = new bla = new gul = new new PopupMenu("Färger"); MenuItem("Rött"); fargmeny.add(rod); rod.addActionListener(this); MenuItem("Grönt"); fargmeny.add(gro); gro.addActionListener(this); MenuItem("Blått"); fargmeny.add(bla); bla.addActionListener(this); MenuItem("Gult"); fargmeny.add(gul); gul.addActionListener(this); this.add(fargmeny); addWindowListener(new FonsterLyssnare() ); addMouseListener(this); } public void actionPerformed(ActionEvent e) { if (e.getSource()==rod) setBackground(Color.red); else if (e.getSource()==gro)setBackground(Color.green); else if (e.getSource()==bla) setBackground(Color.blue); else if (e.getSource()==gul) setBackground(Color.yellow); repaint(); } class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); } } public void mousePressed(MouseEvent e) { if(e.isMetaDown() ) // kollar om höger musknapp tryckts { fargmeny.show(this,e.getX(), e.getY() ); } } public void mouseReleased(MouseEvent e){} public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} } Observera hur man ”känner av” höger musknapp… 265341520 © Ove Lundgren 11 Kap 15: Sid 12 GUI-applikationer Hittills har vi mest arbetat med applets, och ibland, då och då, med fristående konsolprogarm. Det är hög tid att skapa vår första GUI-applikation, det vill säga en fristående java-applikation med frames! (GUI = Graphic User Interface ) Redan i kapitel 3 visade vi hur det går till: Man skriver ett javaprogram (som innehåller metoden main) och så låter vi main instansiera ett frame-objekt och visa det. Övning: En GUI-applikation Vi vill visa vår frame KnappFrame som ett ”fristående fönster”, som en egen GUI-applikation: Skriv nedanstående lilla fil. Spara den som StartaFrame.java Spara den i samma mapp som filerna KnappFrame.java och KnappFrame.class Kompilera. class StartaFrame { public static void main( String args[]) { KnappFrame f; f = new KnappFrame(); // Instansierar ett objekt av typ KnappFrame f.setSize(400,300); // Sätter storlek på fönstret f.setLocation(200,200); // Fönstrets placering f.setResizable(true); // Tillåter användaren att ändra storlek f.setVisible(true); // Visar fönstret } } I KnappFrame.java måste vi göra ett tillägg. Eftersom vår frame ska ”leva sitt eget liv” måste vi se till att den stängs ordentligt (det skötte appleten förut) Gör tillägget System.exit(0); i metoden windowClosing( ), så här: public void windowClosing(WindowEvent e) { setVisible(false); dispose(); System.exit(0); // stänger applikationen helt } Spara KnappFrame.java och kompilera. Exekvera nu StartaFrame (med kommandot java) KnappFrame visas som en fristående applikation! 265341520 © Ove Lundgren 12 Kap 15: Sid 13 Vi skapade (av pedagogiska skäl) en särskild class-fil som endast innehöll en main-metod . Det är inte nödvändigt att skapa en särskild klass för main-metoden. Vi kan lika gärna skriva main-metoden direkt i frame-klassen! När frame-klassen exekveras startar den med att leta upp main-metoden, och när main-metoden utförs så instansieras ett objekt ur frame-klassen. (Klassen instansierar alltså objekt ur ”sig själv”!) Övning: GUI-applikationen - igen Markera och kopiera main-metoden i StartaFrame-klassen Klistra in den i KnappFrame-klassen. Det spelar ingen roll var man placerar den. (Man brukar oftast lägga den först eller sist.) Så här kan det se ut: import java.awt.event.*; import java.awt.*; class KnappFrame extends Frame implements ActionListener { public static void main( String args[]) { KnappFrame f; f = new KnappFrame(); f.setSize(400,300); f.setLocation(200,200); f.setResizable(true); f.setVisible(true); } Button b1, b2, b3; public KnappFrame() // konstruktorn! { setTitle("Min Frame"); b1=new Button("Rött"); b1.addActionListener(this); b2=new Button("Grönt"); b2.addActionListener(this); b3=new Button("Blått"); b3.addActionListener(this); add("West",b1);add("South",b2);add("East",b3); addWindowListener(new FonsterLyssnare() ); } och så vidare ... Spara – kompilera – provkör! Övning: GUI-applikation med menyer Gör om MenyFrame till en fristående javaapplikation genom att tillfoga en main-metod. Kom ihåg att tillse att MenyFrame stängs ordentligt vid avslut. 265341520 © Ove Lundgren 13 Kap 15: Sid 14 Övning: Från applet till GUI-applikation Ta fram en gammal applet, Cirkel.java (Testa först att den fungerar…!) Vi ska göra de ändringar som krävs för att appleten ska bli en fristående applikation. Vi kallar klassen CirkelApp. Den ska ärva från frame och implementera några lyssnare: public class CirkelApp extends Frame implements ActionListener Skriv klassens konstruktor: public CirkelApp() { } I denna: Välj (eventuellt) flowlayout: setLayout(new FlowLayout()); Associera fönsterlyssnaren till fönstret: addWindowListener(new FonsterLyssnare() ); Kopiera satserna i init-metoden (och i eventuell start-metod) till konstruktorn och ta bort denna (dessa) metod(er). Lägg in en inre klass för att hantera fönstret: class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); System.exit(0); } } Lägg till en main-metod: public static void main( String args[]) { CirkelApp f; f = new CirkelApp(); f.setSize(400,300); f.setResizable(true); // eventuellt f.setLocation(200,200); f.setVisible(true); } Spara som CirkelApp.java Kompilera och provkör… Den f d appleten uppträder nu som en fristående applikation… Mer att tänka på: I applets som inte har händelsehantering: Kom ihåg import java.awt.event.*; Lägg satser som används vid dubbelbuffring (createImage och getGraphics) i windowOpened() Satser i appletens stop- och destroy-metod lägger du först i windowClosing() och ta bort stop-och destroy-metoderna. Ljud och bild hanteras på lite annat sätt än i applets: Se nästa avsnitt! Övning: Applet till applikation Välj någon annan applet. Skriv om den som applikation. 265341520 © Ove Lundgren 14 Kap 15: Sid 15 Bild och ljud i applikationer Bild Gör så här för att visa en bild, som är lagrad på en fil, i en applikation: Deklarera en referens Image-objekt: Image im; Denna sats skapar Image-objektet im och hämtar bilden från fil: im = Toolkit.getDefaultToolkit().getImage("minbild.gif"); Ljud Importera paketen sun.audio och java.io : import sun.audio.*; import java.io.*; Deklarera dessa objektreferenser: InputStream in; AudioStream as; Skapa ett FileInputStream-objektet, in (Öppna en inputstream till ljudfilen): try { in = new FileInputStream("ljud.au"); } catch(FileNotFoundException fnfe ) { } Skapa ett AudioStream-objekt, as, från in: try { as = new AudioStream(in); } catch(IOException ioe){ } Ljudet spelas upp med: AudioPlayer.player.start(as); Ljudet stoppas med: AudioPlayer.player.stop(as); Om du vill ha ett kontinuerligt ljud: Deklarera även dessa objektreferenser: AudioData data ; ContinuousAudioDataStream cas; Lägg till satserna: try { data = as.getData(); } catch(IOException ioe){ } cas = new ContinuousAudioDataStream (data); Ljudet spelas upp med: AudioPlayer.player.start(cas); Ljudet stoppas med: AudioPlayer.player.stop(cas); ( Källa: http://www.javaworld.com/javaworld/javatips/ 265341520 © Ove Lundgren Tips nummer 24 ) 15 Kap 15: Sid 16 Dialogrutor En dialogruta (objekt ur klassen Dialog ) är ett fönster utan ram men med titellist. Övning: Meddelanderuta Öppna en applikation, förslagsvis KnappFrame.java Lägg till ytterligare en knapp, b4: Button b1, b2, b3, b4; b4=new Button("Visa meddelande"); b4.addActionListener(this); add("North",b4); Deklarera en dialogruta, d, samt en label, en knapp och en panel som ska finnas på dialogrutan: Dialog d; Label dlabel; Button dbutton; Panel dpanel; Instansiera objekten och addera dem till dialogrutan. Knappen ska dessutom få en lyssnare: d = new Dialog(this, "Meddelande", true); dpanel = new Panel(); dlabel = new Label("Detta är ett meddelande!"); dbutton=new Button("Stäng"); d.add("Center", dpanel); dpanel.add(dlabel); dpanel.add(dbutton); dbutton.addActionListener(this); Gör tilläg i actionPerformed() så att de nya knapparna får respons: if (e.getSource()==b4 && !d.isShowing() ) { d.setSize(200,100); d.setLocation(200,200); d.setVisible(true); } if (e.getSource()==dbutton) { d.setVisible(false); d.dispose(); } // knapp b4 öppnar såvida inte // dialogrutan redan visas // knapp dbutton på dialogrutan gör att // dialogrutan stängs Spara filen. kompilera och provkör. När du klicka knappen ”Visa meddelande” visas dialogrutan. Försök att ändra fönstrets bakgrundsfärg medan dialogrutan visas. Det går inte. Denna dialogruta är modal. Det betyder att man måste stänga dialogrutan innan man kan påverka andra fönster. Dialogrutan instansierades med satsen d = new Dialog(this, "Meddelande", true); Första argumnetet ska vara ett frame-objekt, nämligen det fönster från vilket dialogrutan startas (här this). Den andra argumentet är texten i dialogrutans titellist. Den tredje argumentet anger om dialogrutan ska vara modal eller ej. Ändra tredje argumentet från true till false. Spara. Kompilera. Provkör. Dialogrutan är nu icke-modal. I vårt exempel kan färgerna ändras medan dialogrutan visas… 265341520 © Ove Lundgren 16 Kap 15: Sid 17 Printerutskrift Från en applikation kan vi få utskrift på printer. Här är ett testprogram. Läs kommentarer nedan import java.awt.event.*; import java.awt.*; class SkrivTest extends Frame implements ActionListener { PrintJob pjobb; Graphics pg; Button b; public SkrivTest() { setTitle("SkrivTest"); b = new Button("Utskrift"); add("South",b); addWindowListener(new FonsterLyssnare() ); } b.addActionListener(this); public void paint(Graphics g) { g.setColor(Color.lightGray); g.fillRect(50,50,250,80); g.setFont( new Font("Helvetica",Font.BOLD,30) ); g.setColor(Color.red); g.drawString("Hallå Java",100,100); } public void actionPerformed(ActionEvent e) { pjobb = this.getToolkit().getPrintJob(this,"Utskrift",null); if(pjobb!=null) { pg = pjobb.getGraphics(); if(pg!=null) { pg.setColor(Color.lightGray); pg.fillRect(50,50,250,80); pg.setFont( new Font("Helvetica",Font.BOLD,30) ); pg.setColor(Color.red); pg.drawString("Hallå Java",100,100); pg.dispose(); } pjobb.end(); } } class FonsterLyssnare extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); dispose(); System.exit(0); } } public static void main(String[] args) { SkrivTest f; f = new SkrivTest(); f.setSize(360,200); f.setResizable(false); f.setVisible(true); } } 265341520 © Ove Lundgren 17 Kap 15: Sid 18 För utskrift används ett objekt av klassen PrintJob Objekt av klassen Window (som ju Frame ärver ifrån) har en metod vid namn getToolkit() Denna metod returnerar ett objekt av en klass som heter Toolkit. Ett Toolkit -objekt har en metod getPrintJob(Frame f, String s, Properties p) som returnerar ett PrintJob-objekt. getPrintJob(f,s,p) har tre argument: f är aktuell Frame (i vårt fall this) s är en sträng, ett namn på printerjobbet p är ett objekt av typ Properties som kan ge utskriften vissa egenskaper. Vi sätter värdet null. PrintJob-objektet (som vi kallar pjobb) instansieras med satsen pjobb = this.getToolkit().getPrintJob(this,"Utskrift",null); pjobb har ett grafiskt objekt (precis som applets,frames, images…) Med pg = pjobb.getGraphics(); får vi en referens(i vårt fall pg ) till pjobbs grafiska objekt. Sen kan vi beskriva vad som ska skrivas ut, i vårt exempel, bland annat: pg.setFont( new Font("Helvetica",Font.BOLD,30) ); pg.setColor(Color.red); pg.drawString("Hallå Java",100,100); (Samma teknink som när vi byggde upp ”spökbilder” för dubbelbuffring, alltså…) Kom ihåg pg.dispose(); och pjobb.end(); Övning: Utskrift Testa ovanstående applikation 265341520 © Ove Lundgren 18 Kap 15: Sid 1 Del av klasshierarkien TextComponent Event Objekt Component Graphics CheckBox Panel Applet Window Frame Container Label Dialog CheckboxGroup Button Image List FileDialog Choice 265341520 © Ove Lundgren 1