Grafiska komponenter. Kap J5-1 Grafiska användargränssnitt är det moderna alternativet till traditionell terminal-i/o. GUI-programmering bygger på en händelsestyrd flödeskontroll. I Java utförs GUI-programmeringen med hjälp av standardpaketet AWT vilket följer med alla Javasystem. AWT (Abstract Window Toolkit) innehåller basklasserför att skapa GUI. Finns i java.awt. är portabelt och fungerar tvärsöver olika plattformar. enkelt att använda för enkla gränssnitt. Ett närliggande begrepp är Java-appleten som är ett program som kan laddas ner från internet och köras i värddatorn. som baseras på AWT-komponenter. En översikt. Kap J5-2 AWT-paketet är organiserat i form av klasser i en arvshierarki. Se fig nästa bild. Observera att klasser som t ex Font och Color vilka också definieras i java.awt-paketet ej tillhör Component-hierarkin. De ärver direkt från Object. Component-klassen abstrakt representerar något med position och storlek som kan ritas på skärmen samt ta emot input -händelser. Några viktigare metoder är (finns många!) void paint(graphics g); void repaint(); //anropar paint void setsize(int width, int height); void setbackground (Color c); void setfont(font f); void show(); //setvisible( boolean b); Översikt av Javas grafiska komponenter Kap J5-3 Panel Applet Container Button Checkbox ScrollPane Window Dialog Frame FileDialog Choice Component List Canvas Label TextComponent Scrollbar TextArea TextField 1
En översikt, forts. Kap J5-4 Container-klassen abstrakt superklass representerar komponenter som kan innehålla andra komponenter. Container IS-A Component hjälpobjekt LayoutManager. bestämmer hur komponenterna skall ordnas i containern. Några centrala metoder är void setlayout(layoutmanager mgr); LayoutManager getlayout(); void add (Component comp ); void remove(component comp ); void add (Component comp, Object where); pack() //för subklasser till Window, version? void show(); //setvisible( boolean b); storleken bestäms av typ av Container och val av LayoutManager. Liten FileDialog-applikation Kap J5-5 En applikation som använder GUI-gränssnitt måste ha en Frame (eller subklass till Frame) som yttersta container. import java.io.*; public class FilDialogTest { // Pop up a FileDialog, select a file, and list contents public static void main( String [ ] args ) throws IOException { Frame f = new Frame( ); f.show( ); FileDialog d; d = new FileDialog( f, "List File ", FileDialog.LOAD ); d.show( ); String filename; if( ( filename = d.getfile( ) )!= null ) ListaFiler.listFile( filename ); System.exit( 0 ); Exekvering av FileDialog-applikationen Kap J5-6 D:\minaprog\java\ohtester>java FilDialogTest FILE: a.txt Peter Hellstr m D:\minaprog\java\ohtester> 2
Kort beskrivning av Javas grafiska komponenter. Kap J5-7 Button knapp (med text) CheckBox markerbar ruta med tillhörande text. Kan grupperas. Choice popup-meny List meny i ruta (bläddringslist) Canvas målarduk Label Enkel fast text. TextComponent (superklass) TextField enkel rad för textinmatning. TextArea för flerradstextredigering. Scrollbar skjutreglage för värdesinställning. Kap J5-8 Kort beskrivning av Javas grafiska komponenter, forts. Container (superklass) behållare för grafiska komponenter. Window (superklass) fristående fönster (saknar kanter och titelrad ). Frame fristående fönster (med kanter och titelrad). Dialog dialogfönster (superklass till FileDialog) Panel delfönster, som måste inkapslas i en container. avänds för att få en hierarkisk struktur. Applet innehåller komponenter. har inget eget fönster och kan inte visas på skärmen. Webbläsare eller appletviewer tillhandahåller fönstret. Scrollpane container för en enda komponent. Label. Kap J5-9 Visar en text på skärmen. class ShowLabel extends Frame { public static void main(string[] arg) { ShowLabel w= newshowlabel(); Label l1= new Label("X koord", Label.CENTER); Label l2= new Label("Y koord", Label.CENTER); l1.setfont(newfont("sansserif", Font.BOLD, 12)); l1.setbackground(color.yellow); l1.setforeground(color.blue); w.setlayout(new GridLayout(1,2)); w.add(l1); w.add(l2); w.setsize(400,150); w.show();//w.setvisible(true); 3
Egna grafiska komponenter. Kap J5-10 Egna grafiska komponenter kan skapas genom att låta en egen klass ärva egenskaper från en grafisk standardklass. import java.text.*; class TidpunktG extends Label { //instansvariabler private int t,m,s; private boolean visasek=true; private NumberFormat nf = NumberFormat.getInstance(); //Konstruktorer public TidpunktG(int ti,int mi,int se) { t=ti; m=mi; s=se; nf.setminimumintegerdigits(2); setfont(new Font("Monospaced", Font.BOLD,18)); setbackground(color.lightgray); setalignment(center); public TidpunktG(int t,int m) { this( t, m, 0); visasek=false; public String tostring() { String tid= nf.format(t) + ":" + nf.format(m); if (visasek ) tid=tid + ":" + nf.format(s); return tid; //paint anger hur ett objekt skall ritas //på skärmen. public void paint(graphics g) { settext(tostring() ); Egna grafiska komponenter, forts. Kap J5-11 Egna grafiska komponenter kan skapas genom att låta en egen klass ärva egenskaper från en grafisk standardklass. class TidDemoG extends Frame { TidpunktG t1; TidpunktG t2; TidDemoG() { t1= new TidpunktG(0,0); t2= new TidpunktG(10,20,30); setsize(250,100); setlayout(newgridlayout(2,2,5,5)); //2 rad, 2 col add(new Label("Tidpunkt 1", Label.CENTER)); add(new Label("Tidpunkt 2", Label.CENTER)); add(t1); add(t2); show();//setvisible(true); public static void main(string[] arg) { TidDemoG demo = new TidDemoG(); Panel. Kap J5-12 Panel är subklass både till Component och till Container. d v s man kan med metoden add() placera andra komponenter i ett Panel-objekt. används för att skapa en hierarkisk uppbyggnad av ett fönster. varje Panel har ett eget koordinatsystem och en egen LayoutManager. 4
Panel-klassen Train Kap J5-13 class Train extends Panel { //instansvariabler TidpunktG dep, arr; String no, destination; String comment = " "; Label comlabel=new Label(comment); //Konstruktor public Train(String TrainNo, String dest, int dephour, int depmin, int arrhour, int arrmin) { no= TrainNo; destination= dest; dep= new TidpunktG(depHour, depmin); arr= new TidpunktG(arrHour, arrmin); setlayout(newgridlayout(1,4)); setbackground(color.white); dep.setfont(getfont()); dep.setbackground(getbackground()); add(new Label(no)); add(new Label(destination)); add(dep); add(comlabel); show(); //setvisible(true); public void delay(int min) { dep.ticka(min*60); arr.ticka(min*60); setcomment("ny avgångstid!" ); public void setcomment(string com) { comment=com; comlabel.settext(comment ); repaint(); //ritar om public String tostring() { return (no + " " + destination + " " + dep + " " + comment); Klassen TrainDemo Kap J5-14 class TrainDemo extends Frame { Train t1,t2,t3,t4; setforeground(color.black); pack(); show(); //setvisible(true); t1.delay(15); t2.setcomment("borda nu"); TrainDemo() { t1= new Train("401","Göteborg",9,04,11,49); t2= new Train("701", "Malmö", 9,13, 13, 12); t3= new Train("424","Sundsvall", 9,18,12,48); t4= new Train("436", "Gävle", 9,44,11,15); add(t1); add(t2); add(t3); add(t4); setlayout(newgridlayout(4,1,0,1)); public static void main(string[] arg ) { TrainDemo demo= new TrainDemo(); TextField. Kap J5-15 Inläsning av text kan göras med standardklassen TextField. medger att användaren kan ändra texten (jmf Label). placeras i ett fönster m h a add()-metoden. Några metoder är setcolumns(int n) ändra storlek settext(string t) visa text t String gettext() läs inskriven text setechochar(char ch) visa tecken som ch selectall() markera hela texten select(int no1, int no2) markera tecken i t o m j String getselectedtext() läs markerad text 5
Händelsestyrd programmering Kap J5-16 Ett typiskt enkelt GUI-program baseras på s k händelsestyrd programmering enligt följande: Programmet ritar upp fönster med innehåll etc. Programmet väntar på att användaren skall göra en inmatning. Användaren t ex matar in något och trycker på <enter>. Då genereras en s k händelse (event). Denna talar om för programmet vad som har hänt och programmet agerar utifrån detta. I Java måste speciella lyssnare (eventlistener) definieras som talar om för programmet när en viss händelse har inträffat. Det finns många olika slags lyssnare. enter-tryckning i TextField ActionEvent Fångas av lyssnare av typen ActionListener Enkelt händelsestyrt program Kap J5-17 import java. awt.*; import java. awt. event.*; pack(); special.addactionlistener(this); setvisible(true); class TrainDemoLyss extends Frame implements ActionListener { Train t1,t2,t3,t4; TextField special= new TextField(30); Label svar=new Label ("",Label.CENTER); TrainDemoLyss() { t1= new Train("401","Göteborg", 9,04,11,49); t2= new Train("701", "Malmö", 9,13, 13, 12); t3= new Train("424", "Sundsvall", 9,18,12,48); t4= new Train("436", "Gävle", 9,44, 11, 15); setlayout(new GridLayout(6,1,10,10)); setforeground(color. blue); add(svar); add(t1); add(t2); add(t3);add(t4); add(special); t1. delay(15); t2.setcomment("borda nu"); public static void main(string[] arg ) { TrainDemoLyss d= new TrainDemoLyss(); public void actionperformed (ActionEvent e) { //anropas när händelse inträffat if (e.getsource()==special) { System. out.println("i actev"); String namn= special.gettext (); svar.settext( namn ); Ett seriöst program Kap J5-18 import java.awt.event.*; import java.text.*; class V75Cost extends Frame implements ActionListener { TextField antl1 = new TextField("1",3); TextField antl2 = new TextField("1",3); TextField antl3 = new TextField("1",3); TextField antl4 = new TextField("1",3); Label antl5 = new Label(" 1"); Label antl6 = new Label(" 1"); Label antl7 = new Label(" 1"); Panel p = new Panel(); // övre halvan under rubriken Panel p2 = new Panel(); // mitten TextField radpris = new TextField("1.0",5); // mitten Label antrad = new Label(); // mitten Label cost = new Label("Kostnad ",Label.RIGHT); // undre halvan Label rub = new Label("V75-3 spikar ",Label.CENTER); // Rubrik V75Cost() {// Konstruktor rub.setfont(new Font ("Serif", Font.BOLD, 20)); setfont(new Font("Dialog", Font.PLAIN, 14)); // placera ut komponenterna i den övre panelen p.setlayout(new GridLayout (1,8)); // 1 rader 7 kolumner 6
Ett seriöst program, forts. Kap J5-19 V75Cost() {// Konstruktor rub.setfont(new Font ("Serif", Font.BOLD, 20)); setfont(new Font("Dialog", Font.PLAIN, 14)); // placera ut komponenterna i den övre panelen p.setlayout(new GridLayout (1,8)); // 1 rader 7 kolumner p.add(new Label("Lopp 1-7:", Label.RIGHT));p.add(antL1);p.add(antL2); p.add(antl3);p.add(antl4);p.add(antl5);p.add(antl6);p.add(antl7); // placera ut komponenterna i den nedre panelen p2.setlayout(new GridLayout (1,2)); // 1 rader 2 kolumn p2.add(radpris); p2.add(antrad); // placera ut fönstrets komponenter setlayout(newgridlayout(4,1)); // 4 rader 1 kolumn add(rub); add(p); add(p2); add(cost); cost.setalignment(label.center); pack(); // beräkna fönstrets storlek // ange vilken lyssnare som skall användas antl1.addactionlistener(this); antl2.addactionlistener(this); antl3.addactionlistener(this); antl4.addactionlistener(this); radpris.addactionlistener(this); setvisible(true); // visa fönstret Ett seriöst program, forts. Kap J5-20 public static void main (String[] arg) { V75Cost sys = new V75Cost(); public void actionperformed(actionevent e) { // lyssnare int ant1, ant2, ant3, ant4, antr; if (e.getsource()==antl1 e.getsource()==antl2 e.getsource()==antl3 e.getsource()==antl4 e.getsource()==radpris ) { // avläs de fem svarsrutorna ant1= Integer.parseInt(antL1.getText()); ant2= Integer.parseInt(antL2.getText()); ant3 = Integer.parseInt(antL3.getText());ant4= Integer.parseInt(antL4.getText()); double rpris = Double.valueOf(radpris.getText()).doubleValue(); antr= ant1*ant2*ant3*ant4; antrad.settext("antal rader: " + antr); double totpris = antr * rpris; // redigera resultattexten NumberFormat r = NumberFormat.getInstance(); r.setminimumfractiondigits(2); r.setmaximumfractiondigits(2); String s = "Kostnad:" + r.format(totpris); cost.settext(s); // visa nytt resultat Exekvering Kap J5-21 Om Button används i stället Button bu= new Button("Beräkna kostnad");... setlayout(new GridLayout(5,1)); // 5 rader 1 kolumn add(rub); add(p); add(p2); add(cost); add(bu);...... bu.addactionlistener(this);.. public void actionperformed(actionevent e) { if (e.getsource()==bu ) { 7
Layout Managers. Kap J5-22 En layout-manager arrangerar automatiskt en containers komponenter. Kommandot setlayout() associerar en layout-manager med en viss container. T ex setlayout(new FlowLayout()); 5 subklasser till LayoutManager, 5 olika strategier FlowLayout komponenterna placeras ut radvis från höger till vänster. GridLayout matrisuplacering BorderLayout Fönstret delas in i fem delar North,South,West,East,Center CardLayout kortutplacering, delvis dolda GridBagLayout Fönstret delas in i olika stora rutor Kap J5-23 8