Sunteți pe pagina 1din 62

Proiectarea aplicațiilor orientate

obiect
Curs 13 – Swing

J
J Acest curs
› Swing
› Tratarea evenimentelor
J Swing
› O limitare a AWT este aceea ca se bazează pe sistemul de operare
pentru crearea controalelor GUI (butoane, checkbox etc.). Acest
lucru poate să difere de la un sistem de operare la altul.
J Caracteristici ale Swing
› Lightweight Components
– componente GUI nu implică sistemul de operare în creare acestora.
– Swing este parte a JFC – Java Fundation Classes
– Componente swing necesită mai puține resurse comparativ cu echivalentele lor AWT
› Pluggable Look and Feel
– Aparența poate fi separată de comportament. Acest lucru permite programatorilor să
asigneze diferite teme pentru aceeași componentă fără a-i schimba comportamentul
J Diferente AWT - Swing
J Model – View – Controller (MVC)
› Este un șablon arhitectural folosit pe larg în dezvoltare software.
› Fiecare control GUI sau componentă conține trei aspecte:
– Aparența – felul în care arată componenta când este randată pe ecran
– Felul în care componenta reacționează la acțiunile utilizatorului
– Informația de stare asociată componentei
› MVC poate fi folosit pentru a separa aceste aspecte. Odată separate,
acestea pot fi modificate separat
J MVC
› Model – gestionează
datele, logica și regulile
aplicației
› View – reprezinta datele
utilizatorului
› Controller – acceptă acțiuni
ale utilizatorului și le
convertește în comenzi
către Model și View
J Containers
› Swing furnizeaza doua tipuri de containere
– heavyweight containers (top-level containers): JFrame, JApplet, JWindow, si
Jdialog. Toate containerele mostenesc clasele AWT Component and Container
– lightweight containers: pot fi imbricate in “heavyweight containers”. Toate mostenesc
clasa JComponent: ex. JPanel
J Containers
J Containers
J Top-level Container Panes
› Fiecare top-level container definește un set de panouri. Ex. JRootPane
este unul dintre cele mai folosite panouri al cărui scop este de a gestiona
alte panouri.
› Se compune din:
– GlassPane
– ContentPane
– LayeredPane
J Panoul GlassPane
› Este un panou top-level care se află deasupra
tuturor componentelor și acoperă toate panourile
› Este o instanță transparentă a JPanel
› Este folosit pentru a:
– gestiona evenimentele generate de mouse
– desena peste orice componentă
J Panoul LayeredPane
› Este o instanță a JLayeredPane
› Permite componentelor să li se asigneze
atributul de adâncime (Z-order)
› Conține ContentPane și menu bar.
J Panoul ContentPane
› Este panoul în care sunt adaugate componentele
vizuale
› Este o instanță opacă a Jpanel

› Exemplu de pachete swing


J Exemplu de aplicatie GUI folosing JFrame
import java.awt.*;
import javax.swing.*;

public class Main extends JFrame


{
JButton b;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Labels
› Folosite pentru a afișa text static
› Constructori:
JLabel(Icon icon)
JLabel(String str)
JLabel(String str, Icon icon, int align)

› Metode:
void setText(String str)
String getText()
void setIcon(Icon icon)
Icon getIcon()
J JLabel
import java.awt.*;
import javax.swing.*;

public class Main extends JFrame


{
JLabel l;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
l = new JLabel("This is a swing label!");
add(l);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Butoane
› Pentru afișarea butoanelor se folosește JButton
› Clasa JButton implementează clasa AbstractButton care furnizează
următoarele metode:
void setDisableIcon(Icon di)
void setPressedIcon(Icon pi)
void setSelectedIcon(Icon si)
void setRolloverIcon(Icon ri)
void setText(String str)
String getText()
› Constructori:
JButton(Icon icon)
JButton(String str)
JButton(String str, Icon icon)

› Genereaza ActionEvent la apăsare ce poate fi gestionat implementând


interfața ActionListener, metoda corespunzătoare fiind actionPerformed()
J JButton
public class Main extends JFrame
{
JButton b;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
b = new JButton("swing button");
add(b);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Comutator (toggle button)
› Este creat folosind clasa JToggleButton
› Diferă față de un “push button” prin faptul că are două stări
(apăsat/ridicat sau on/off)
› Mosteneste clasa AbstractButton
› Constructori:
JToggleButton(String str)
J JToggleButton

public class Main extends JFrame


{
JToggleButton b;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
b = new JToggleButton("toggle button");
add(b);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Check boxes
› Sunt create prin intermediul clasei JCheckBox
› Moștenește clasa JToggleButton
› Generează evenimentul ItemEvent la selectare/deselectare ce poate fi
gestionat implementând interfața ItemListener și metoda
itemStateChanged()
› Se poate folosi metoda isSelected() pentru a determina dacă check
box-ul a fost selectat sau nu
› Constructori:
JCheckBox(String str)
J JCheckBox
public class Main extends JFrame {
JCheckBox c1;
JCheckBox c2;
JCheckBox c3;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
c1 = new JCheckBox("C");
c2 = new JCheckBox("C++");
c3 = new JCheckBox("Java");
add(c1); add(c2); add(c3);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Butoane radio
› Sunt folosite pentru a crea un grup de butoane care se exclud reciproc
› Clasa folosită este JRadioButton care moștenește clasa
JToggleButton
› Generează ActionEvent
› Trebuie utilizată o altă clasa ButtonGroup pentru a face butoanele să se
excludă reciproc
› Constructori:
JRadioButton(String str)
J JRadioButton
public class Main extends JFrame {
JRadioButton r1, r2;
ButtonGroup bg;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
r1 = new JRadioButton("White");
r2 = new JRadioButton("Black");
add(r1); add(r2);
bg = new ButtonGroup();
bg.add(r1); bg.add(r2);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Text fields
› Campuri de tip text care permit utilizatorului introducerea unei linii de text
› Poate fi creat prin intermediul clasei JTextField care moștenește clasa
JTextComponent
› Generează ActionEvent la apăsarea tastei “Enter”
› Poate genera și CaretEvent la modificarea poziției cursorului
› Constructori:
JTextField(int cols)
JTextField(String str)
JTextField(String str, int cols)
J JTextField
public class Main extends JFrame
{
JTextField jtf;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
jtf = new JTextField(20);
add(jtf);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Tab-uri
› Un TabbedPane este folosit pentru a gestiona un număr de
componente ca un grup
› Componente înrudite pot fi plasate pe un tab
› Crearea presupune instanțierea clasei JTabbedPane urmat de apelul
funcției:
void addTab(String tabname, Component comp)
public class Main extends JFrame
{
JCheckBox c1;

J JTabbedPane
JCheckBox c2;
JCheckBox c3;

JRadioButton r1;
JRadioButton r2;
ButtonGroup bg;

JLabel l;
JTextField jtf;

JPanel langs;
JPanel gender;
JPanel name;

JTabbedPane jtp;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
c1 = new JCheckBox("C");
c2 = new JCheckBox("C++");
c3 = new JCheckBox("Java");
langs = new JPanel();
langs.add(c1);
J JTabbedPane langs.add(c2);
langs.add(c3);
r1 = new JRadioButton("Male");
r2 = new JRadioButton("Female");
bg = new ButtonGroup();
bg.add(r1);
bg.add(r2);
gender = new JPanel();
gender.add(r1);
gender.add(r2);
l = new JLabel("Enter Name: ");
jtf = new JTextField(20);
name = new JPanel();
name.add(l);
name.add(jtf);
jtp = new JTabbedPane();
jtp.addTab("Languages", langs);
jtp.addTab("Gender", gender);
jtp.addTab("Name", name);
add(jtp);
J JTabbedPane
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J List boxes
› Componentă vizuală obișnuită din care se poate selecta un element
› Este creată prin intermediul clasei generice Jlist
JList<type>

› Unde type reprezintă tipul de date al elementelor stocate în listă


› Constructori: JList(type[] items)
– unde items este un tablou de elemente de tip type.
› După crearea unui obiect de tip JList acesta ar trebui împachetat într-un
JScrollPanel ce furnizeaza bare de defilare pentru elementele din lista
› Generează ListSelectionEvent la selectarea/deselectarea unui element din
listă
› Este gestionat prin implementarea interfeței ListSelectionListener și
metoda valueChanged()
J List boxes
› Modul de selectare poate fi setat prin apelul metodei
setSelectionMode(int mode)
› unde mode poate fi:
SINGLE_SELECTION
SINGLE_INTERVAL_SELECTION
MULTIPLE_INTERVAL_SELECTION

› Metode:
int getSelectedIndex()
E getSelectedValue()
J JList
public class Main extends JFrame {
JList<String> jl;
JScrollPane jsp;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
String[] branches = {"CSE", "ECE", "EEE", "IT", "MECH", "CIV"};
jl = new JList<String>(branches);
jsp = new JScrollPane(jl);
jsp.setPreferredSize(new Dimension(120, 80));
add(jsp);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Combo box
› Este un control de tip pop-up din care se poate selecta doar un item
› Poate fi creat prin intermediul clasei generice JComboBox
JComboBox<type>

› Constructori:
JComboBox()
JComboBox(E[] items)
› Metode: void addItem(E obj)
Object getSelectedItem()
int getSelectedIndex()
› Generează ActionEvent la selectarea/deselectarea unui element
din listă
J JComboBox
public class Main extends JFrame
{
JComboBox<String> jc;
Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
String[] branches = {"CSE", "ECE", "EEE", "IT", "MECH", "CIV"};
jc = new JComboBox<String>(branches);
add(jc);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
}
J Tabele
› Control ce poate fi folosit la afișarea datelor pe linii și coloane
› Fiecare coloană are un nume
› Poate fi creat prin intermediul clasei JTable
› Constructori:
JTable(Object[][] data, Object[] colHeads)

› unde:
– data este un tablou bidimensional care conține datele de afișat.
– colHeads este un tablou unidimensional cu denumirile coloanelor
› JTable nu furnizează și proprietatea de scroll motiv pentru care trebuie
împachetat în JScrollPanel
› Generează ListSelectionEvent la selectarea unui element din tabel și
TableModelEvent la schimbarea unei date din tabel
public class Main extends JFrame{
JTable jt;
JScrollPane jsp;
J JTable Main() {
setSize(500, 300);
setTitle("My swing window");
setLayout(new FlowLayout());
String[] colHeads = {"Student", "Mate", "Fizica", "Paoo"};
String[][] data = { {"Gica", "7.7", "8.0", "7.5"},
{"Dorel", "8.9", "8.6", "8.3"},
{"Ion", "7.4", "8.0", "7.5"},
{"Costel", "7.8", "8.0", "7.5"},
{"Marin", "8.9", "8.6", "8.3"},
{"Nicu", "7.7", "8.4", "7.2"} };
jt = new JTable(data, colHeads);
jsp = new JScrollPane(jt);
jsp.setPreferredSize(new Dimension(450, 100));
add(jsp);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Main mf = new Main();
}
J JTable
J Arhitectura bazată pe evenimente
› EDA – Event-Driven Arhitecture – reprezintă un model architectural utilizat în
multe aplicații software datorită flexibilității și capacității de a reprezenta facil
lumea reală
› EDA reprezintă un tipar arhitectural bazat pe entități de tip eveniment și acțiuni
de tip: generare/creare de evenimente, detecție de evenimente, consumare de
evenimente și începerea unui set de activități în momentul detecției unui
eveniment
› O aplicație dezvoltată pe baza acestui model arhitectural va defini și construi
următoarele entități:
– evenimente
– surse sau producători de evenimente – sources
– consumatori de evenimente – sinks
– protocol de transmitere și interpretare a evenimentelor dinspre sursa spre consumator
› Java Swing API este un framework GUI dezvoltat pe baza acestui tip de
arhitectură
J Observer Pattern
J Observer Pattern
› Entitățile de tip Observer reprezintă clasa de baza/interfața pentru orice
obiect care vrea să se înscrie ca și observator față de un anumit
Subject.
› Subject reprezinta clasa de baza pentru orice entitate care defineste
elemente de interes pentru observator.
› Subject menține o lista de entități Observer și un API (i.e. metode) care
permit:
– înregistrarea/eliminarea entităților de tip Observer în lista respectivă
– notificarea observatorilor înregistrați la momentul producerii unui eveniment de interes în
ciclul de viata al subiectului.
› O entitate de tip Observer trebuie să definească metoda notify().
Aceasta este apelată de către Subject în momentul în care dorește să
trimită o notificare către observatori. Metoda este suprascrisă în clasele
specializate ale clasei de bază Observer pentru a defini reacția potrivită
în momentul în care entitățile de tip Subject notifică evenimentele de
interes.
J Observer Pattern

public abstract class Observer {


public abstract void doNotify();
public abstract <T> void doNotify(T message);
}
class ConcreteObserver extends Observer {
String history = "";
public void doNotify() {
history += "Notified at: " +
Calendar.getInstance().getTimeInMillis() + "\n";
}
public <T> void doNotify(T message) {
history += "Notified at: " +
Calendar.getInstance().getTimeInMillis() +
"Message received: " + message + "\n";
}
}
class Subject implements Runnable {
private List<Observer> observers;
Subject() {

J }
observers = new ArrayList<Observer>();

public void registerObserver(Observer o) {


observers.add(o);
}
public void unregisterObserver(Observer o) {
observers.remove(o);
}
public void notifyAllObservers() {
for(Observer o: observers)
o.doNotify(); // apel polimorfic
}
@Override
public void run() {
// ....
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
}
notifyAllObservers();
}
J Event listeners
› Pe baza modelului arhitectural EDA și a design pattern-ului Observer,
Java Swing defineste noțiunea de Event Listener. Orice componentă
grafică poate genera evenimente atunci când:
– utilizatorul interacționează prin intermediul mouse-ului aflat deasupra componentei
– componenta deține focus-ul iar utilizatorul interacționează prin intermediul tastaturii.
› Pentru ca aplicația să poată reacționa la evenimentele generate Java
Swing permite înregistrarea unor observatori la nivelul componentelor
grafice. Acești observatori sunt denumiti în Java Swing API:
EventListener. Orice tip specializat de listener/observer extinde clasa
EventListener.
J Event listeners
› Entitățile de tip Listener ce sunt suportate de componentele grafice
definite la nivelul Java Swing API sunt de doua tipuri:
– entități Listener recunoscute de toate componentele grafice
– entități Listener recunoscute doar de anumite componente grafice (ex.
ActionListener).
Entități Listener recunoscute de toate
J componentele grafice
› ComponentListener – observă și reacționează la modificările ce apar la
nivelul dimensiunii, poziției sau vizibilității unei componente
› FocusListener – observă și reacționează la deținerea/eliberarea
focusului pentru o componentă
› KeyListener – observă și reacționează la apăsarea tastelor (doar în
cazul în care componenta deține focusul)
› MouseListener – observă și reacționează la evenimente de tip mouse
(click, move, etc)
› MouseMotionListener – reacționează la schimbarea poziției cursorului
mouse-ului deasupra componentei
Entități Listener recunoscute de toate
J componentele grafice
› MouseWheelListener – reacționează la mișcarea rotiței mouse-ului
deasupra componentei
› HierarchyListener – reacționează și observa la evenimente din
ierarhia de includere față de alte componente grafice (i.e. fiecare
componenta grafică are un context grafic înregistrat ca și părinte)
› HierarchyBoundsListener – similar HierarchyListener dar
relativ la evenimente de mutare și redimensionare.
J Model bazat pe evenimente

› Modelul bazat pe evenimente implementat pe baza EDA și Observer


Pattern în Java Swing induce mecanisme puternice și flexibile de
dezvoltare a aplicațiilor GUI.
› Astfel orice număr de entități event listener pot să asculte/observe orice
tip de eveniment de la oricate entități de tip sursa de evenimente (i.e.
orice relație de asociere între entitățile sursă și listener se poate
implementa; e.g. un event listener poate primi evenimente de la multiple
surse, o mulțime de event listeners pot primi evenimente de la o singură
sursă, etc)
J Model bazat pe evenimente
› Spre deosebire de tiparul clasic al Observer Pattern în cazul
entităților event listener din Java Swing, informația este mereu
transmisă între sursă și listener. Informația este încapsulată într-un
obiect de tip Event și conține informație relevantă despre
evenimentul produs și despre sursa care la emis.
› Pentru majoritatea evenimentelor ce pot fi regăsite la nivelul unei
aplicații GUI există o serie de event listeners și exemple/pattern-uri
de manipulare și reacționare la aceste evenimente.
J Dezvoltarea unui event listener
› Un event listener trebuie să se execute rapid deoarece toate apelurile
către metodele de redare grafică și event-listening sunt executate la
nivelul aceluiași thread.
› În cazul în care un anumit eveniment determină execuția unei secțiuni
îndelungate atunci este indicată execuția acesteia într-un nou thread
J Obiecte de tip Event
› Informația primită – sub forma de argument – la nivelul metodelor unui
event listener, este împachetată într-un obiect ce este de tipul sau
extinde EventObject. (EventObject: KeyEvent, MouseEvent,
AWTEvent, InputEvent).
› EventObject definește metoda getSource() ce returnează un Object
care încapsulează sursa care a generat respectivul eveniment.
› În cazul evenimentelor specializate se pot obține informații suplimentare
prin API-ul asociat (KeyEvent definește getKeyCode() care returnează
un întreg asociat cu key-ul acestui eveniment; apoi se poate invoca
metoda getKeyText(int keyCode) cu argument întregul returnat de
getKeyCode() și astfel se obține o reprezentare String a tastei
apasate – ex: “HOME”).
Evenimente de nivel primar și evenimente
J semantice
› Un eveniment poate fi:
– de nivel primar – low level event - acel eveniment care este lansat
la nivelul sistemului de ferestre grafice sau device-uri de tip input
(ex. mouse, tastatura).
– Semantic - acele evenimente generate fie ca urmare a unui
low-level event sau ca urmare a unei alte acțiuni sau activități
sesizate în fluxul de execuție al aplicației. (ex. un ActionEvent
lansat în urma unui click peste o componentă JButton)
J Clase adaptor – Event Adapters
› Majoritatea entităților de tip Listener se regăsesc în Java Swing API
sub forma de interfețe ce trebuie implementate în clase concrete la
nivelul aplicației.
› Unele interfețe de tip listener definesc o multitudine de metode, de
exemplu MouseListener defineste:
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)

› Implementarea tuturor acestor metode într-o clasa concretă care


implementează interfața MouseListener, clasa care tratează doar
cazul de mouse clicked, și implică:
– implementarea unor metode empty-body (ex. {})
– reducerea lizibilității codului și a mentenanței.
J public class SomeMouseListenerImpl implements MouseListener {
...
someObject.addMouseListener(this);
...
/* Empty-body method definition. */
public void mousePressed(MouseEvent e) {}
/* Empty method definition. */
public void mouseReleased(MouseEvent e) {}
/* Empty method definition. */
public void mouseEntered(MouseEvent e) {}
/* Empty method definition. */
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {
...//Event listener implementation goes here...
}
}
J
› Prin utilizarea MouseAdapter:

public class SomeMouseListenerImpl extends MouseAdapter {


...
someObject.addMouseListener(this);
...
public void mouseClicked(MouseEvent e) {
...//Event listener implementation goes here...
}
}
J Ierarhia AWTEvent
J
J
Cpntrol addXXXListener() listener.Metoda()
JButton addActionListener() actionPerformed(ActionEvent e)
JTextField
JMenuItem
JSlider addChangeListener() stateChanged(ChangeEvent e)
JCheckBox addItemListener() itemstateChanged()
Key on component addKeyListener() keyPressed(), keyReleased(), keyTyped()
Mouse on component addMouseListener() mouseClicked(), mouseEntered(),
mouseExited(), mousePressed(),
mouseReleased()
Mouse over component addMouseMotionListener() mouseMoved(), mouseDragged()
JFrame addWindowListener() windowClosing(WindowEvent e), ...
J Tratarea evenimentelor
› Procesul de gestionare a evenimentelor este cunoscut ca event handling
› Eveniment: apăsarea unui buton, modificarea textului, închiderea unei
ferestre,etc.
› Sursă: componentă care generează un eveniment.
› Interceptarea evenimentelor generate de componentele unui program se
realizează prin intermediul unor clase de tip listener
J
public class Main extends JFrame {
static JButton myButton;

J public static void main(String[] args) {


// 1. initializare frame container
Main frame = new Main();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300,300));
// 2. creare buton JButton si inregistrare MyListener
myButton = new JButton("my button");
myButton.setPreferredSize(new Dimension(100, 30));
myButton.addActionListener(new MyListener());
// 3. adaugare buton pe interfata
frame.getContentPane().add(myButton);
frame.setVisible(true);
}
}
class MyListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}

S-ar putea să vă placă și