Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Generelt

Swing er et "lettvekter" API til å lage GUI for java. Swing har en Model-View-Controller GUI-arkitektur, 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"lage buttons, tekstfelt, " check boxes"boxes, " labels", tabeller og  tabeller og lister, i tillegge tillegg til en rekke andre komponenter.
For mer om komponentene og hvordan de virker, se se Swing komponenter

En kort og brukbar introduksjon til Swing kan finnes her (youtube-link).

Swing timer

Swing har en spesiell timer, som egner seg til bruk mot GUI. Veldig enkelt forklart kan man bruke en swingtimer til å få komponenter til å flytte seg med veldig små tidsintervaller, i den hensikt å få en applikasjon til å se levende ut. 

Timeren fungerer slik at vi forteller den hvor ofte den skal "pipe" og hvem den skal "pipe" til, som heretter kalles timerens mottaker.
Mottakeren har en metode som timeren kjenner til, og for hvert intervall kalles denne metoden hos mottakeren (kall av denne metoden blir altså et "pip"). 

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, ikkeframen.

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.
 

 

Code Block
languagejava
title

...

JPanel
linenumberstrue

...

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);
	}
}

 

 

Code Block
languagejava
titleJFrame
linenumberstrue
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, 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 

Code Block
languagejava
titleJPanel with ActionListener
linenumberstrue
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);
	}
// Siden klassen SwingExample skal være mottaker for timeren, må den implementere interfacet ActionListner
// som vil si at klassen lover å ha metoden "actionPerformed". Timeren vil da kalle på denne metoden som et "pip"


public class SwingExample implements ActionListener {
 
	Timer timer = new Timer(100, this); // Intervallet skal være på 100 ms, og klassen er selv mottaker
	
    public SwingExample() {
    	timer.start();  // Timeren må startes
	}
 
	// For hvert intervall kalles denne metoden, og hva metoden inneholder, avgjør funksjonen av timeren
	
	public void actionPerformed(ActionEvent aee) {
			// Flytte komponenter eller lignende
	}
 

 


		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 blankMulighetene med Swing er mange, og om man vil lære seg Swing godt, må man prøve seg fram og bruke ressurser som finnes på internett.