Programmeren in Java/GUI
AWT
[bewerken]De Abstract Window Toolkit (AWT) is de platformonafhankelijke verzameling van klassen die een beroep doen op de grafische mogelijkheden van het onderliggende besturingssysteem, waardoor toch een platformafhankelijk uitzicht ontstaat.
Swing
[bewerken]Swing werd later ontwikkeld. De soms bedroevende grafische componenten van AWT (knoppen, vensters, navigatiebalken, ...) werden geherdefinieerd in Swing. In tegenstelling tot AWT, waar elk grafische element een resource van het besturingssysteem is, heeft Swing een eigen cross-platform library. Hierdoor biedt Swing een hogere diversiteit aan componenten.
Het basisvenster wordt nog altijd opgevraagd aan het besturingssysteem, maar de GUI-componenten worden hierop getekend. De onderliggende structuren van AWT werden echter niet verdrongen:
- helper-classes
- Graphics
- Color
- Font
- FontMetrics
- LayoutManagers
- eventmodel
Daarom worden altijd beide packages (javax.swing en java.awt) geïmporteerd.
Basisstructuur
[bewerken]Java-code: basisvenster.java
import javax.swing.*;
import java.awt.*;
public class HelloWorld extends JFrame{
private JTextField textField;
public static void main(String[] args) {
HelloWorld frame = new HelloWorld();
frame.setSize(300,200); // Standaard = .setSize(0,0)
frame.createGUI();
frame.setVisible(true); // Standaard = setVisible(false)
}
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE); // Anders blijft het programma op de achtergrond lopen
Container window = this.getContentPane();
window.setLayout(new FlowLayout());
textField = new JTextField("Hello World !");
window.add(textField);
}
}
Alle klassen uit de swing-bibliotheek hebben een naam die begint met een J: JButton behoort tot Swing, Button tot AWT.
Java-code: Hallo.java
import javax.swing.*;
public class HalloWereldSwing {
/**
* Maak de GUI en laat het zien.
*/
private static void createAndShowGUI() {
//Hier zorgt Java dat het er goed uit komt te zien.
JFrame.setDefaultLookAndFeelDecorated(true);
//Maak het venster.
JFrame frame = new JFrame("HalloWereldSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Laat de tekst zien.
JLabel label = new JLabel("Hallo Wereld!");
frame.getContentPane().add(label);
//Laat het venster zien.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Events
[bewerken]Een event is iets wat de gebruiker doet, en waarop het programma kan reageren, bvb. het klikken op een knop. Om hiervan gebruik te kunnen maken, wordt met import java.awt.event.* en import javax.swing.event.* het bijhorende package geïmporteerd, respectievelijk voor componenten met en zonder een overeenkomstig AWT-equivalent. De laatste groep bevat o.m. JSlide. Dit wordt gecombineerd met implements ActionListener dat de implementatie van een methode actionPerformed(ActionEvent e) vereist.
Java-code: actieKnoppen.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class actieKnoppen extends JFrame
implements ActionListener{
private JTextField tekstveld;
private JLabel tekst, melding;
private JButton knop;
public actieKnoppen() { // constructor
setSize(500, 250);
setTitle("Titeltekst");
//setResizable(false); // voorkomt herschalen
}
public static void main(String[] args) {
actieKnoppen venster = new actieKnoppen();
venster.createGUI();
venster.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container venster = this.getContentPane();
venster.setLayout(new FlowLayout() );
JPanel bladhoofd = new JPanel(); // hulpconstructie
{
tekst = new JLabel("Geef uw keuze: ");
tekstveld = new JTextField(20);
knop = new JButton("Kies");
melding = new JLabel();
bladhoofd.add(tekst);
bladhoofd.add(tekstveld);
bladhoofd.add(knop);
}
venster.add(bladhoofd);
venster.add(melding);
knop.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
String tkt = "U koos: " +
tekstveld.getText();
melding.setText(tkt);
}
}
In bovenstaand voorbeeld wordt eerst het bladhoofd gevuld, en wordt dit vervolgens toegevoegd aan het venster. Dit kan van belang zijn als je een bepaalde schikking wil bekomen (zie verder: FlowLayout).
Tekenen kan je met objecten uit de Graphics class: drawString(), drawRect() en fillRect(), drawOval() en fillOval(), drawLine(), drawPolygon() en fillPolygon(), setColor(), setBackground(), ...
Java-code: tekenblad.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class tekenblad extends JFrame implements ActionListener {
private int breedte = 350, hoogte = 50, horizontaal = 0, verticaal = 10;
private JButton knop1, knop2;
private JPanel blad;
private Graphics g;
public tekenblad() {
setSize(breedte + 100, hoogte + 100);
setTitle("tekenblad");
}
public static void main(String[] args) {
tekenblad frame = new tekenblad();
frame.createGUI();
frame.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container venster = this.getContentPane();
venster.setLayout(new FlowLayout() );
JPanel knoppen = new JPanel();
venster.add(knoppen);
knop1 = new JButton();
knop1.setText("1");
venster.add(knop1);
knop1.addActionListener(this);
knop2 = new JButton();
knop2.setText("2");
venster.add(knop2);
knop2.addActionListener(this);
blad = new JPanel();
blad.setPreferredSize(new Dimension(breedte,hoogte));
venster.add(blad);
}
public void actionPerformed(ActionEvent e){
horizontaal += 10;
if (horizontaal > breedte) {
horizontaal = 0;
verticaal += 15;
}
String tekst;
if (e.getSource() == knop1) {tekst = "1";}
else {tekst = "" + e.getActionCommand();} // Neemt de tekst op de knop
g = blad.getGraphics();
g.drawString(tekst,horizontaal,verticaal);
}
}
Andere grafische objecten die gevoelig zijn voor events zijn: JList met bijhorende public void valueChanged(ListSelectionEvent e), JScrollPane, JComboBox, JTextArea, JRadioButton, JOptionPane (showConfirmDialog: yes/no/cancel, showInputDialog, showMessageDialog: OK), JMenu (> JMenu > JMenuItem), JSlider, JTabbedPane, JFileChooser, JProgressBar, JColorChooser, ...
De eventlisteners kunnen zijn: ActionListener, AdjustmentListener, ComponentListener, ContainerListener, FocusListener, KeyListener, MouseListener, MouseMotionListener, WindowListener, JFrame, JDialog, JfileDialog, ItemListener, JComboBox, JList, JcheckBoxMenuItem, TextListener, ...
WindowAdapter en MouseAdapter kunnen het aantal te specifiëren klassen beperken met extends:
Java-code: kliklijst.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class kliklijst extends JFrame {
private JList keuzelijst;
private DefaultListModel lijst;
public kliklijst() {
setSize(500, 300);
setTitle("aan te klikken lijst");
}
public static void main (String[] args) {
kliklijst frame = new kliklijst();
frame.createGUI();
frame.setVisible(true);
}
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = this.getContentPane();
window.setLayout(new FlowLayout());
lijst = new DefaultListModel();
lijst.addElement("voorgerecht");
lijst.addElement("hoofdgerecht");
lijst.addElement("nagerecht");
keuzelijst = new JList(lijst);
JScrollPane metSchuif = new JScrollPane(keuzelijst);
window.add(metSchuif);
keuzelijst.addMouseListener(new muisvoeler());
}
class muisvoeler extends MouseAdapter {
public void mouseClicked (MouseEvent e)
{
Object[] keuze = keuzelijst.getSelectedValues();
for (int i=0; i<keuze.length; i++) {
System.out.println(keuze[i].toString());
}
lijst.addElement("water");
}
}
}
Layout
[bewerken]De schikking van de grafische elementen kan gebeuren met LayoutManager:
- FlowLayout
- BorderLayout
North Left Center Right South
- GridLayout
- GridBagLayout
- BoxLayout
- CardLayout: tabbladen