![]() |
![]() |
Start på kapittel om spesialiserte komponenter for grafiske brukergrensesnitt |
Action
-objekterInterface
Action
er en utvidelse av
ActionListener
.
Et Action
-objekt kan derfor brukes som et lytteobjekt av type
ActionListener
. Action
-objekter er nyttige å bruke
som lytteobjekter når det skal være to eller flere forskjellige måter å
aktivere én og samme kommando på: menyalternativ, knapp (som kan være
på en verktøylinje), popp-opp-meny, tastaturalternativ. Alle disse kan bruke
et felles Action
-objekt for kommandoen. Dette kan da inneholde
data som navn (til menyalternativ og knapp), ikon og tooltip-tekst. Et
Action
-objekt kan aktiveres og deaktiveres. Alle gui-komponenter
som er knyttet til Action
-objektet blir da samtidig aktivert
eller deaktivert. Vi slipper altså å utføre instruksjoner for dette for
hver enkelt gui-komponent: Action
-objektet gjør jobben for oss.
For å knytte et Action
-objekt til en gui-komponent, kan vi enten
gjøre kall på komponentens setAction
-metode med
Action
-objektet som aktuell parameter, eller vi kan bruke
Action
-objektet som konstruktørparameter når komponenten blir
opprettet.
Klassen
AbstractAction
implementerer
interface Action
med standardoppførsel for metodene. For å
definere et Action
-objekt er det derfor greiest å definere en
subklasse til AbstractAction
og redefinere metoden
actionPerformed
. Som nevnt ovenfor, kan Action
-objektet
inneholde hva som skal brukes av navn, ikon og tooltip-tekst for de
komponentene som objektet skal være tilknyttet og lytte på. Verdier for disse
kan vi få tilført Action
-objektet i form av konstruktørparametre
etter dette mønster:
class EksempelAction extends AbstractAction { public EksempelAction(String tekst, ImageIcon ikon, String tooltiptekst, Integer mnemonic) { super(tekst, ikon); //gir tekst og ikon for knapper og menyalternativer putValue(Action.SHORT_DESCRIPTION, tooltiptekst); putValue(Action.MNEMONIC_KEY, mnemonic); //tastaturalternativ } public void actionPerformed(ActionEvent e) { ... } }
Det er mer ressurskrevende å bruke Action
-objekter enn å
bruke ActionListener
-objekter. De bør derfor ikke brukes dersom
man ikke har bruk for den tilleggsfunksjonaliteten som de gir.
Vi skal nedenfor ta for oss et programeksempel der det blir brukt
Action
-objekter som felles lytteobjekter for knapper,
menyalternativer og popp-opp-menyer. I programmet brukes det dessuten et
lytteobjekt av type
CaretListener
.
Vi må derfor først se litt nærmere på slike.
CaretListener
Subklasser av klasse
JTextComponent
kaller vi med en felles
betegnelse for tekstkomponenter. (Blant annet vil objekter av typene
JTextField, JTextArea
og JEditorPane
være
tekstkomponenter.) Når markøren flytter seg i en tekstkomponent, eller når
det er endringer i hvilken tekst som er markert, så blir det generert
hendelser av type
CaretEvent
.
Lytteobjekter av type
CaretListener
kan lytte på slike hendelser. Vi kan knytte et
lytteobjekt av denne type til en tekstkomponent ved kall på dens
addCaretListener
-metode. For å definere en
CaretListener
, må vi implementere metoden
caretUpdate
:
class Markeringslytter implements CaretListner { public void caretUpdate(CaretEvent e) { ... } }
For det CaretEvent
-objekt som er parameter til
caretUpdate
, kan vi gjøre kall på to nyttige metoder:
int getDot()
:int getMark()
:getDot()
. getMark() >= getDot()
.Programmet
Actiondemo.java
som er gjengitt nedenfor, har et brukervindu som ved oppstart ser ut som
vist på følgende bilde.
I det tomme tekstområdet kan det skrives eller kopieres inn tekst. De tre knappene på vinduets verktøylinje er programmert til å kunne utføre følgende tekstredigeringsoperasjoner:
For de samme tre tekstredigeringsoperasjoner finnes det menyalternativer i
menyen Editer, samt i en popp-opp-meny som kommer opp ved å høyreklikke musa
mens markøren er i tekstområdet. I tillegg virker de vanlige
tastaturalternativene Ctrl-c, Ctrl-x og Ctrl-v for disse operasjonene.
Disse tastaturalternativene virker automatisk på alle editerbare tekstkomponenter,
uten at vi trenger å foreta noe ekstra programmering. For å kopiere, klippe ut,
eller lime inn tekst ved bruk av utklippsbordet, bruker vi
tekstkomponentmetodene copy, cut
og paste
.
For hver av de tre nevnte tekstredigeringsoperasjonene er det i programmet
definert et Action
-objekt:
CutAction
for utklippCopyAction
for kopieringPasteAction
for innliming.
Hvert av Action
-objektene brukes som felles lytteobjekt for de tre
aktiveringsalternativene for vedkommende operasjon (knapp på verktøylinje,
vanlig meny-alternativ, alternativ i popp-opp-meny). Når det gjelder
kopiering og utklipp, er vedkommende Action
-objekt bare aktivert
i tilfelle det er merket noe tekst i tekstområdet. Ved aktivering og
deaktivering av Action
-objekt, vil da automatisk de knapper og
meny-alternativer som er knyttet til dette, også bli aktivert eller deaktivert.
For å finne ut om det er merket noe tekst i tekstområdet, brukes en
CaretListener
. Denne er definert av den indre klassen
Markeringslytter
. Tekst vil være merket i tilfelle
CaretEvent
-metodene getDot
og
getMark
returnerer forskjellig verdi.
Programmet gjør bruk av tre bildefiler som gir ikoner til knappene. Slik
programmet er skrevet, må bildefilene ligge i en underkatalog bilder
i forhold til programfilene. De tre bildefilene er
copy.gif
,
cut.gif
og
paste.gif
.
For å få opp den nevnte popp-opp-meny ved høyreklikk av musa i
tekstområdet, trenger vi en muselytter. Denne er definert av den
indre klassen Muselytter
. Det blir sjekket om høyre museknapp
er trykket ned eller sluppet opp, og i så fall vises popp-opp-menyen på det
stedet der musepekeren er. Fullstendig programkode er gjengitt nedenfor.
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 import javax.swing.text.*; 5 import javax.swing.event.*; 6 7 //Hendelsesobjekt for å klippe ut merket tekst og 8 //legge den på klippebordet. 9 class CutAction extends AbstractAction 10 { 11 private JTextComponent kilde; 12 13 public CutAction(String navn, Icon ikon, String tiptekst, 14 JTextComponent komp) 15 { 16 super(navn, ikon); 17 putValue(Action.SHORT_DESCRIPTION, tiptekst); //gir tooltip-tekst 18 //til knapper 19 kilde = komp; 20 } 21 22 public void actionPerformed(ActionEvent e) 23 { 24 kilde.cut(); 25 } 26 } 27 28 //Hendelsesobjekt for å kopiere merket tekst til klippebordet. 29 class CopyAction extends AbstractAction 30 { 31 private JTextComponent kilde; 32 33 public CopyAction(String navn, Icon ikon, String tiptekst, 34 JTextComponent komp) 35 { 36 super(navn, ikon); 37 putValue(Action.SHORT_DESCRIPTION, tiptekst); 38 kilde = komp; 39 } 40 41 public void actionPerformed(ActionEvent e) 42 { 43 kilde.copy(); 44 } 45 } 46 47 //Hendelsesobjekt for å lime inn tekst fra klippebordet. 48 class PasteAction extends AbstractAction 49 { 50 private JTextComponent kilde; 51 52 public PasteAction(String navn, Icon ikon, String tiptekst, 53 JTextComponent komp) 54 { 55 super(navn, ikon); 56 putValue(Action.SHORT_DESCRIPTION, tiptekst); 57 kilde = komp; 58 } 59 60 public void actionPerformed(ActionEvent e) 61 { 62 kilde.paste(); 63 } 64 } 65 66 public class Actiondemo extends JFrame 67 { 68 private JTextArea testområde; 69 private JToolBar verktøylinje; 70 private JPopupMenu poppopp; 71 private Action kopier, klippUt, limInn; 72 73 public Actiondemo() 74 { 75 super("Action-demonstrasjon"); 76 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 77 78 testområde = new JTextArea(10, 30); 79 testområde.addMouseListener(new Muselytter()); 80 testområde.addCaretListener(new Markeringslytter()); 81 82 //Oppretter Action-objekter som skal brukes av meny, 83 //verktøylinje og pop-opp-meny: 84 kopier = new CopyAction( 85 "Kopier", new ImageIcon( 86 getClass().getResource("bilder/copy.gif")), 87 "Kopier merket tekst til utklippsbord", 88 testområde); 89 kopier.setEnabled(false); //Aktiveres bare når noe tekst er merket. 90 klippUt = new CutAction( 91 "Klipp ut", new ImageIcon( 92 getClass().getResource("bilder/cut.gif")), 93 "Klipp ut merket tekst til utklippsbord", 94 testområde); 95 klippUt.setEnabled(false); //Aktiveres bare når noe tekst er merket. 96 limInn = new PasteAction( 97 "Lim inn", new ImageIcon( 98 getClass().getResource("bilder/paste.gif")), 99 "Lim inn tekst fra utklippsbord", testområde); 100 101 //Knapper for verktøylinje: 102 JButton kopi = new JButton(); 103 kopi.setAction(kopier); //vil gi knappen både tekst, 104 //tooltip-tekst, ikon og lytteobjekt 105 kopi.setText(""); //ønsker bare ikon og tooltip-tekst på knappen 106 JButton klipp = new JButton(); 107 klipp.setAction(klippUt); 108 klipp.setText(""); 109 JButton lim = new JButton(); 110 lim.setAction(limInn); 111 lim.setText(""); 112 113 verktøylinje = new JToolBar(); 114 verktøylinje.add(kopi); 115 verktøylinje.add(klipp); 116 verktøylinje.add(lim); 117 118 //Oppretter meny 119 JMenu editering = new JMenu("Editer"); 120 JMenuItem kopivalg = new JMenuItem(); 121 kopivalg.setAction(kopier); 122 editering.add(kopivalg); 123 JMenuItem klippvalg = new JMenuItem(); 124 klippvalg.setAction(klippUt); 125 editering.add(klippvalg); 126 JMenuItem limvalg = new JMenuItem(); 127 limvalg.setAction(limInn); 128 editering.add(limvalg); 129 130 //Oppretter pop-opp-meny 131 poppopp = new JPopupMenu(); 132 JMenuItem kopiering = new JMenuItem(); 133 kopiering.setAction(kopier); 134 poppopp.add(kopiering); 135 JMenuItem utklipp = new JMenuItem(); 136 utklipp.setAction(klippUt); 137 poppopp.add(utklipp); 138 JMenuItem innliming = new JMenuItem(); 139 innliming.setAction(limInn); 140 poppopp.add(innliming); 141 142 //Lager layout 143 Container c = getContentPane(); 144 c.add(new JScrollPane(testområde), BorderLayout.CENTER); 145 c.add(verktøylinje, BorderLayout.PAGE_START); 146 JMenuBar menylinje = new JMenuBar(); 147 menylinje.add(editering); 148 setJMenuBar(menylinje); 149 pack(); 150 setVisible(true); 151 } 152 153 //Brukes til å lytte på høyre-klikk av mus for å vise poppopp-meny. 154 private class Muselytter extends MouseAdapter 155 { 156 public void mousePressed(MouseEvent e) 157 { 158 visPoppopp(e); 159 } 160 161 public void mouseReleased(MouseEvent e) 162 { 163 visPoppopp(e); 164 } 165 166 private void visPoppopp(MouseEvent e) 167 { 168 if (e.isPopupTrigger()) 169 { 170 poppopp.show(e.getComponent(), e.getX(), e.getY()); 171 } 172 } 173 } 174 175 //Bruker denne for å sjekke om det er markert noe tekst. 176 private class Markeringslytter implements CaretListener 177 { 178 public void caretUpdate(CaretEvent e) 179 { 180 int pos = e.getDot(); //henter markørposisjon 181 int start = e.getMark(); //henter posisjon for andre ende 182 //av merket område 183 boolean merket = (pos != start); //sjekker om noe tekst er merket 184 klippUt.setEnabled(merket); 185 kopier.setEnabled(merket); 186 } 187 } 188 189 public static void main(String[] args) 190 { 191 EventQueue.invokeLater(new Runnable() 192 { 193 public void run() 194 { 195 new Actiondemo(); 196 } 197 }); 198 } 199 }
Copyright © Kjetil Grønning og Eva Hadler Vihovde, revidert 2015
![]() |
![]() |
Start på kapittel om spesialiserte komponenter for grafiske brukergrensesnitt |