Menyer och verktygsfält
Följande exempel illustrerar mycket av menyhanteringen i Swing, Menus.java. Du kan hämta bilden genom att hålla
nere shifttangenten och klicka här, plant.gif.
Vi går igenom exemplet bit för bit.
JMenuItem
Ett menyelement är ett objekt av klassen JMenuItem. Den ärver
av AbstractButton, vilket innebär dels att den har JComponents
och AbstractButtons hela funktionalitet, dels att vilken subklass
som helst till JComponent kan användas som menyelement.
Ett menyelement kan ha en mnenomic, vilken kan anges antingen direkt i
konstruktorn eller med metoden setMnemonic(). I exemplet ovan sätts
den i konstruktorn. Raden item = new JMenuItem( "Paste", 'P' ) tilldelar
mnemonic P till menyvalet paste på editmenyn. Det innebär att tangentkombinationen
ALT-P genererar ett tryck på paste då editmenyn är uppe.
Observera att den bokstav som anges måste finnas i menyelementets label
och att den inte får vara mnemonic för menyns label.
Det går också att ange en genväg, i exemplet görs
det med bland annat raden item.setAccelerator( KeyStroke.getKeyStroke(
'V', java.awt.Event.CTRL_MASK, false ) ).
Detta gör att tangentkombinationen CTRL-V genererar ett tryck på
item oavsett om dess meny är uppe eller inte. KeyStroke
är en klass som används för att representera en tangentkombination.
Man kan placera en ikon bredvid texten. I exemplet ovan har ikonen angetts
i konstruktorn med raden otherMenu.add(
item = new JMenuItem( "Potted Plant", new ImageIcon( "plant.gif" ) ) ).
Checkbox och radiobutton
En checkbox eller radiobutton placeras i exemplet ut med raderna otherMenu.add(
item = new JCheckBoxMenuItem( "Check Me" ) ) respektive
ButtonGroup buttonGroup = new ButtonGroup();
otherMenu.add(item = new JRadioButtonMenuItem("Radio 1"));
buttonGroup.add(item);
Precis som när det gäller knappar används en ButtonGroup
för att max en radiobutton åt gången ska kunna vara vald.
JMenu
En meny representeras av klassen JMenu. Eftersom den ärver
av JMenuItem går det bra att placera en meny inuti en annan
meny. Det görs, precis på samma sätt som ett menyelement
läggs till, men metoden add(). Se till exempel raden otherMenu.add(
subMenu ) i exemplet. Även en meny kan ha en mnemonic. Det finns
dock ingen konstruktor som tar den utan metoden setMnemonic() måste
användas, som på raden editMenu.setMnemonic( 'E' ).
JMenuBar
Menyerna måste placeras i ett objekt av klassen JMenuBar,
med hjälp av dess metod add(). Menyraden placeras sedan i
till exempel en frame med metoden setJMenuBar(). Egentligen placeras
menyraden i framens layeredPane, men det sköter Swing åt
oss. SetJMenuBar() placerar menyraden där den normalt hör
hemma, överst i framen. Men då JMenuBar ärver av
JComponent går det lika bra att placera ut den var som helst
med metoden add(), precis som vilken annan komponent som helst.
Separator
Ett objekt av JSeparator representerar en linje. I vårt
menyexempel läggs ett sådant in till exempel med raden otherMenu.addSeparator().
Eftersom JSeparator ärver av JComponent går
det att använda den även i exempelvis en frame, som vilken komponent
som helst.
Popupmenyer
En popupmeny är en meny som inte finns på menyraden utan kan
dyka upp var som helst på en komponents yta. Ett typiskt exempel är
den meny som dyker upp när du högerklickar på något
fönster. Här är ett exempel på en frame som visar en
popupmeny när du högerklickar på den, PopupMenuExample.java. Håll ner shifttangenten
och klicka här för att hämta bilderna left.gif,
right.gif, center.gif,
full.gif. Menyn dyker upp när höger musknapp
släpps på framens yta, vilket är den metod som används
i till exempel MS Office. MouseEvent har en metod, isPopupTrigger(),
som returnerar true om aktuell mushändelse ska visa popupmenyer på
aktuell plattform. På Windows är det höger musknapp som visar
popupmenyer. Normalt behöver vi inte bry oss om att ta bort menyn, det
sköts av Swing.
Lyssnarstrategier och händelser
Hur ska man veta när användaren gjort ett menyval? JMenuItem
ärver hanteringen av ActionEvent från AbstractButton,
dvs den skickar ett ActionEvent när användaren släpper
musen på det alternativet. Det ActionEvent som skickas kommer
att ha ActionCommand satt till menyelementets label. Förutom
denna metod går det även bra att använda en Action. Dessutom skickar både JCeckBoxMenuItem
och JRadioButtonMenuItem ett ItemEvent när deras
tillstånd ändras.
Förutom vad som nämnts ovan skickar de olika menyklasserna en
drös med händelser. Till exempel skickar JMenuItem MenuDragMouseEvent
vid olika tillfällen när användaren drar musen över en
meny och MenuKeyEvent när menyelementet tar emot en tangenttryckning,
dvs har fokus och användaren trycker på en tangent. En JPopupMenu
skickar ett PupupMenuEvent när den dyker upp eller försvinner
från skärmen. En JMenu skickar ett MenuEvent
för att tala om bland annat huruvida menyn är utfälld eller
ej.
Verktygsfält
Ett verktygsfält representeras av klassen JToolBar, vilken
ärver av JComponent. Du placerar ut den som alla andra komponenter,
med metoden add(). Verktygsfältet kan innehålla vilka
andra komponenter som helst. Default har det layouthanteraren BoxLayout, men det går
att ändra.
Ett verktygsfält har en property floatable som default är
sann. Är den sann går det att klicka på en tom yta på
verktygsfältet och dra iväg det. Det placeras då i ett eget
fönster. Om floatable är sann är det klokt att låta
framen som innehåller verktygsfältet ha BorderLayout.
Det går då att släppa verktygsfältet i någon av
framens kanter och det kommer att fastna där.
Ett verktygsfält har även det en metod addSeparator().
Den har dock inget med klassen JSeparator att göra, utan infogar
en tom yta i verktygsfältet.
Här är ett exempel som implementerar funktionaliteten ovan,
ToolBarTest.java.