![]() |
![]() |
Start på kapittel om grafiske brukergrensesnitt |
JButton
ItemListener
Fellesnavnet knapp brukes om følgende typer grafiske komponenter:
Klasse | Knappetype |
---|---|
JButton | vanlig knapp |
JCheckBox | avkryssingsboks |
JRadioButton | radioknapp |
JMenuItem | menyalternativ |
JCheckBoxMenuItem | avkryssingsalternativ i meny |
JRadioButtonMenuItem | radioknapp i menyalternativ |
JToggleButton | av/på-bryter |
Når det gjelder den siste typen, JToggleButton
, så brukes
den vanligvis ikke som den er. Isteden brukes komponenter av en av de to
subklassetypene: JCheckBox
eller JRadioButton
.
En JToggleButton
ser ut som en vanlig knapp (av type
JButton
), men virker som en av/på-bryter tilsvarende som en
avkryssingsboks.
Alle de nevnte klassene er (direkte eller indirekte) subklasser til
AbstractButton
. Denne definerer det som er felles for alle typer
knapper.
Alle typer knapper kan utstyres med både tekst og bilder, eller bare én av delene. Dessuten kan de knyttes til et tastaturalternativ for aktivering.
Implementasjon av hendelses-håndtering (event-håndtering) for knapper
avhenger av hvilken type knapp vi har med å gjøre. Det vanlige er å ha et
lytteobjekt av type ActionListener
. Dette vil da bli varslet
hver gang vi klikker på knappen (eller aktiverer den ved hjelp av
tastaturalternativ). For avkryssingsbokser er det imidlertid mer vanlig å
bruke et lytteobjekt av type ItemListener
. Dette vil da bli
varslet hver gang avkryssingsboksen blir valgt eller av-valgt.
Java skiller mellom tegn og virtuelle tastaturkoder
(virtual key codes). Virtuelle tastaturkoder blir indikert med prefikset
VK_
, slik som i eksemplene VK_A
og
VK_SHIFT
. Virtuelle tastaturkoder svarer til taster på tastaturet.
For eksempel vil VK_A
svare til tasten med A på tastaturet. Det finnes
ingen separate tastaturkoder for små bokstaver, for på tastaturet er det
ingen separate taster for små bokstaver.
For å spesifisere tastaturalternativ for en knapp, brukes metoden
setMnemonic
. Som det vil gå fram av det følgende programeksemplet,
kan vi som parameter i denne bruke både et tegn, for eksempel
'h'
,
eller en virtuell tastaturkode, for eksempel VK_H
. I begge
disse tilfellene ville det ha blitt Alt-H som var tastaturalternativet (det
vil si holde Alt-tasten nede mens vi trykker på H-tasten). Dette alternativet
ville det også ha blitt om vi hadde brukt 'H'
som parameter i
setMnemonic
-metoden. Hadde vi i dette tilfellet prøvd med
tastaturalternativet Alt-shift-H (for å få tegnet H), ville det ikke virket.
JButton
Vi skal se på et eksempel på bruk av tekst og bilde i en vanlig knapp,
av type JButton
,
hvordan plassering av tekst og bilde innenfor knappen kan styres og hvordan
vi kan få bildet til å skifte når musepekeren beveger seg over knappen.
Eksemplet er en modifikasjon og utvidelse av eksemplet Fig. 14.15 og Fig. 14.16 i
læreboka til Deitel & Deitel, 9. utgave. Den viktigste utvidelsen er
at det til knappene er knyttet tastaturalternativer. Vi legger merke til
at tastaturalternativene er markert på knappeteksten ved at den bokstaven
som gir tastaturalternativet er understreket. Når programmet blir kjørt,
vil det gi et vindu som vist på følgende bilde:
Bildene (ikonene) som er brukt på knappene finnes i følgende filer:
right.gif,
bug1.GIF,
bug2.GIF,
left.gif.
Slik programkoden er skrevet, må disse filene ligge i samme filkatalog som
class
-fila for vindusklassen. Vinduet er definert i fila
Knappevindu.java som
er gjengitt nedenfor. Driverklasse for programmet finnes i fila
Knappetest.java.
Merk deg spesielt koden for å plassere tekst
og bilder på knappene, samt koden for å sette tastaturalternativ.
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 //Bruk av bilde og tekst i knapper 6 public class Knappevindu extends JFrame 7 { 8 private JButton venstreknapp, midtknapp, høyreknapp; 9 10 public Knappevindu() 11 { 12 super( "Knappedemo" ); 13 14 Container c = getContentPane(); 15 c.setLayout( new FlowLayout() ); 16 17 // oppretter knapper 18 Icon venstreknappikon = new ImageIcon( 19 getClass().getResource("bilder/right.gif" )); 20 venstreknapp = new JButton("Venstre knapp", venstreknappikon); 21 venstreknapp.setVerticalTextPosition( AbstractButton.CENTER ); 22 venstreknapp.setHorizontalTextPosition( AbstractButton.LEFT ); 23 venstreknapp.setMnemonic( KeyEvent.VK_V ); 24 c.add( venstreknapp ); 25 26 Icon bug1 = new ImageIcon( 27 getClass().getResource( "bilder/bug1.gif" )); 28 Icon bug2 = new ImageIcon( 29 getClass().getResource( "bilder/bug2.gif" )); 30 midtknapp = new JButton( "Midtknapp", bug1 ); 31 midtknapp.setRolloverIcon( bug2 ); 32 midtknapp.setVerticalTextPosition( AbstractButton.BOTTOM ); 33 midtknapp.setHorizontalTextPosition( AbstractButton.CENTER ); 34 midtknapp.setMnemonic( KeyEvent.VK_M ); 35 c.add( midtknapp ); 36 37 Icon høyreknappikon = new ImageIcon( 38 getClass().getResource("bilder/left.gif" )); 39 høyreknapp = new JButton( "Høyre knapp", høyreknappikon ); 40 //bruker default tekstposisjon CENTER, RIGHT. 41 høyreknapp.setMnemonic( 'H' ); 42 høyreknapp.setForeground( Color.red ); 43 c.add( høyreknapp ); 44 45 Knappelytter handler = new Knappelytter(); 46 midtknapp.addActionListener( handler ); 47 venstreknapp.addActionListener( handler ); 48 høyreknapp.addActionListener( handler ); 49 } 50 51 private class Knappelytter implements ActionListener 52 { 53 public void actionPerformed( ActionEvent e ) 54 { 55 JOptionPane.showMessageDialog( null, 56 "Du klikket på: " + e.getActionCommand() ); 57 } 58 } 59 }
Både avkryssingsbokser og radioknapper blir brukt til å velge blant alternativer. Forskjellen mellom dem er at avkryssingsbokser blir brukt til å velge ingen, ett eller flere av alternativene i en gruppe av muligheter. Radioknapper blir brukt til å velge nøyaktig ett alternativ. For øvrig har de to typene knapper ulikt utseende.
En avkryssingsboks, type
JCheckBox
,
genererer én ItemEvent
og én
ActionEvent
per klikk i boksen. Vanligvis lytter vi bare på
ItemEvent
'ene, siden de kan brukes til å avgjøre om det ble
avkrysset eller frakrysset (valg opphevet) i avkryssingsboksen.
Radioknapper er en gruppe av knapper som hører sammen og der bare én knapp om gangen
kan velges. Knappene oppretter vi som
JRadioButton
-objekter.
Objektene må add'es til et
ButtonGroup
-objekt.
Hver gang
brukeren klikker på en radioknapp (selv om den er valgt allerede), blir det
generert en ActionEvent
. Dessuten vil det bli generert én
eller to ItemEvent
'er: en fra knappen som nettopp ble valgt, og
en fra knappen som ble av-valgt, dersom det var noen.
Det er ButtonGroup
-objektet som sørger for at den forrige
valgte radioknapp blir av-valgt når en ny blir valgt. En gruppe av
radioknapper bør initialiseres slik at én av dem er valgt i utgangspunktet.
ItemListener
I programmet
Radioknapper.java
som det er gjengitt vinduskode for nedenfor,
er det et tekstfelt med en demonstrasjonstekst som kan vises i flere forskjellige
fonter etter brukerens valg. Navn på valgt font blir skrevet ut i et annet tekstfelt.
Når programmet kjøres, kan programvinduet se ut som vist på følgende bilde.
Tre radioknapper brukes til å velge ett av
tre mulige fontnavn for teksten. To avkryssingsbokser brukes til å velge fontstil:
normal, fet normal, kursiv, eller fet kursiv. Til radioknappene er det brukt
lytteobjekt av type ActionListener
. (Vi kunne også ha brukt
ItemListener
.) Til avkryssingsboksene er det brukt lytteobjekt av
type ItemListener
. Et slikt lytteobjekt må implementere metoden
public void itemStateChanged( ItemEvent e ) { ... }
I programeksemplet blir det i denne metoden for hver avkryssingsboks sjekket
om det er krysset av i den eller ikke. Det får vi gjort ved kall på
avkryssingsboksens metode isSelected
. Denne returnerer
true
dersom det er krysset av i boksen,
false
ellers. På grunnlag av de forskjellige mulige kombinasjonene av
avkryssingsalternativer blir det i dette tilfelle valgt stilkode for
teksten i tekstfeltet.
Driverklasse for programmet finnes i fila Radioknapptest.java.
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.*; 4 5 //Demonstrasjon av radioknapper og avkrysningsbokser 6 public class Radioknapper extends JFrame 7 { 8 private int stilkode = Font.PLAIN; 9 private String fontnavn = "Monospaced"; 10 private JTextField prøvefelt, infofelt; 11 private JCheckBox fet, kursiv; 12 private ButtonGroup fonter; 13 private JRadioButton mono, dialog, serif; 14 //skal legges inn i gruppa fonter 15 private Typelytter avkryssingslytter; 16 private Fontlytter radiolytter; 17 18 public Radioknapper() 19 { 20 super( "Radioknapper" ); 21 avkryssingslytter = new Typelytter(); 22 radiolytter = new Fontlytter(); 23 prøvefelt = new JTextField( "Demonstrasjonstekst", 25 ); 24 fet = new JCheckBox( "Fet skrift" ); 25 fet.addItemListener( avkryssingslytter ); 26 kursiv = new JCheckBox(); 27 kursiv.setText( "Kursiv" ); //tekst til avkrysningsboks 28 kursiv.addItemListener( avkryssingslytter ); 29 fonter = new ButtonGroup(); 30 mono = new JRadioButton( "Monospaced", true ); 31 mono.addActionListener( radiolytter ); 32 dialog = new JRadioButton( "Dialog", false ); 33 //én radioknapp skal være aktivert, resten ikke 34 dialog.addActionListener( radiolytter ); 35 serif = new JRadioButton( "Serif", false ); 36 serif.addActionListener( radiolytter ); 37 fonter.add( mono ); 38 fonter.add( dialog ); 39 fonter.add( serif ); 40 infofelt = new JTextField( 25 ); 41 infofelt.setEditable( false ); 42 oppdaterFont(); 43 Container c = getContentPane(); 44 c.setLayout( new FlowLayout() ); 45 c.add( prøvefelt ); 46 c.add( mono ); //Obs: Radioknappene 47 c.add( dialog ); //adderes til vinduet hver for seg, 48 c.add( serif ); //ikke som en gruppe. 49 c.add( fet ); 50 c.add( kursiv ); 51 c.add( infofelt ); 52 setSize( 300, 160 ); 53 setVisible( true ); 54 } 55 56 //setter utskriftsfont i samsvar med valg 57 public void oppdaterFont() 58 { 59 Font skrivefont = new Font( fontnavn, stilkode, 16 ); 60 prøvefelt.setFont( skrivefont ); 61 prøvefelt.repaint(); 62 infofelt.setText( "Fontnavn: " + skrivefont.getFontName() ); 63 } 64 65 private class Typelytter implements ItemListener 66 { 67 public void itemStateChanged( ItemEvent e ) 68 { 69 if ( !fet.isSelected() && !kursiv.isSelected() ) 70 stilkode = Font.PLAIN; 71 else if ( fet.isSelected() && !kursiv.isSelected() ) 72 stilkode = Font.BOLD; 73 else if ( !fet.isSelected() && kursiv.isSelected() ) 74 stilkode = Font.ITALIC; 75 else 76 stilkode = Font.BOLD + Font.ITALIC; 77 oppdaterFont(); 78 } 79 } 80 81 private class Fontlytter implements ActionListener 82 { 83 public void actionPerformed( ActionEvent e ) 84 { 85 if ( mono.isSelected() ) //eller: e.getSource() == mono 86 fontnavn = "Monospaced"; 87 else if ( dialog.isSelected() ) //eller: e.getSource() == dialog 88 fontnavn = "Dialog"; 89 else if ( serif.isSelected() ) //eller: e.getSource() == serif 90 fontnavn = "Serif"; 91 oppdaterFont(); 92 } 93 } 94 }
De andre typene knapper som er listet opp ovenfor har med menyer å gjøre. Menyer er omtalt i notatet Litt om hvordan man lager menyer.
Copyright © Kjetil Grønning, revidert av Eva Hadler Vihovde 2014
![]() |
![]() |
Start på kapittel om grafiske brukergrensesnitt |