Graphical User Interface (GUI) - Java Swing și JavaFX

De la WikiLabs
Jump to navigationJump to search

În multe dintre aplicațiile pe care le veți dezvolta folosing Java, veți avea nevoie și de o interfață grafică adecvată: ferestre, butoane, câmpuri de editare, checkbox­uri, etc. Există mai multe biblioteci de dezvoltare pentru interfețe grafice, cea mai cunoscută fiind Java Swing și cea mai nouă fiind JavaFX.

Java Swing

Pachetul care conține majoritatea claselor pentru aplicațiile Swing este java.swing dar sunt utilizate și multe din clasele din vechea biblotecă GUI, java.awt. Clasa principală pentru aplicații Java Swing este clasa javax.swing.JFrame.

Frame-ul este fereastra principală a unei interfețe grafice. Este elementul care are asociată bara de deasupra, care conține icon-ul, numele aplicației și cele trei butoane: minimize, maximize, close:

Exemplu de frame fără elemente

În continuare este prezentat un frame ce conține cele mai utilizate componente Swing:

Exemplu de frame cu elemente

Componente

Toate obiectele Swing, cu excepția clasei JFrame, moștenesc clasa javax.swing.JComponent, care la rândul ei moștenește (indirect) clasa java.awt.Container. Astfel, se creează o ierarhie de componente, fiecare element (numit parent) înglobând alte sub-componente (numite children). În continuare se vor prezenta elementele necesare realizării temei 6. Pentru descrierea altor elemente mai avansate, citiți tutorial-ul Oracle.

javax.swing.JPanel

JPanel este un container generic care poate conține alte elemente. Poate fi vizibil, schimbându-i-se culoarea background-ului, sau modelul marginii, sau invizibil, folosit doar pentru ierarhizarea conținutului. Este indicat să nu plasați alte obiecte direct pe un JFrame, ci doar un JPanel care să conțină restul de elemente. Acest lucru este foarte util și când aveți nevoie să schimbați complet elementele dintr-un JFrame, înlocuiți doar JPanel-ul.

javax.swing.JLabel

JLabel este un component utilizat pentru a afișa text sau imagini într-un container.

javax.swing.JButton

JButton este, cum îi spune și numele, un buton. Acesta poate avea afișat un text sau o imagine. De cele mai multe ori este utilizat asociindu-i-se un Event Handler de tip ActionListener (vezi #Event Handlers) care se declanșează când acesta este apăsat (se dă click pe el).

javax.swing.JTextField

JTextField reprezintă o zonă în care se poate introduce text scurt, de o singură linie. Și acestul element i se poate asocia un Event Handler de tip ActionListener care se declanșează când se apasă tasta Enter în zona de editare.

javax.swing.JTextArea

JTextArea reprezintă o zonă în care se poate introduce text de mai multe linii.

Layouts

O altă serie de clase necesară pentru implementarea unei interfețe grafice este setul de clase care extind interfața java.awt.LayoutManager. Aceste clase descriu modul în care elementele se așează într-un Container. Cele mai importante sunt:

java.awt.FlowLayout

FlowLayout este utilizat pentru a așseza elementele pe orizontală, până când nu mai încap, în care situație se trece pe rândul următor. Acesta este cel mai simplu tip de layout.

java.awt.GridLayout

GridLayout este utilizat pentru a așseza elementele într-o matrice cu număr configurabil de linii și coloane.

java.awt.BorderLayout

BorderLayout este utilizat pentru a așseza elementele dealungul celor patru margini și în centru, adică NORTH, SOUTH, EAST, WEST și CENTER. Un singur element poate fi plasat în fiecare din aceste poziții.

java.awt.CardLayout

CardLayout este utilizat pentru a adăuga mai multe componente unui Container din care doar unul este vizibil la un moment dat. Acest tip de layout este util pentru generarea de aplicații tip wizard în care utilizatorul trece de la o fereastră la alta cu ajutorul unor butoane Next și Previous.

Mai multe despre elemente de tip Layout, în tutorial-ul Oracle.

Event Handlers

Fiecare JComponent suportă o listă de evenimente la care e sensibil. Fiecărui eveniment i se poate asociaza o acțiune care se execută când acel eveniment se declanșează. De exemplu, când un buton este apăsat, sau când cursorul de la mouse a intrat în zona ocupată de componentă, sau când s-a tastat ceva într-o zonă de text, etc. Aceste handler-e sunt, de fapt, niște metode, definite în anumite interfețe. Aceste metode se excută în paralel cu programul principal (ca și thread-uri) în momentul în care evenimentul se declanșează. Metodele care adaugă un handler unui obiect sunt de forma:

  • public void addActionListener(ActionListener _listener) - pentru evenimente de tip action, adică activarea unui component (click pe un buton, enter într-un text field, etc.);
  • public void addMouseListener(MouseListener _listener) - pentru evenimente legate de mouse;
  • etc.

Același handler poate fi asociat mai multor elemente, iar în acest caz, pentru a știi care obiect a generat evenimentul, se folosește metoda getSource() definită în clasa java.util.EventObject care este superclasă pentru toate obiectele primite ca argumente de metode de tip handler (java.awt.event.ActionEvent, java.awt.event.MouseEvent, etc.). Metoda getSource() întoarce o referință de tip Object la componenta de interfață care a generat evenimentul.

Mai multe despre handler-e, în tutorial-ul Oracle.

Exemplu

Vom descrie un JFrame care conține două JLabel, două JTextField, un JTextArea și un JButton. Când se apasă butonul, cele două JTextField se vor încărca cu valorile dimensiunii JFrame-ului și se va scrie un caracter x în JTextArea:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class FrameTest extends JFrame implements ActionListener {

    // we define the elements used in
    // the frame
    private JPanel mainPanel;
    private JLabel xLabel;
    private JLabel yLabel;
    private JTextField xField;
    private JTextField yField;
    private JTextArea textArea;
    private JButton button;
    
public FrameTest(String _title){
    // calling the constructor for JFrame to set the title
    super(_title);
    
    // initializing the components (method is implemented below)
    initComponents();
    
    // calling pack() defined in superclass to resize the frame according to
    // contents
    pack();
    
    // displaying the frame (defined in superclass)
    setVisible(true);
}

public static void main(String[] _args){
    FrameTest _frame = new FrameTest("Frame Test");
}

private void initComponents() {
    // setting the layout as FlowLayout
    setLayout(new FlowLayout());
    
    // creating the components
    
    // the panel adds the components in
    // a FlowLayout
    mainPanel = new JPanel(new FlowLayout()); 
    xLabel = new JLabel("X size (width):");
    yLabel = new JLabel("Y size (height):");
    xField = new JTextField(6); //6 columns (characters)
    yField = new JTextField(6); //6 columns (characters)
    textArea = new JTextArea(10, 10); //10 columns, 10 rows
    button = new JButton("Click me!");
    
    //adding components to panel
    mainPanel.add(xLabel);
    mainPanel.add(xField);
    mainPanel.add(yLabel);
    mainPanel.add(yField);
    mainPanel.add(textArea);
    mainPanel.add(button);
    
    //adding panel to frame
    add(mainPanel);
    
    // adding the listener to the button Component
    button.addActionListener(this);
}

// this is the handler defined in the ActionListener interface
public void actionPerformed(ActionEvent _actionEvent) {
    xField.setText(String.valueOf(this.getWidth()));
    yField.setText(String.valueOf(this.getHeight()));
    textArea.append("x");
}
    
}

Rezultatul arată așa:

Codul de mai sus, rulat

Pentru a crea frame-uri mai complexe, trebuie să folosiți alte tipuri de LayoutManager, elemente de tip javax.swing.JScrollPane, sau, puteți utiliza un mediu de dezvoltare, gen Netbeans pentru a crea în mod vizual interfața.

JavaFX