Kapitel 1 Grundlæggende Swing

Kapitel 1 : Generelt om Swing

 

Swing er oprindeligt en del af Java Foundation Classes (JFC), som Sun udviklede som en tilføjelse til Java-standarden, svarende til det Standard Template Library (STL), der kendes fra C++. Swing er den grafiske den af JFC, som udvider Abstract Window Toolkit (AWT), der altid har været en del af Java-standarden.

 

Som nævnt er JFC – og dermed Swing – oprindeligt tænkt som en tilføjelse til Java-standarden, og det er derfor muligt at downloade JFC-klasserne som en separat udvidelse til Java Development Kit 1.1. Hvis man opgraderer sin Internet-browsers Java Virtual Machine med Java Activator, installeres understøttelse af JFC automatisk. Bruger man Java Development Kit version 1.2, er Swing en integreret del af API’et. Klasserne hørende til Swing ligger i pakker, der starter med java.awt.swing.

Du læser en gammel bog

Den bog, du læser her, er fra 1998, og mange ting kan have ændret sig siden da.
Vi håber, at du stadig kan finde relevant information i den.
Hvis du vil læse aktuelle oplysninger om de avancerede dele af Java, anbefaler vi
bogen Core Java – Advanced Features

Swing kontra AWT

 

Der er store forskelle på Swing og AWT. AWT bærer præg af at være fra første version af Java – sproget har udviklet sig meget siden, mens den største opgradering i AWT har været skift af event-model fra version 1.0 til 1.1. Derudover er AWT’s udseende – look and feel – specielt udviklet til Java med det formål at være platformsuafhængigt. Det betyder både, at programmer skrevet i Java ser væsentligt anderledes ud, end det brugere kender fra programmer, der er skrevet direkte til det pågældende operativsystem, men også at man har været nødt til at lave en brugergrænseflade, der nemt kunne implementeres på de fleste platforme. Derfor har AWT manglet mange af de avancerede komponenter, som for eksempel Win32-programmører, har vænnet sig til.

 

Swing er også platformsuafhængig, men det er muligt at designe brugergrænseflader, der har samme udseende, som et bestemt operativsystem. Hvilke operativsystem, brugergrænsen skal tilpasse sig, kan bestemmes dynamisk, og man kan således ved programstart lave en kontrol af, hvilket operativsystem programmet afvikles under, og så automatisk få brugergrænsefladen tilpasset hertil.

 

Vinduer

 

I AWT bruger man klassen java.awt.Frame til at lave et vindue. Hvis man vil bruge Swing, bruger man i stedet java.awt.swing.JFrame. JFrame adskiller sig fra Frame ved at have understøttelse for en Swing-menulinie og ved at være organiseret ved hjælp af et content pane. Det har indflydelse på, hvordan man håndterer elementer i vinduet. Bruger man en almindelig AWT Frame, kan man tilføje en knap ved at skrive

 

 

 

frame.add(knap);

 

mens man i Swing skal skrive

 

frame.getContentPane().add(knap);

 

Det samme gælder andre handlinger, som for eksempel valg af layout manager og fjernelse af elementer. getContentPane vil altid returnere en værdi, der ikke er null. Hvis man forsøger at sætte et vindues content pane til at være null, vil man få en exception.

 

Hvis andet ikke er angivet, vil et vindues content pane have border layout som layout manager.

 

Ovenstående gælder også for den anden Java-klasse, der håndterer vinduer – Dialog. I Swing-terminologi hedder den JDialog. JDialog skal bruges til at lave brugerdefinerede dialogbokse. Man kan også vælge at bruge en af de, der er defineret i JOptionPane. JOptionPane vil blive beskrevet i detaljer senere i kapitlet.

 

public class JFrame extends Frame implements WindowConstants, Accesible

{

 

public java.awt.Component getComponentAt (int, int);

public java.awt.Component getComponentAt (java.awt.Point);

public synchronized java.awt.dnd.DropTarget getDropTarget ();

public synchronized void setDropTarget (java.awt.dnd.DropTarget);

public void setSize (int, int);

public void setSize (java.awt.Dimension);

public void show ();

public void show (boolean);

public java.awt.Container getContentPane ();

public int getDefaultCloseOperation ();

public void setDefaultCloseOperation (int);

}

 

public class JDialog extends Dialog implements WindowConstants, Accessible

{

public JDialog();

public JDialog(java.awt.Frame);

public JDialog(java.awt.Frame, java.lang.String);

public JDialog(java.awt.Frame, java.lang.String, boolean);

public JDialog(java.awt.Frame, boolean);

 

public java.awt.Component getComponentAt (int, int);

public java.awt.Component getComponentAt (java.awt.Point);

public synchronized java.awt.dnd.DropTarget getDropTarget ();

 

 

public synchronized void setDropTarget (java.awt.dnd.DropTarget);

public void setSize (int, int);

public void setSize (java.awt.Dimension);

public void show ();

public void show (boolean);

public java.awt.Container getContentPane ();

public int getDefaultCloseOperation ();

public void setDefaultCloseOperation (int);

}

 

Som det ses af ovenstående specifikation er en del af metoderne i de to vinduesklasser nedarvet fra henholdsvis java.awt.Frame og java.awt.Dialog. I det omfang deres semantik ikke afviger væsentligt fra superklassernes, vil de ikke blive beskrevet her. Det skal dog nævnes, at alle de metoder, der bruges til at tilføje og redigere elementer i vinduet i stedet skal kaldes på vinduets content pane. Bliver de kaldt på selve vinduet, resulterer kaldet i en <<kode>> Error <</kode>>, hvis rootPaneChecking er sat til true.

 

Metoderne setDefaultCloseOperation og getDefaultCloseOperation bruges til henholdsvis at sætte og læse, hvilken handling, der skal udføres, når brugeren vælger at lukke vinduet. I Windows 95 sker dette enten ved at klikke på krydset i øverste højre hjørne eller ved at vælge Luk fra systemmenuen. Tre forskellige handlinger kan udføres, og hver af disse har tilknyttet en konstant int-værdi, der definerer den. Værdierne og deres tilknyttede handlinger er:

 

  • DO_NOTHING_ON_CLOSE
    Udfører ingen handlinger, når vinduet lukkes. Det er op til programmet selv at håndtere handlingen ved hjælp af en WindowListener.
  • HIDE_ON_CLOSE
    Skjuler automatisk vinduet, når brugeren vælger at lukke det. Alle tilknyttede WindowListener-objekter kaldes, inden vinduet skjules.
  • DISPOSE_ON_CLOSE
    Skjuler og fjerner automatisk vinduet, når brugern vælger at lukke det. Inden da udføres alle tilknyttede WindowListener-objekter.

 

Angives andet ikke, bliver defaultCloseOperation sat til HIDE_ON_CLOSE

 

Standarddialogbokse

 

Ved hjælp af JDialog og JFrame-klasserne er det muligt at designe vinduer og dialogbokse præcis som man vil have dem. Ofte har man imidlertid bare brug for at give brugeren en besked, eller stille vedkommende et simpelt spørgsmål. Til disse formål er det overdrevet at skulle designe en dialogboks fra bunden – til dette formål har Swing en række standarddialogbokse, der er nemme at anvende.

 

Til dette formål bruges klassen JoptionPane, der har følgende specifikation:

public class JOptionPane extends Jcomponent

{

public JOptionPane();

 

public JOptionPane(java.lang.Object);

public JOptionPane(java.lang.Object, int);

public JOptionPane(java.lang.Object, int, int);

public JOptionPane(java.lang.Object, int, int, java.awt.swing.Icon);

public JOptionPane(java.lang.Object, int, int, java.awt.swing.Icon, Ljava.lang.Object[]);

public JOptionPane(java.lang.Object, int, int, java.awt.swing.Icon, java.lang.Object[], java.lang.Object);

 

public static int showConfirmDialog (java.awt.Component, java.lang.Object);

public static int showConfirmDialog (java.awt.Component, java.lang.Object,   java.lang.String, int);

public static int showConfirmDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int);

public static int showConfirmDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int, java.awt.swing.Icon);

public static java.lang.String showInputDialog (java.awt.Component, java.lang.Object);

public static java.lang.String showInputDialog (java.awt.Component, java.lang.Object, java.lang.String, int);

public static java.lang.Object showInputDialog (java.awt.Component, java.lang.Object, java.lang.String, int, java.awt.swing.Icon,   java.lang.Object[], java.lang.Object);

public static java.lang.String showInputDialog (java.lang.Object);

public static int showInternalConfirmDialog (java.awt.Component, java.lang.Object);

public static int showInternalConfirmDialog (java.awt.Component,  java.lang.Object, java.lang.String, int);

public static int showInternalConfirmDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int);

public static int showInternalConfirmDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int, java.awt.swing.Icon);

public static java.lang.String showInternalInputDialog (java.awt.Component, java.lang.Object);

public static java.lang.String showInternalInputDialog (java.awt.Component, java.lang.Object, java.lang.String, int);

public static java.lang.Object showInternalInputDialog (java.awt.Component, java.lang.Object, java.lang.String, int, java.awt.swing.Icon,   java.lang.Object[], java.lang.Object);

public static void showInternalMessageDialog (java.awt.Component, java.lang.Object);

 

 

public static void showInternalMessageDialog (java.awt.Component, java.lang.Object, java.lang.String, int);

public static void showInternalMessageDialog (java.awt.Component, java.lang.Object, java.lang.String, int, java.awt.swing.Icon);

public static int showInternalOptionDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int, java.awt.swing.Icon, java.lang.Object[], java.lang.Object);

public static void showMessageDialog (java.awt.Component, java.lang.Object);

public static void showMessageDialog (java.awt.Component, java.lang.Object,  java.lang.String, int);

public static void showMessageDialog (java.awt.Component, java.lang.Object, java.lang.String, int, java.awt.swing.Icon);

public static int showOptionDialog (java.awt.Component, java.lang.Object, java.lang.String, int, int, java.awt.swing.Icon, [Ljava.lang.Object;, java.lang.Object);

}

 

Umiddelbart ser JOptionPane-klassen relativt kompliceret ud, men faktisk kan dens funktionalitet begrænses til fire statiske funktioner:

 

  • showMessageDialog
    Giver brugeren en besked.
  • showInputDialog
    Beder brugeren indtaste et svar.
  • showConfirmDialog
    Stiller et spørgsmål, der kræver bekræftelse – for eksempel med ja/nej/annullér.
  • showOptionDialog
    En kombination af de tre ovenstående.

 

Disse funktioner findes i et utal af afskygninger. Som det ses findes de også i showInternalXXX. Disse bruger en intern ramme – JInternalFrame – til at vise dialogboksen. Derudover findes der en række overloadede funktioner, der gør det muligt at angive forskellige former for parametre. Dette afsnit vil beskrive de generelle funktioner og vise, hvordan de præsenteres med det almindelige Java look and feel. Skærmbillederne er fra en Windows 95 Java Virtuel Maskine.

 

Linien

 

JOptionPane.showMessageDialog(null, “Der er af ukendte årsager opstået en fejl”, “Fejl”, JOptionPane.ERROR_MESSAGE);

 

viser en dialogboks som i figur 1.1. Metodens første parameter angiver, hvilket vindue, der ejer dialogboksen. Har dialogboksen ingen ejer – som i dette tilfælde – kan ejeren angives med null. Den næste parameter er den

 

tekst, der skal vises i dialogboksen. Denne tekst efterfølges af titlen. Den sidste parameter angiver, hvilken type dialogboks der skal vises. Forskellige typer dialogbokse er ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE og PLAIN_MESSAGE. Dialogboksens type angiver hvilket ikon, der skal vises i dialogboksen.

 

 

Fig. 1.1 ­– en MessageDialog.

 

Har man brug for input fra brugeren, skal man som nævnt anvende showInputDialog. Det kan for eksempel gøres således:

 

String navn = JOptionPane.showInputDialog(null, “Hvad er dit navn”, “Personlig information”, JOptionPane.QUESTION_MESSAGE);

 

Denne linie vil vise en dialogboks svarende til den i figur 1.2.

 

Som det ses, returnerer showInputDialog en streng. Det er den tekst, brugeren indtaster. Parametrene til funktionen er de samme som ved showMessageDialog.

 

 

Figur 1.2 – en InputDialog.

 

Hvis man vil stille brugeren et mindre komplekst spørgsmål, kan man nøjes med en dialogboks, der har en knap pr. svarmulighed. Denne funktionalitet stilles til rådighed af showConfirmDialog. Den kan bruges således:

 

int valg = JOptionPane.showConfirmDialog(null, “Er du sikker på, at du vil formatere C:”, “Formatering”, JOptionPane.YES_NO_OPTION);

 

Som det ses, returnerer showConfirmDialog en int-værdi. Denne værdi angiver, hvilken knap brugeren har valgt. Følgende statiske variable i JoptionPane bruges til at angive valget:

 

  • CANCEL_OPTION
  • CLOSED_OPTION
  • NO_OPTION
  • OK_OPTION
  • YES_OPTION

 

 

Pånær CLOSED_OPTION, bør returværdierne betydning være åbenlys. CLOSED_OPTION bruges, når brugeren – i stedet for at klikke på en knap – vælger at lukke dialogboksen. Som regel skal denne returværdi behandles som CANCEL_OPTION eller NO_OPTION. Parametrene til showConfirmDialog svarer til parametrene til de tidligere gennemgåede metoder. Dog skal det nævnes, at den sidste parameter ikke angiver dialogboksens ikon, men hvilke knapper der skal vises. Her er mulighederne DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION og OK_CANCEL_OPTION.

 

 

Fig. 1.3 – en ConfirmDialog.

 

Hvis man gerne vil bruge en standarddialogboks, men ikke kan nøjes med de, der er blevet gennemgået indtil nu, kan man måske bruge en OptionDialog. showOptionDialog er lidt mere kompliceret at bruge end de øvrige metoder. Som det ses af metoden signatur, der er vist tidligere i kapitlet, tager showOptionDialog 8 parametre. Den første parameter er som vanligt dialogboksens ejer. Den næste er den besked, der skal vises, efterfulgt at dialogboksens titel. Dette er som det har været tidligere, men herefter bliver det interessant. Funktionens fjerde parameter angiver, hvilke knapper der skal vises. Dette sker efter samme metode, som ved showConfirmDialog. Dernæst skal det angives, hvilket ikon der skal vises i dialogboksen – her kan de samme konstanter som ved showMessageDialog bruges. Hvis man ikke ønsker et af de indbyggede ikoner vist, kan man vælge at angive sit eget – det gør man ved at angive et Icon-objekt som den næste parameter. Den næste parameter er et array af typen Object. Dette array indeholder de valgmuligheder, brugeren har. Hvis arrayet indeholder objekter, der er komponenter – dvs. instanser af subklasser af Component – bliver disse vist i dialogboksen. Ellers bliver objektets toString-metode kaldt, og resultatet deraf, bliver vist som tekst på knapper.

 

Nedenstående er et eksempel på brug af showOptionDialog. Her vises en dialogboks, hvor brugeren har mulighed for at vælge, hvilke komponenter, der skal installeres. Dialogboksen ses i figur 1.4.

 

Object elementer[] = new Object[5];

elementer[0] = new Checkbox(“Programfiler”);

elementer[1] = new Checkbox(“Hjælpefiler”);

elementer[2] = new Checkbox(“Eksempelfiler”);

elementer[3] = new Button (“OK”);

elementer[4] = new Button (“Annuller”);

JOptionPane.showOptionDialog(null, “Hvilke komponenter vil du installere”, null, 0, JOptionPane.QUESTION_MESSAGE, null, elementer, null);

 

 

 

fig. 1.4 – en OptionDialog

 

 

Træk og slip

Træk og slip er et velkendt begreb i de fleste operativsystemer med grafiske brugergrænseflader. Systemet gør det muligt for brugeren at overføre information mellem to elementer, der er repræsenteret på den grafiske brugergrænseflade. Med træk og slip er det endvidere muligt at gøre brugeren opmærksom på, hvad der vil ske, hvis det element, der trækkes, slippes over det element, markøren befinder sig over. Dette sker oftest ved at ændre udseendet af musemarkøren.

På den baggrund er det kun naturligt, at Java også understøtter træk og slip. Alle komponenter – det vil sige klasser, der nedarver fra java.awt.Component – har metoder, der muliggør træk og slip. Det vil altså sige, at træk og slip ikke er begrænset til at kunne bruges med komponenter fra Swing.

Træk og slip kan implementeres på flere måder. Man kan vælge selv at programmere det hele. Det kan gøres ved at håndtere de mouse events, der opstår, når brugeren begynder at trække i et element. Herefter kan man bruge metoden getComponentAt til at konvertere event’ens x- og y-koordinater til et komponent i vinduet. Det samme kan gøres, når brugeren slipper elementet.

Hvis man ikke behøver meget specialiseret træk og slip-håndtering er det imidlertid væsentligt nemmere at bruge Javas indbyggede funktioner til træk og slip.

En træk og slip-operation indeholder typisk disse elementer:

  • En drag source opstår. Denne er tilknyttet et komponent på brugergrænsefladen, og eventuelt nogle data.
  • Et eller flere drop targets opstår og forsvinder. Drop targets er tilknyttet elementer, der kan modtage data ved hjælp af træk og slip.
  • En bruger starter en træk og slip-operation ved at begynde at trække musen over et komponent, der er tilknyttet en drag source.

 

Knapper

 

I Swing findes der mange forskellige former for knapper. Det drejer sig om almindelige knapper, checkbokse, radioknapper og  menuer.

Almindelige knapper

Almindelige knapper bliver i Swing repræsenteret af objekter af klassen JButton. I forhold til de knapper, som kendes fra AWT (java.awt.Button), er der en del forskelle. Eksempelvis har man mulighed for at tilføje grafik til Swings knapper. Dette vil blive beskrevet yderligere i kapitel 3.

En anden interessant forskel er muligheden for at have genvejstaster. Brugergrænsefladen i AWT er ikke særlig tastaturorienteret – det forventes, at brugeren benytter en mus. Ved at bruge Swing kan man imidlertid aktivere en knap blot ved et enkelt tastetryk. Det gør man ved hjælp af metoden setMnemonic. Nedenstående program er et eksempel på, hvordan genvejstaster kan bruges.

import java.awt.swing.*;

import java.awt.*;

public class Genvejstaster extends JFrame

{

public Genvejstaster()

{

super (“Genvejstaster”);

JButton b1 = new JButton (“Aktivér”);

b1.setMnemonic(‘a’);

getContentPane().add(b1);

 

JButton b2 = new JButton (“Deaktivér”);

b2.setMnemonic(‘d’);

getContentPane().add(b2);

getContentPane().setLayout (new GridLayout());

setSize(200,70);

}

 

public static final void main (String args[])

{

Genvejstaster me = new Genvejstaster();

me.show();

}

}

 

 

Som det ses af figur 1.5, bliver genvejstasten automatisk understreget, hvis den findes i den tekst, som bliver vist på knappen.

 

Figur 1.5 – knappers genvejstaster bliver automatisk understreget.

 

Metoden setMnemonics kan bruges på alle former for knapper.

 

Checkbokse

 

En afkrydsningsfelt er en knap, der enten kan være markeret eller ikke. Hvorvidt knappen er markeret er uafhængig af andre komponenter. I Swing bliver checkbokse repræsenteret af klassen JCheckBox. Nedenstående eksempel viser, hvordan man benytter checkbokse.

 

import java.awt.*;

import java.awt.swing.*;

import java.awt.event.*;

 

public class CheckBoxExample extends JFrame implements ItemListener

{

private JCheckBox b1, b2, b3;

private JTextArea t;

 

private boolean kina, tomat, agurk;

 

public CheckBoxExample ()

{

super (“Salatblander”);

kina = false;

tomat = false;

agurk = false;

 

JPanel panel = new JPanel();

 

b1 = new JCheckBox (“Kinakål”);

b2 = new JCheckBox (“Tomater”);

b3 = new JCheckBox (“Agurk”);

 

b1.addItemListener(this);

b2.addItemListener(this);

b3.addItemListener(this);

 

panel.setLayout (new GridLayout());

 

 

panel.add (b1);

panel.add (b2);

panel.add (b3);

 

t = new JTextArea ();

 

getContentPane().setLayout(new GridLayout(2,1));

getContentPane().add (panel);

getContentPane().add (t);

setSize (300,200);

}

 

public void itemStateChanged (ItemEvent e)

{

if (e.getItem() == b1)

kina = !kina;

else

if (e.getItem() == b2)

tomat = !tomat;

else

if (e.getItem() == b3)

agurk = !agurk;

 

t.setText (“Din salat består nu af følgende:\n”);

if (kina)

t.append (“Kinakål\n”);

if (tomat)

t.append (“Tomat\n”);

if (agurk)

t.append (“Agurk”);

}

 

public static final void main(String args[])

{

CheckBoxExample me = new CheckBoxExample();

me.show();

}

}

 

Grunden, til at klassen implementerer interfacet ItemListener, er, at klassen selv skal håndtere de events, der opstår, når der trykkes på en af checkboksene. Dette foregår i metoden itemStateChanged.

 

Ovenstående program resulterer i et skærmbillede svarende til figur 1.6.

 

Figur 1.6 – Brug af checkbokse

 

 

 

 

 

 

Radioknapper

 

I modsætning til checkbokse kan kun én radioknap i en gruppe være markeret. Radioknapper bruges således, når brugeren kan vælge en (og kun en) af flere muligheder. Klassen RadioButtonExample viser, hvordan radioknapper kan bruges.

 

import java.awt.*;

import java.awt.event.*;

import java.awt.swing.*;

 

public class RadioButtonExample extends JFrame implements ActionListener

{

private JRadioButton b1, b2, b3;

private JTextField t;

 

public RadioButtonExample()

{

super(“Hvilken type is vil du have?”);

 

JRadioButton b1 = new JRadioButton (“Jordbær”);

JRadioButton b2 = new JRadioButton (“Chokolade”);

JRadioButton b3 = new JRadioButton (“Vanille”);

 

b1.setActionCommand(“jordbær”);

b2.setActionCommand(“chokolade”);

b3.setActionCommand(“vanille”);

 

b1.addActionListener (this);

b2.addActionListener (this);

b3.addActionListener (this);

 

ButtonGroup bg = new ButtonGroup();

bg.add (b1);

bg.add (b2);

bg.add (b3);

 

JPanel panel = new JPanel();

panel.setLayout(new GridLayout(1,3));

 

panel.add(b1);

panel.add(b2);

panel.add(b3);

 

t = new JTextField();

 

getContentPane().setLayout(new GridLayout(2,1));

getContentPane().add(panel);

getContentPane().add(t);

 

setSize (400,100);

 

}

 

 

public void actionPerformed (ActionEvent e)

{

if (e.getActionCommand().equals(“jordbær”))

t.setText (“En jordbæris på vej…”);

else

if (e.getActionCommand().equals(“chokolade”))

t.setText (“En chokoladeis på vej…”);

else

if (e.getActionCommand().equals(“vanille”))

t.setText (“En vanilleis på vej…”);

}

 

public static final void main (String args[])

{

RadioButtonExample me = new RadioButtonExample();

me.show();

}

}

 

Radioknapper skal samles i en gruppe for at sikre, at kun én af dem er markeret ad gangen. Det gøres ved at tilføje dem til et ButtonGroup-objekt. Derudover skal man lægge mærke til, at radioknapper bruger action-events og ikke item-events. Figur 1.7 viser et vindue med radioknapper.

 

 

Et vindue med radioknapper

 

Tooltips

 

Tooltips er de små gule beskeder, som bliver vist, når man lader musemarkøren vente over et komponent. Hvis man vil tilføje et tooltip til et komponent, er det relativt simpelt. Nedenstående programstump viser, hvordan det kan gøres.

 

import java.awt.swing.*;

import java.awt.*;

 

public class ToolTipExample extends JFrame

{

public ToolTipExample()

{

JButton b1 = new JButton (“Knap 1”);

JButton b2 = new JButton (“Knap 2”);

 

b1.setToolTipText (“Dette er den første knap”);

b2.setToolTipText (“Dette er den anden knap”);

getContentPane().add(b1);

getContentPane().add(b2);

getContentPane().setLayout(new GridLayout());

 

 

setSize(200,70);

}

 

public static final void main(String args[])

{

ToolTipExample me = new ToolTipExample();

me.show();

}

}

 

Figur 1.8 viser, hvordan vinduet og tooltippet kommer til at se ud.

 

 

Figur 1.8 – Tooltip

 

Hvis man selv skriver en komponent, og gerne selv vil specificere, hvordan tooltips skal håndteres skal man bruge klassen java.awt.swing.JToolTip. Denne klasse har følgende signatur:

 

public class JToolTip extends java.awt.swing.JComponent implements java.awt.accessibility.Accessible

{

public java.awt.swing.JToolTip();

public java.awt.swing.JComponent getComponent();

public java.lang.String getTipText();

public void setComponent(java.awt.swing.JComponent);

public void setTipText(java.lang.String);

}

 

Metoderne getTipText og setTipText bruges naturligvis til at manipulere den tekst, der vises i tooltippet. getComponent og setComponent bruges til at læse og angive, hvilket komponent tooltippet er tilknyttet.

Valg af brugergrænseflade

 

Som nævnt tidligere understøtter Swing flere forskellige brugergrænseflader. Nogle brugergrænseflader kan følger med Java Development Kit, mens andre skal installeres særskilt. Klassen UIManager håndterer installerede brugergrænseflader.

 

 

public class UIManager extends Obejct implements Serializable

{

public UIManager();

 

public static java.awt.swing.UIManager$LookAndFeelInfo[] getInstalledLookAndFeels ();

 

public static void installLookAndFeel (java.lang.String, java.lang.String);

}

 

Det er ikke overraskende metoden, getInstalledLookAndFeels, der bruges til at hente en oversigt over de installerede grænseflader. Denne funktion returnerer de installerede grænseflader i et array af LookAndFeelInfo-objekter:

 

 

public class UIManager.LookAndFeelInfo extends Object

{

public LookAndFeelInfo(java.lang.String, java.lang.String);

 

public java.lang.String getClassName ();

public java.lang.String getName ();

}

 

 

Når man har et LookAndFeel-objekt, kan man kalde funktionen getClassName for at få navnet på den tilknyttede klasse.

 

Dette navn kan man bruge til at vælge at anvende den pågældende brugergrænseflade. Det gør man med den statiske metode UIManager.setLookAndFeel.setLookAndFeel. setLookAndFeel kan kaldes når som helst i programmet – man kan således godt ændre udseendet af brugergrænsefladen, mens den vises. Nedenstående eksempel viser, hvordan man kan lave en oversigt over installerede brugergrænseflader og herefter lade brugeren vælge mellem dem. Figur 1.5 og 1.6 viser skærmbilledet med to forskellige typer af brugergrænseflader.

 

import java.awt.swing.*;

import java.awt.*;

import java.awt.event.*;

 

public class LookAndFeelChanger extends JFrame {

public static LookAndFeelChanger myFrame = null;

 

public LookAndFeelChanger() {

getContentPane().setLayout(null);

UIManager.LookAndFeelInfo info[] = UIManager.getInstalledLookAndFeels();

for (int i = 0; i < info.length; i++) {

JButton b = new JButton(info[i].getClassName());

b.setBounds(10, i * 30, 400,20);

b.addActionListener(new LAFCListener());

getContentPane().add(b);

}

setSize(440, 120);

setVisible(true);

}

 

 

public static final void main(String args[])

{

myFrame = new LookAndFeelChanger();

 

 

}

 

class LAFCListener implements ActionListener {

public void actionPerformed (ActionEvent e) {

try {

UIManager.setLookAndFeel(e.getActionCommand());

SwingUtilities.updateComponentTreeUI(myFrame);

}

catch(ClassNotFoundException cnfe) {

System.err.println(cnfe.toString());

}

catch(UnsupportedLookAndFeelException ulafe) {

System.err.println(ulafe.toString());

}

catch(IllegalAccessException iae) {

System.err.println(iae.toString());

}

catch(InstantiationException ie) {

System.err.println(ie.toString());

}

}

}

}

 

 

fig. 1.9 – En MetalLookAndFeel dialogboks.

 

 

fig. 1.10 – En Windows dialogboks.

 

 

FAQ

 

Ved almindelige Dialog-objekter kan man angive, om dialogboksen skal være modal. Har standarddialogbokse den samme mulighed.

Nej. Standarddialogbokse er altid modale. Det vil sige, at udførslen af den tråd, der kalder dialogboksen, stoppes, indtil dialogboksen er blevet lukket.

 

Hvordan sikrer man, at ens program har den samme brugergrænseflade på flere forskellige platforme?

Hvis man ikke ændrer udseendet af brugergrænsefladen, får den MetalLookAndFeel. Denne brugergrænseflader er installeret på alle implementationer af Java, og programmer, der bruger denne grænseflade, vil derfor, være stort set ens på alle platforme. Det kan være en fordel, når der skal udarbejdes manualer og onlinehjælp.

 

Kan man anvende double-buffering med Swing?

 

Double-buffering er en teknik, der kan forbedre udseendet af brugergrænseflader, der ændres tit. Swing anvender automatisk double-buffering, så man behøver ikke længere selv at skrive den del af programmet. Hvis man ikke vil bruge double-buffering kan man kalde metoden setDoubleBuffered(false) på et komponent.

 

Du læser en gammel bog

Den bog, du læser her, er fra 1998, og mange ting kan have ændret sig siden da.
Vi håber, at du stadig kan finde relevant information i den.
Hvis du vil læse aktuelle oplysninger om de avancerede dele af Java, anbefaler vi
bogen Core Java – Advanced Features

Comments are closed.