Generelt
Swing er et "lettvekter" API til å lage GUI for java. Swing har en arkitektur som gjør det mulig å legge grafikk til kode, uten å forandre alt for mye på applikasjonen.
Med swing kan man enkelt lage buttons, tekstfelt, check boxes, labels, tabeller og lister, i tillegg til en rekke andre komponenter.
For mer om komponentene og hvordan de virker, se Swing komponenter.
Basic komponentbruk og oppbygning
En vanlig måte å bygge opp en GUI-applikasjon med swing er å bruke klassene JFrame og JPanel etter et bestemt mønster.
Konseptet handler om å ha en klasse A, som subklasser (arver) JPanel. A fyller seg selv med komponenter (tekst, buttons, osv.) og danner hele (eller deler) av et vindu.
Merk at en instans av JPanel, et panel, er en komponent på lik linje med et tekstfelt.
En instans av A, a, er altså en komponent utformet slik man ønsker at vinduet sitt skal se ut, men a vil ikke opprette noe vindu som vi kan se og røre ved. Her kommer JFrame inn. En instans av JFrame representeres som et faktisk vindu på skjermen vår. I dette vinduet kan man legge komponenter på lik linje som et panel, men for å skape en struktur fyller vi hele vinduet eller framen med panelet a. Dersom man ønsker en button nederst i vinduet sitt, legges dette altså til i panelet a, ikke i framen.
Forklaring til denne strukturen:
Det er vanlig å strukturere koden slik at klassen tilsvarende et vindu eller panel, typisk en subklasse av JPanel, selv fyller seg med innhold og reagerer på brukerens interaksjon med innholdet (forklares senere).
For mindre applikasjoner uten menylinje er det uvanlig å subklasse JFrame, fordi denne er mindre vanlig å gjenbruke. Istedenfor subklasses JPanel som instansieres i en main-metode sammen med en JFrame og settes som JFramens contentPane.
Eksempelet under viser hvordan man lager et panel (JPanel) som fyller seg selv med komponenter. Dersom applikasjonen har main-metoden (JFrame) som vist under, vil det skapes et vindu som fylles med panelet MySimplePanel.
OBS! Juster størrelsen på vinduet når du tester koden. Dette med layout (BorderLayout) kan du lese mer om her.
JPanel import java.awt.BorderLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; public class MySimplePanel extends JPanel { JTextArea inputText = new JTextArea("Skriv litt tekst her da vel..."); JTextArea text = new JTextArea("Dette er South i layouten :)"); JLabel label = new JLabel("Jeg gleder meg til UKA!"); public MySimplePanel () { this.createGUI(); } private void createGUI() { setLayout(new BorderLayout()); add(inputText, BorderLayout.NORTH); add(label, BorderLayout.WEST); add(text, BorderLayout.SOUTH); text.setEditable(false); } }
|
JFrame import javax.swing.JFrame; public static void main(String[] args) { JFrame frame = new JFrame(); MySimplePanel panel = new MySimplePanel(); frame.setContentPane(panel); frame.setTitle("YOLO"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); }
|
---|
Hendelsestyrte programmer
Dersom man lager en applikasjon som skal ta i mot brukerinteraksjon (trykking på knapper, tasting på tastatur, museklikk, valg i menyer, osv.), bygger dette videre på strukturen for oppbygning forklart ovenfor.
Vi ønsker å holde interaksjonen i panelet, ikke i framen.
Prinsippet bak brukerinteraksjon bygger på at man setter lyttere på komponenter på panelet sitt. Det vil si at når en knapp, tast, el. trykkes på, oppfattes dette av lytteren til denne komponenten (anse dette som automagisk inntil videre) som gir beskjed til panelet om at noe har skjedd, og hva som skjedde.
For at lytteren skal kunne gi beskjed til panelet, må det ha en metode som lytteren vet om. Panelet må derfor implementere ActionListener-interfacet, som innebærer at panelet garantert har metoden void actionPerformed(ActionEvent e).
OBS! Kjør koden, og se under for beskrivelse av sentrale kodelinjer
import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class MySimplePanel2 extends JPanel implements ActionListener { JTextArea inputText = new JTextArea("Skriv litt tekst her da vel..."); JButton btn1 = new JButton("Does nothing"); JButton btn2 = new JButton("Blanks text"); public MySimplePanel () { btn1.addActionListener(this); btn2.addActionListener(this); this.createGUI(); } private void createGUI() { setLayout(new BorderLayout()); JTextArea text = new JTextArea("Dette er South i layouten og bare til info :)"); JPanel panel1 = new JPanel(); panel1.setLayout(new BorderLayout()); panel1.add(btn2,BorderLayout.WEST); panel1.add(btn1, BorderLayout.EAST); add(panel1,BorderLayout.NORTH); add(inputText, BorderLayout.CENTER); add(text,BorderLayout.SOUTH); text.setEditable(false); } public void actionPerformed(ActionEvent e) { if (e.getSource() == btn1) { JOptionPane.showMessageDialog(null, "Did nothing!"); } if (e.getSource() == btn2) { inputText.setText(""); } } }
NB! Linjenummer i fullskjermvisning
Linje 8-11: Oppretter globale komponenter som vi må kunne nå fra hele klassen.
Linje 15-16: Etter vi har opprettet knappene btn1&2 setter vi en lytter på de. Uten denne lytteren vil det ikke sendes noen beskjed om at knappene har blitt trykket på. Parameteren her angir hvem som skal varsles om hendelsen.
Linje 24: Oppretter en komponent som ikke trenger å være global.
Linje 26-31: Oppretter ett "subpanel" og legger to knapper til Øst og Vest på dette panelet. Deretter legges "subpanelet" til helt øverst på hovedpanelet. Dvs; de to knappene vil ligge øverst på hovedpanelet, og dernest til høyre og venstre.
Linje 38: Funksjonen som lytterne kaller når brukerinteraksjoner foretas. Parameteren e er et Action-objekt som bærer info om hendelsen som har funnet sted.
Linje 40-42: Dersom kilden til hendelsen er btn1 skal det dukke opp et dialogvindu med tekst.
Linje 43-45: Dersom kilden til hendelsen er btn2 skal teksten i til inputText settes blank.