javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

11 Grafiske standardkomponenter

Indhold:

Forudsættes af kapitel 13, Hændelser.

Kapitlet forudsætter kapitel 9, Grafiske programmer, og at du har adgang til et værktøj, der kan udvikle grafiske brugergrænseflader (f.eks. Borland JBuilder, Oracle JDeveloper, Netbeans eller Eclipse).

Når man skal lave en grafisk brugergrænseflade (eng.: GUI, graphical user interface), gøres det ofte ved at anvende standardkomponenter. Vi vil starte med at se på, hvordan det gøres i praksis med et værktøj.

11.1 Generering med et værktøj

Med moderne udviklingsværktøjer kan man udarbejde en grafisk brugergrænseflade ud fra standardkomponenter på ret kort tid og uden at skulle programmere ret meget selv.

Herunder er beskrevet, hvordan man gør i Borland JBuilder, med sideløbende forklaringer til udviklingsværktøjerne Oracle JDeveloper og Netbeans. Hvis du bruger et andet værktøj, må du prøve dig lidt frem. Ideerne er de samme og koden, der genereres, ligner også nogenlunde, men menuerne og knapperne varierer selvfølgelig noget.

I JBuilder/JDeveloper er det nemmest at tage en eksisterende klasse, der arver fra Frame eller Applet, f.eks. GrafiskVindue fra kapitel 9 (i Netbeans skal du oprette ny "GUI Form") .

Hvis du i stedet vil oprette en ny, så vælg 'New..' og Application eller Applet. Fjern pakkenavnet, skriv et navn på din klasse og klik 'Finish'. Definér evt. en paint()-metode, der tegner noget. I Netbeans/andre: Opret en ny frame eller applet.

  1. Gå over på Design-fanen (ved punkt 1 nederst). Den er delt op i en del, hvor du designer din brugergrænseflade til venstre og en tabel af egenskaber til højre (punkt 2).
    JDeveloper: Højreklik på GrafiskVindue.java og vælg 'UI Editor'.
    Netbeans: Gå over på fanen 'GUI Editing', hvis du ikke allerede står der.

  2. Her skal du først ændre layout fra '<default layout>' til 'null' (punkt 2 til højre; måske skal du klikke på den grå flade i designeren først).
    Netbeans: Højreklik på den grå flade og vælg 'Set Layout' og 'Null layout'.

  3. Nu kan du gå i gang med at lægge komponenter ind på grænsefladen.
    Vælg i første omgang at arbejde med AWT-komponenter (punkt 3).

  4. Vælg først en Label (det store A ved punkt 4) og klik på grænsefladen. Der dukker en etikette med en tekst op. På egenskabstabellen til højre kan du ændre dens variabelnavn (name øverst) til f.eks. labelHvadErDitNavn. Længere nede er egenskaben text, der bestemmer, hvad der skal stå på etiketten. Ret den til f.eks. "Hvad er dit navn?".

  5. Indsæt derefter et TextField (et indtastningsfelt - længere nede i listen).
    Ret variabelnavnet til textFieldNavn og teksten til f.eks. "Jacob".

Gå tilbage til Source-fanen. Nu ser kildeteksten nogenlunde således ud:

import java.awt.*;

public class GrafiskVindue extends Frame
{
  Label labelHvadErDitNavn = new Label();
  TextField textFieldNavn = new TextField();

  public void paint(Graphics g)
  {
    // Herunder referer g til et Graphics-objekt man kan tegne med.
    g.drawLine(0,0,50,50);

    g.fillOval(5,20,300,30);

    g.setColor(Color.GREEN);

    g.drawString("Hej grafiske verden!",100,40);
  }

  public GrafiskVindue() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    labelHvadErDitNavn.setText("Hvad er dit navn?");
    labelHvadErDitNavn.setBounds(new Rectangle(15, 69, 108, 15));
    textFieldNavn.setText("Jacob");
    textFieldNavn.setBounds(new Rectangle(141, 61, 112, 29));
    this.setLayout(null);
    this.add(textFieldNavn, null);
    this.add(labelHvadErDitNavn, null);
  }
}

De to objekter, vi satte på i designeren, er erklæret og oprettet øverst uden for metoderne:

  Label labelHvadErDitNavn = new Label();
  TextField textFieldNavn = new TextField();

Nedenunder står vores gamle paint() uændret. Herunder er der oprettet en konstruktør, der kalder metoden jbInit(). I Netbeans hedder metoden initComponents().

Den andet kode, 'try{ ... } catch (Exception e) {...}' er beregnet til at håndtere undtagelser og vil blive forklaret i kapitel 14, Undtagelser.

I metoden jbInit() nedenunder lægger værktøjet koden til at initialisere de grafiske komponenter. Man ser her, hvordan både Label og TextField har metoden setText() og at begge objekter får kaldt denne metode (svarende til, at vi ændrede egenskaben text).

    labelHvadErDitNavn.setText("Hvad er dit navn?");
    textFieldNavn.setText("Jacob");

De andre kommandoer i jbInit() sørger for at placere komponenterne korrekt i vinduet.

"Design"- og "Source"-fanen er to måder at se programmet på og man kan frit skifte mellem dem. Laver man en designændring, vil det blive afspejlet i koden i jbInit(). Ændrer man i koden, vil designet ændre sig (i Netbeans er koden beskyttet mod ændringer). Tilføjer du din egen kode til denne metode, så sørg for, at det ligner værktøjets egen kode, ellers kan værktøjet have svært ved at opretholde sammenhængen mellem kode og design.

11.1.1 Interaktive programmer

Lad os nu tilføje en knap og et indtastningsfelt på flere linjer (TextArea). Jeg kalder dem for buttonOpdater og textAreaHilsen. Knappen skal selvfølgelig gøre noget. Fra Design-fanen, dobbeltklik på knappen, og vupti! Der genereres automatisk en metode til at håndtere et klik (og pakken java.awt.event bliver importeret):

  void buttonOpdater_actionPerformed(ActionEvent e) {

  }

Hvis du kigger i jbInit(), kan du se, at JBuilder har indsat følgende kode:

    buttonOpdater.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        buttonOpdater_actionPerformed(e);
      }
    });

Det er disse linjer, der sørger for at "lytte efter hændelser" på knappen, sådan at når man klikker på buttonOpdater, så kaldes metoden buttonOpdater_actionPerformed(). Det vil vi komme tilbage til i kapitel 13, Hændelser.

Nu kan du indsætte kode, der udfører en handling. Skriv f.eks. noget ud til systemoutput:

  void buttonOpdater_actionPerformed(ActionEvent e) {
    System.out.println("Opdater!");
  }

Vi kunne også lave noget sjovere, f.eks. læse den indtastede tekst fra textFieldNavn og skrive den i textAreaHilsen. JBuilder har lavet koden, der sætter teksterne for os og ved at studere den kan man få en ide til, hvordan det skal gøres:

    String navn = textFieldNavn.getText();     // aflæs navnet

    textAreaHilsen.setText("Hej kære "+navn);  // sæt navnet

Her har vi tastet "Jacob Nordfalk" ind og trykket på "opdater!"-knappen (paint() er ændret til også at tegne navnet 5 gange).

Der er altså to måder at arbejde med grafik på:

Her kommer det fulde eksempel.

import java.awt.*;
import java.awt.event.*;

public class GrafiskVindue extends Frame
{
  Label labelHvadErDitNavn = new Label();
  TextField textFieldNavn = new TextField();
  Button buttonOpdater = new Button();
  TextArea textAreaHilsen = new TextArea();

  public void paint(Graphics g)
  {
    g.drawLine(0,0,50,50);
    g.fillOval(5,20,300,30);

    g.setColor(Color.GREEN);
    String navn = textFieldNavn.getText();
    for (int i=0; i<50; i=i+10)
      g.drawString("Hej "+navn+" !",100+i,30+i);
  }


  // Udviklingsværktøj definerer gerne en separat metode hvor de 
  // initialiserer komponenterne. I JBuilder og JDeveloper hedder
  // den jbInit(), mens den hedder initComponents() i Betbeans.
  // Initialiseringen kunne dog lige så godt ligge direkte her i konstruktøren

  public GrafiskVindue() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }


  // Udviklingsværktøjets initialisering af komponenter.
  // Ændr med varsomhed, ellers kan værktøjet ikke genkende "sin" kode.

  private void jbInit() throws Exception {
    labelHvadErDitNavn.setText("Hvad er dit navn?");
    labelHvadErDitNavn.setBounds(new Rectangle(15, 69, 108, 15));
    textFieldNavn.setText("Jacob");
    textFieldNavn.setBounds(new Rectangle(129, 61, 95, 29));
    buttonOpdater.setLabel("opdater!");
    buttonOpdater.setBounds(new Rectangle(231, 60, 91, 32));
    buttonOpdater.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        buttonOpdater_actionPerformed(e);
      }
    });
    textAreaHilsen.setText("Her kommer en tekst...");
    textAreaHilsen.setBounds(new Rectangle(6, 102, 316, 78));
    this.setLayout(null);
    this.add(labelHvadErDitNavn, null);
    this.add(textAreaHilsen, null);
    this.add(buttonOpdater, null);
    this.add(textFieldNavn, null);
  }

  void buttonOpdater_actionPerformed(ActionEvent e) {
    String navn = textFieldNavn.getText();
    System.out.println("Opdater! navn="+navn);
    textAreaHilsen.setText("Hej kære "+navn);
    repaint(); // gentegn vinduet
  }
}

11.2 Grafiske komponenter

Grafiske komponenter er objekter, der bruges som en synlig del af en grafisk brugergrænseflade, f.eks. knapper, valglister, indtastningsfelter, etiketter.

Alle komponenter arver fra Component-klassen og har derfor dennes træk til fælles:

Metoderne setForeground(Color c) og setBackground(Color c) sætter hhv. forgrundsfarven og baggrundsfarven for komponenten, svarende til egenskaberne foreground og background. Egenskaberne kan aflæses med getForeground() og getBackground().

En anden egenskab er font, der bestemmer skrifttypen. I tråd med de andre egenskaber sættes den med setFont(Font f) og aflæses med getFont().

Dette kan sammenfattes i en tabel over egenskaber, der er fælles for alle komponenter.

Egenskab

Type

Sættes med

Læses med

foreground

Color

setForeground(Color c)

getForeground()

background

Color

setBackground(Color c)

getBackground()

font

Font

setFont(Font f)

getFont()

visible

boolean

setVisible(boolean synlig)

isVisible()

Nedenfor vil de mest almindelige komponenter blive beskrevet. Kun de nye egenskaber er beskrevet.

11.2.1 Button


En trykknap. Egenskaben label angiver, hvad der står på knappen.

Egenskab

Type

Sættes med

Læses med

label

String

setLabel(String t)

getLabel()

11.2.2 Checkbox


Et afkrydsningsfelt. Kan både bruges til flueben og til radioknapper. Hvis man skal have radioknapper (der gensidigt udelukker hinanden), skal objekterne knyttes sammen af et CheckboxGroup-objekt.

label angiver, hvad der står ved feltet. state angiver, om feltet er afkrydset.

Egenskab

Type

Sættes med

Læses med

label

String

setLabel(String t)

getLabel()

state

boolean

setState (boolean afkrydset)

getState()

11.2.3 Choice


En valgliste. Brug metoden addItem(String elementnavn) til at tilføje indgange.

Med getSelectedItem() undersøger man, hvad brugeren har valgt.

11.2.4 TextField


Et indtastningsfelt på en linje. Egenskaben text angiver, hvad der står i feltet.

Mindre brugt er: columns angiver, hvor bredt feltet skal være.

editable angiver, om brugeren kan redigere teksten i indtastningsfeltet.

echoChar bruges til felter, der skal skjule det indtastede, typisk adgangskoder.

Sæt f.eks. echoChar til '*' for at få vist stjerner i stedet for det indtastede.

Egenskab

Type

Sættes med

Læses med

text

String

setText(String t)

getText()

editable

boolean

setEditable(boolean rediger)

isEditable()

columns

int

setColumns(int bredde)

getColumns()

echoChar

char

setEchoChar(char tegn)

getEchoChar()

11.2.5 TextArea


Et indtastningsfelt på flere linjer.

Egenskaberne text, rows og columns angiver, hvad der står i feltet, hhv. bredde og højde.

Egenskab

Type

Sættes med

Læses med

text

String

setText(String t)

getText()

editable

boolean

setEditable(boolean rediger)

isEditable()

columns

int

setColumns(int bredde)

getColumns()

rows

int

setRows(int højde)

getRows()

TextField og TextArea har en del egenskaber til fælles og disse fællestræk ligger i superklassen TextComponent (se klassediagrammet).

11.2.6 Label


En etikette, der viser en tekst (som brugeren ikke kan redigere i).

Egenskaben text angiver, hvad der står i feltet.

Egenskab

Type

Sættes med

Læses med

text

String

setText(String t)

GetText()

11.2.7 List


En menu, hvor flere af indgangene kan ses samtidigt og hvor man kan vælge en eller flere elementer. Brug metoden add(String elementnavn) til at tilføje indgange.

Med isIndexSelected(int index) undersøger man, om en indgang er valgt.

Egenskaberne rows og multipleMode angiver, hvad højden er og om man kan vælge flere indgange samtidigt.

Egenskab

Type

Sættes med

Læses med

rows

int

setRows(int højde)

getRows()

multipleMode

boolean

setMultipleMode(boolean m)

getMultipleMode()

11.2.8 Canvas

Et tegne-område. Canvas er en anelse besværlig, idet man skal nedarve fra klassen og implementere paint(Graphics g) for at kunne tegne noget.

En lettere (men ikke nødvendigvis altid smartere) måde er som sagt at definere paint()-metoden direkte i appletten/vinduet, som vi har gjort tidligere.

11.3 Eksempel

Herunder et eksempel (genereret med JBuilder), der viser komponenterne omtalt i forrige afsnit.

På billedet ses det resulterende skærmbillede under Windows (sidst i kapitlet ses, hvordan det ser ud under Linux).

public class VisGrafiskeKomponenter
{
  public static void main(String[] arg)
  {
    GrafiskeKomponenter vindue = new GrafiskeKomponenter();
    vindue.setSize(700,300);
    vindue.setVisible(true);
  }
}
import java.awt.*;

public class GrafiskeKomponenter extends Frame
{
  // opret alle komponenterne og husk dem i nogle objektvariabler
  Button button1 = new Button();
  Checkbox checkbox1 = new Checkbox();
  Checkbox checkbox2 = new Checkbox();
  Checkbox checkbox3 = new Checkbox();
  Checkbox checkbox4 = new Checkbox();
  Checkbox checkbox5 = new Checkbox();
  CheckboxGroup checkboxGroup1 = new CheckboxGroup();
  Choice choice1 = new Choice();
  TextField textField1 = new TextField();
  TextArea textArea1 = new TextArea();
  List list1 = new List();
  Label label1 = new Label();

  FlowLayout flowLayout1 = new FlowLayout(); // layout-manager (se senere)

  public GrafiskeKomponenter() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    button1.setLabel("OK");

    checkbox1.setLabel("En");     // Sæt afkrydsningsfelternes navne
    checkbox2.setLabel("To");
    checkbox3.setLabel("Tre");

    checkbox4.setLabel("Radio1"); // Sæt radioknappernes navne og
    checkbox5.setLabel("Radio2");
    checkbox4.setCheckboxGroup(checkboxGroup1); // gruppen de tilhører
    checkbox5.setCheckboxGroup(checkboxGroup1);
    checkboxGroup1.setSelectedCheckbox(checkbox4);

    choice1.add("Choice Rød");
    choice1.add("Choice Grøn");
    choice1.add("Choice Blå");

    textField1.setColumns(10);
    textField1.setText("Et TextField");

    textArea1.setColumns(15);
    textArea1.setRows(5);
    textArea1.setText("Et TextArea");

    label1.setText("En Label");

    list1.add("List Rød");
    list1.add("List Grøn");
    list1.add("List Blå");

    this.setLayout(flowLayout1);// sæt layout-manager (se senere)

    this.add(button1, null);    // til sidst skal komponenterne føjes
    this.add(checkbox1, null);  // til containeren (se senere)
    this.add(checkbox2, null);
    this.add(checkbox3, null);
    this.add(checkbox4, null);
    this.add(checkbox5, null);
    this.add(choice1, null);
    this.add(textArea1, null);
    this.add(textField1, null);
    this.add(label1, null);
    this.add(list1, null);
  }
}

11.4 Containere

En container er beregnet til at indeholde komponenter. De arver alle fra Container-klassen og har alle en såkaldt layout-manager tilknyttet, der bestemmer, hvor og med hvilken størrelse komponenterne skal vises i containeren.

For at en komponent bliver vist, skal den tilføjes en container. I eksemplet ovenfor er vinduet den container, komponenterne bliver tilføjet og derfor står der sidst i initialiseringen:

    this.add(button1, null);

11.4.1 Panel

Et panel er den simpleste og oftest brugte container. Den indeholder simpelt hen komponenterne (i henhold til layout-manageren).

11.4.2 Applet

En applet er et udvidet panel, der er beregnet til at blive vist i en netlæser. Læs kapitel 10, Appletter for mere information om denne klasse.

11.4.3 Window

Window repræsenterer et bart vindue uden en titellinje eller lukkeknap øverst. Det bruges meget sjældent direkte. Man bruger i stedet arvingerne Frame og Dialog.

11.4.4 Frame

En Frame er den simpleste og oftest brugte måde at definere et "normalt" vindue med en titel. Læs kapitel 9, Grafiske programmer for mere information om denne klasse.

11.4.5 Dialog

Dialog bruges til dialog-bokse, vinduer, der dukker op med et eller andet spørgsmål, som skal besvares, før man kan gå videre. Egenskaben modal angiver, om dialog-boksen er modal, dvs. om man skal lukke den, før man kan få adgang til ejer-vinduet. Den sættes med setModal(boolean m) og aflæses med isModal(). Er vinduet modalt vil et kald til setVisible(true) vente, indtil brugeren har udfyldt og lukket dialog-boksen igen.

11.5 Relationer mellem klasserne

Herunder ses klassediagrammet for nogle af komponenterne og containerne.

De hule pile ( ) repræsenterer er-en-relationer (dvs. nedarvning). De andre pile ( ), mellem Container og Component og mellem CheckboxGroup og Checkbox, repræsenterer har-relationer (dvs. at et objekt har en reference til et andet objekt, evt. "ejer" objektet).

Bemærk, at Container selv arver fra Component, så en Container kan i sig selv bruges som en komponent. Det er relevant for Panel og ScrollPane, der er beregnet til at blive placeret inden i andre containere.

11.6 Layout-managere

En layout-manager styrer layoutet af komponenterne på et Panel eller en anden container. Alle containere har egenskaben layout, der kan sættes med metoden setLayout(Layout l).

11.6.1 Ingen styring (null-layout)

I udviklingsfasen er det mest bekvemt at sætte layout-manageren til null, der tillader udvikleren at sætte komponenterne, som han vil på en hvilken som helst (x,y)-position og med en hvilken som helst højde og bredde. Koden ser således ud:

    this.setLayout(null);                              // sæt null-layout
    this.add(button1, null);                           // tilføj knap
    button1.setBounds(new Rectangle(231, 60, 91, 32)); // sæt position/størrelse

null-layout tager slet ikke højde for vinduets størrelse, så hvis vinduet bliver for lille, vil nogle af komponenterne ikke blive vist. Når programmet er ved at være færdigt, bør man derfor ændre programmet til at bruge en layout-manager, der kan styre komponenternes størrelse og indbyrdes placering ud fra deres behov.

11.6.2 FlowLayout

FlowLayout placerer komponenterne ligesom bogstaver: Øverst fra venstre mod højre og på en ny linje nedenunder, når der ikke er mere plads.

Angiver man ikke nogen layout-manager i et panel/applet, vil FlowLayout blive brugt.

I eksemplet GrafiskeKomponenter ovenfor blev FlowLayout brugt:

    this.setLayout(new FlowLayout());
    this.add(button1, null);

11.6.3 BorderLayout

BorderLayout tager højde for vinduets størrelse og tilpasser komponenternes størrelse efter den tilgængelige plads. Komponenterne kan placeres på 5 mulige positioner, nemlig NORTH, SOUTH, EAST, WEST og CENTER.

Den mest almindelige måde at lave det grafiske layout af et skærmbillede er med BorderLayout. I de områder, hvor man ønsker at placere flere komponenter, sætter man først et Panel og komponenterne tilføjes så panelet.

Angiver man ikke nogen layout-manager i et vindue, vil BorderLayout blive brugt (i eksemplet nedenfor kunne de to linjer omkring BorderLayout strengt taget fjernes).

import java.awt.*;

public class VindueMedBorderLayout extends Frame
{
  Button button1 = new Button();
  Button button2 = new Button();
  Button button3 = new Button();
  Button button4 = new Button();
  Button button5 = new Button();

  BorderLayout borderLayout1 = new BorderLayout();

  public VindueMedBorderLayout() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    button1.setLabel("NORTH");
    button2.setLabel("SOUTH");
    button3.setLabel("EAST");
    button4.setLabel("WEST");
    button5.setLabel("CENTER");

    this.setLayout(borderLayout1);

    this.add(button1, BorderLayout.NORTH);
    this.add(button2, BorderLayout.SOUTH);
    this.add(button3, BorderLayout.EAST);
    this.add(button4, BorderLayout.WEST);
    this.add(button5, BorderLayout.CENTER);
  }
}

Man sætter altså først layoutet ved at kalde setLayout() med et BorderLayout-objekt. Derefter kan add() kaldes med komponenterne og deres placering på borderlayoutet.

Bemærk, at når man bruger en layout-manager, bør man lade den afgøre vinduets størrelse ud fra komponenternes behov, ved at kalde pack() i stedet for setSize() på vinduet. Denne metode pakker komponenterne i vinduet optimalt og sætter vinduesstørrelsen passende.

public class VisVindueMedBorderLayout
{
  public static void main(String[] arg)
  {
    VindueMedBorderLayout vindue = new VindueMedBorderLayout();
    vindue.pack();// sætter en rimelig vinduesstørrelse (i stedet for setSize())
    vindue.setVisible(true);
  }
}

11.6.4 GridBagLayout

En anden måde at lave layout er med GridBagLayout, som lægger komponenterne efter et usynligt gitter. Hver komponent kan fylde en eller flere celler i højden eller bredden.

import java.awt.*;

public class VindueMedGridBagLayout extends Frame
{
  GridBagLayout gridBagLayout1 = new GridBagLayout();
  Button   knap1 = new Button();
  Button   knap2 = new Button();
  Button   knap3 = new Button();
  Button   knap4 = new Button();
  Button   knap5 = new Button();
  Checkbox chkHø = new Checkbox();
  Checkbox chkVe = new Checkbox();
  Checkbox chkCe = new Checkbox();
  TextArea tekst = new TextArea();

  public VindueMedGridBagLayout() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    knap1.setLabel("knap1 (på 3x1 celler)");
    knap2.setLabel("knap2 (1x2)");
    knap3.setLabel("knap3 (på 1x1 celle)");
    knap4.setLabel("knap4 (1x1)");
    knap5.setLabel("knap5 (1x1)");
    chkHø.setLabel("Højre");
    chkVe.setLabel("Venstre");
    chkCe.setLabel("Centreret");
    tekst.setColumns(15);
    tekst.setRows(2);
    tekst.setText("Tekstfelt (3x3 celler)");

    this.setLayout(gridBagLayout1);

    // til sidst skal komponenterne føjes til containeren
    this.add(knap1, new GridBagConstraints(0, 0, 3, 1, 0.0, 0.0, 
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
    this.add(knap2, new GridBagConstraints(3, 0, 1, 2, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
    this.add(knap3, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
    this.add(knap4, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
    this.add(knap5, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
    this.add(chkHø, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
    GridBagConstraints.EAST,  GridBagConstraints.NONE,new Insets(0,0,0,0),0,0));
    this.add(chkVe, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,
    GridBagConstraints.WEST,  GridBagConstraints.NONE,new Insets(0,0,0,0),0,0));
    this.add(chkCe, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.NONE,new Insets(0,0,0,0),0,0));
    this.add(tekst, new GridBagConstraints(1, 2, 3, 3, 0.0, 0.0,
    GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0));
  }
}

Når en komponent tilføjes, angives i et GridBagConstraints-objekt:

  • Komponentens position (cellekolonne og -række)

  • Komponentens spændvidde i højde og bredde

  • Vægt i højde og bredde (komponenter med størst værdi får mest af eventuel overskydende plads)

  • Justering i tilfælde af overskydende plads (CENTER, EAST, WEST, NORTHEAST, ...)

  • Om komponenten skal strækkes til at fylde overskydende plads (BOTH, NONE, HORIZONTAL, VERTICAL)

  • Til sidst nogle parametre til indsættelse af ekstra plads.

Her er koden, der viser vinduet.

public class VisVindueMedGridBagLayout
{
  public static void main(String[] arg)
  {
    VindueMedGridBagLayout vindue = new VindueMedGridBagLayout();
    vindue.pack();
    vindue.setVisible(true);
  }
}

11.7 Menuer

Menuer med rullegardiner er relativt enkle at lave. Herunder ses brudstykkerne af den kode, der skal til, for at lave menuerne vist på figuren til højre.

  MenuBar menuBar1 = new MenuBar();

  Menu     menuFil         = new Menu();
  MenuItem menuItemÅbn     = new MenuItem();
  MenuItem menuItemAfslut  = new MenuItem();

  Menu     menuHjælp       = new Menu();

  ... i f.eks jbInit() kunne der stå:

    this.setMenuBar(menuBar1);

    menuFil.setLabel("Fil");
    menuItemÅbn.setLabel("Åbn");
    menuItemAfslut.setLabel("Afslut");
    menuFil.add(menuItemÅbn);
    menuFil.add(menuItemAfslut);
    menuBar1.add(menuFil);

    menuHjælp.setLabel("Hjælp");
    menuBar1.add(menuHjælp);

For at fange, når brugeren vælger et menupunkt, skal man lytte efter actionPerformed, ligesom med Button-klassen (det blev diskuteret i afsnit 11.1.1).

11.8 Test dig selv

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

11.9 Resumé

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

11.10 Avanceret

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

11.10.1 AWT-komponenter på andre platforme

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

11.10.2 Swing-komponenter

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.
javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (82% af værket).

Ønsker du at se de sidste 18% af dette værk (199974 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.