Curs Swing

Post on 20-Oct-2015

35 views 0 download

transcript

Swing

Curs 9

Cuprins Introducere

Arhitectură

Modelul root pane container

Fire de execuţie Swing

Componente

AWT – Abstract Windows Toolkit Primul API Java utilizat pentru construirea de aplicaţii GUI

Oferă Mecanism robust de tratare a evenimentelor Manageri de layout

Dezavantaje: Portabilitate

Limitări legate de modul nativ în care se generează componentele (ex. pe Window foloseşte DirectX pentru generarea componentelor)

Facilităţi Nu suportă toate componentele (ex. tooltips, icoane)

Swing Un set de componente grafice customizabile al căror look-

and-feel este stabilit la runtime

Prima versiune oficială 1998

Versiune Java > 1.1.5

Corectează deficienţele AWT

Numele componentelor încep cu “J”

Noutăţi Swing vs AWT Acţiuni

Model de sincronizare al acţiunilor Tooltips Timers

Util pentru animaţie Event dispathcer thread Proprietăţi client Keyboard shortcuts

Managementul focusului, mnemonice şi acceleratori pentru meniuri, keymaps Contururi (borders) Icoane Cursori Double-buffering Containerul Box

Dimensiunile minime, maxime şi preferate ale componentelor Ferestre de dialog simple Componente

JFileChooser, JColorChooser, JTable (TableModel), ...

Componente AWT/Swing Componentele AWT Componente heavyweight Sunt asociate cu componentele native denumite peers Au acelaşi comportament dar look and feel care depinde de

platformă java.awt

Componentele Swing Componente lightweight Modul în care sunt desenate (renderizate) este controlat de

JVM javax.swing

Componente AWT/Swing Diferenţe componente heavyweight/lightweight Componentele lightweight pot conţine pixeli transparenţi, componentele

heavyweight sunt opace

Componentele lightweight pot avea alta formă decât dreptunghiulară deoarece conţin pixeli transparenţi, în schimb componentele heavyweight sunt doar dreptunghiulare

Evenimentele de mouse în cazul componentelor lightweight sunt tratate prin intermediul componentelor părinte, în schimb în cazul componentelor heavyweight nu sunt tratate prin intermediul componentelor părinte

În versiunile de Java mai mici de 1.7, când o componentă leightweight se suprapune pe una heavyweight, componenta heavyweight este totdeuna deasupra

Cuprins Introducere

Arhitectură

Modelul root pane container

Fire de execuţie Swing

Componente

Model View Controller Şablon arhitectural care separă nivelul de prezentare

de logica de business

Componentele Swing folosesc patternul MVC Model

Încapsulează starea datelor pentru fiecare componentă View

Modul în care se vede componenta pe ecran

Controler Modul în care interacţionează componenta cu evenimentele (tastatură, mouse, focus, etc)

Model

Controller

View

Model View Controller Şablonul este puţin diferit faţă de cel clasic Nu există o separare clară între View şi Controller Separarea de model este clară

Model View Controller MV/C

Pentru componentele mai simple se foloseşte de obicei modelul default

MVC Componente mai complexe

JList JTable JTree

JComponent

Swing Model(s)

View

Controller reporteză

referă la

modifică

Modelul Fiecare componentă are clasa ei de model JTable are TableModel

Modelul este responsabil cu oferirea de date componentei

De fiecare dată când modelul se modifică se notifică toţi ascultătorii prin lansarea unui eveniment

Putem folosi modele Default Implementa propriile modele, dacă ne asigură un mai bun control al

datelor în interiorul componentei

View Fiecare componentă are propria clasă de view Responsabilă cu desenarea componentei Numite UI Delegate

Exemplu: ButtonUI, SliderUI, etc

Unele din proprietăţile viewului se regăsesc în clasa Component Exemplu: proprietăţile de font, background, mărime

Root Pane Gestionează Content pane Bara de meniuri Alte containăre

Cuprins Introducere

Arhitectură

Modelul root pane container

Fire de executie Swing

Componente

Regula threadu-ului Unic Metodele componentelor AWT sunt thread safe accesul concurent la componente nu le vor afecta starea

Componentele Swing nu sunt thread safe din motive

de eficienţă Odată ce o componentă Swing este pregătită să primească

evenimente, tot codul care poate afecta sau depinde de starea componentei trebuie să fie executat în event dispatching thread

Unele din metode, de exemplu repaint(), revalidate(), invalidate(), metodele ce modifică listele de listeners, au rămas thread safe fiind tratate de event thread

Event-Handling Thread Event Thread este pornit automat de JVM când o

aplicaţie conţine componente grafice

Responsabil pentru apelul metodelor paint() actionPerformed() Restul de metode care se ocupă de tratarea acţiunilor

Permite modificarea sigură (safe) a componentelor

Regula threadu-ului Unic Rezolvarea problemei modificării componentelor de

un fir de execuţie extern Mecanism de adăugare a unei bucăţi de cod în coada de

evenimente Când thread-ul event ajunge la acest cod se blochează şi

execută codul

SwingUtilities public static void invokeLater( Runnable r)

Dacă nu se doresc rezultatele înainte de a contiunua cu restul de taskuri şi nu ne interesează când taskul se termină

public static void invokeAndWait( Runnable r) Dacă avem nevoie de rezultate înainte de a continua cu restul de

taskuri

Cuprins Introducere

Arhitectură

Modelul root pane container

Fire de executie Swing

Componente

Crearea unei aplicaţii Crearea:

Frame/JFrame Panel/JPanel Componente Listenere

Adăugarea: Listenere la componente Componente într-un panel Panel într-un frame

JPanel

JButton

Listener

JFrame

JLabel

Containere intermediare Containere intermediare JPane JScrollPane JSplitPane JTabbedPane

Utilizate pentru a grupa componente

Layoutul default FlowLayout

JPane Containerul intermediar de bază pentru orice interfaţă grafică

Cel mai des utilizat pentru a organiza un grup de componente

Panoul implicit al unei ferestre este contentPane, al cărui

layout implicit este BorderLayout

Metode Setare layout Gestionare componente (adăugare/ştergere) Setare border

JScrollPane Dă posibilitatea altor componente de a se derula (scroll)

dacă nu încap într-o zonă de dimensiune fixă Exemplu

JTextArea textArea = new JTextArea(5, 5); JScrollPane scrollableTextArea = new JScrollPane(textArea); scrollableTextArea.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); scrollableTextArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SC add(scrollableTextArea);ROLLBAR_ALWAYS);

JSplitPane Încapsulează două panouri alăturate separate printr-un marcaj

despărţitor (divider), permiţând vizualizarea simultană a două componente una lângă alta

Metode pentru adăugarea de componente setTopComponent() setLeftComponent() setBottomComponent() setRightComponent()

Exemplu

JPanel panel1 = new JPanel(); JPanel panel2 = new JPanel(); JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2); splitPane.setDividerLocation(0.25);

JTabedPane Stivă de componente aşezate pe mai multe straturi

suprapuse

Metode addTab() removeTabAt() setSelectedIndex()

Nu este prezent în AWT Similar cu FlowLayout

JTabedPane Exemplu

JTabbedPane tabbedPane = new JTabbedPane(); ImageIcon icon = createImageIcon("images/middle.gif"); JComponent panel1 = makeTextPanel("Panel #1"); tabbedPane.addTab("Tab 1", icon, panel1,"Does nothing"); tabbedPane.setMnemonicAt(0, KeyEvent.VK_1); JComponent panel2 = makeTextPanel("Panel #2"); tabbedPane.addTab("Tab 2", icon, panel2, "Does twice as much nothing"); tabbedPane.setMnemonicAt(1, KeyEvent.VK_2); tabbedPane.setSelectedIndex(2); add(tabbedPane);

Componente Simple Etichete

Butoane

Borduri

Liste

Drop down list

Spinner

Etichete JLabel Poate interpreta cod HTML

Utile pentru a afişa Text Imagini

label1 = new JLabel("Image and Text", icon, JLabel.CENTER); label1.setVerticalTextPosition(JLabel.BOTTOM); label1.setHorizontalTextPosition(JLabel.CENTER); label2 = new JLabel("Text-Only Label"); label3 = new JLabel(icon);

JLabel l = new JLabel("<html><center><b>Label</b><br><font color=#ff00ff>HTML Format</font></html>");

Butoane JButton

JCheckbox

JRadioButton

JMenuItem

JCheckBoxMenuItem

JRadioButtonMenuItem

JToggleButton

Butoane Realizează acţiuni

Pot fi grupate ButtonGroup

Se pot adăuga Imagini HTML text Mnemonice

Stările butoanelor Selectat (selected)

Apăsat (pressed)

Derulat (rollover)

Armat (armed)

Activat (enabled)

Exemple Butoane Simple Butoane - new JButton("Buton Simplu"); Adăugare de icoane

Modificarea modului cum arată Utilizare HTML - add(new

JButton("<html><b><u>T</u>wo</b><br>lines</html>"));

Radio/CheckboxButtons

btnCuPoza = new JButton("Buton cu Poza"); btnCuPoza.setIcon(new ImageIcon(getImage(getCodeBase(), "../img/butoane/icon1.JPG"))); btnCuPoza.addActionListener(this); btnCuPoza.setHorizontalTextPosition(SwingConstants.LEFT); btnCuPoza.setMnemonic(KeyEvent.VK_P);

Exemple Butoane Simple Modificarea modului cum arată

btn = new FancyButton(new ImageIcon(getImage(getCodeBase(), "../img/butoane/icon1.JPG")), new ImageIcon(getImage( getCodeBase(), "../img/icon2.JPG")), new ImageIcon(getImage(getCodeBase(), "../img/butoane/icon3.JPG"))); btn.setText("FancyButton"); btn.setIcon(new ImageIcon(getImage(getCodeBase(), "../img/butoane/icon1.JPG")));

public class FancyButton extends JButton { public FancyButton(Icon icon, Icon pressed, Icon rollover) { super(icon); setFocusPainted(false); setRolloverEnabled(true); setRolloverIcon(rollover); setPressedIcon(pressed); setBorderPainted(false); setContentAreaFille(false); }

Exemple Radio/CheckboxButtons

r1 = new JRadioButton("Icoana vizibila cand butonului nu este afisat"); r1.setActionCommand("1"); r1.setSelected(true); panelButone.add(r1); r2 = new JRadioButton("Icoana vizibila la trecerea peste buton"); r2.setActionCommand("2"); panelButone.add(r2); r3 = new JRadioButton("Icoana vizibila la apasarea butonuluit"); panelButone.add(r3); ButtonGroup group = new ButtonGroup(); group.add(r1); group.add(r2); group.add(r3); JCheckBox cb1 = new JCheckBox("Rosu");

Exemplu ToolgeButton JToggleButton redButton = new JToggleButton("red");

Borduri Borders

Nu sunt derivate din JComponent, nu li se pot adăuga ascultători

Borduri standard

CompoundBorder EmptyBorder EtchedBorder LineBorder MatteBorder SoftBevelBorder TitledBorder

BorderFactory

setBorder()

Borduri

Borduri Exemplu

Border outline = BorderFactory.createLineBorder(Color.black); JLabel northLabel = new JLabel("NORTH"); northLabel.setHorizontalAlignment(SwingConstants.CENTER); northLabel.setBorder(outline);

JList Permite selectarea unui/sau mai multor elemente dintr-o listă SINGLE_SELECTION SINGLE_INTERVAL_SELECTION MULTIPLE_INTERVAL_SELECTION

Obiectele sunt afişate prin apelul la metoda toString() Excepţie: clasa Icon

Modelul DefaultListModel AbstractListModel

Evenimente ListSelectionListener

JComboBox Combină un buton cu o listă (intern popup)

Modele de date DefaultComboBoxModel MutableComboBoxModel

Permite operaţii de adăugare/ştergere/modificare

Evenimente ChangeListener

Tipuri Combobox Combobox editabil

Exemplu final JComboBox<Culoare> cb = new JComboBox<Culoare>(); cb.addItem(new Culoare ("Rosu", Color.red)); cb.addItem(new Culoare ("Gri",Color.gray)); cb.addItem(new Culoare ("Verde",Color.green)); cb.addItem(new Culoare ("Albastru",Color.blue)); cb.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent ie) { Culoare color = (Culoare) cb.getSelectedItem(); lText.setBackground(color.color); lText.updateUI(); } });

JSpinner Reprezintă o linie de text care permite utilizatorului să

selecteze o valoare dintr-o secvenţă de valori

Selectare Utilizând săgeţi Introducerea directă a unei valori

Modele SpinnerListModel AbstractSpinnerModel SpinnerDateModel SpinnerModel SpinnerNumberMode

Componente complexe Componente text

Tabele

Arbori

Componente Text Afişează şi permit editarea textului

Componente Text Conţinutul este menţinut într-o instanţă a interfeţei

document PlainDocument StyledDocument

Sistemul de copiere/lipire implementat în

JTextComponent copy() cut() select(int pozInt, int pozFin) selectAll()

Tabele JTable

Afişarea datelor în tabele

Proprietăţi

Utilizatorul poate să Selecteze linii, coloane sau capul tabelului (header) Reordoneze coloane prin mutarea header-ului Redimensioneze coloane prin mutarea marginii dintre coloane Editeze valorile celulelor Sorteze coloanele pe baza conţinutului Filtreze coloanele pe baza conţinutului

Codul poate să

Modifice valorile celulelor Adauge/şterge/mutearea de coloane Customizeze modul în care se desenează tabelul Customizeze modul de editare al tabelului

Tabele - Clase relaţionate

Tabele JTable conţine multe proprietăţi care pot fi customizate, precum editarea

sau desenarea celulelor, dar de asemenea oferă valori default pentru aceste

O componentă Jtable este formată din: Linii de date Coloane cu date Headere de coloane Un editor dacă dorim ca celulele să fie editabile TableModel, de obicei subclasă a clasei AbstractTableModel care conţine datele

tabelului TableColumnModel, de obicei DefaultTableColunModel, care controlează

comportamentul coloanelor tabelului şi ne dă acces la ele ListSelectionModel, de obicei DefaultListSelectionModel, care menţine informaţii

despre liniile selectate din tabel TableCellRenderere, de obicei DefaultTableCellRenderer, care oferă informaţii

despre modul în care se desenează celulele MultipleTableColums, stochează informaţii despre fiecare coloană JTableHeader afişează headerul

TableModel Gestioneză datele afişate în tabel Metode Class getColumnClass(int columnIndex)

Utilizat de renderer şi editor

boolean isCellEditable(int rowIndex, int columnIndex) Object getValueAt(int rowIndex, int columnIndex) void setValueAt(Object aValue, int rowIndex, int

columnIndex) Apelată de JTable când au loc editări

void addTableModelListener (TableModelListener l) Notificări ale datelor şi sturucturi tabelului

TableModel AbstractTableModel defaulats

Clasa obiectului este raportată ca fiind de tip Object Coloanele au un nume default dacă nu se specifică unul Celulele nu sunt editabile

Trebuie suprascrise metodele

int getRowCount(); int getColumnCount(); Object getValueAt(int rowIndex, int columnIndex

TableModel DefaultTableMode Stochează datele în vectori

Un vector pentru fiecare coloană

defaulats

Clasa obiectului este raportată ca fiind de tip Object Coloanele au un nume default dacă nu se specifică unul Celulele nu sunt editabile

ColumModel Încapsulează informaţii despre:

Valorile header-elor Dimensiuni Modul de desenare Modul de editare Permite redimensionarea coloanelor

JTree Permite vizualizarea structurilor arborescente

Are un singur nod rădăcină

Mecanism de selecţie asemănător cu al componentei JList

Dialoguri default JOptionPane

JFileChooser

JColorChooser

JOptionPane Permite realizarea facilă de dialoguri simple Afişarea unui mesaj Punerea unei întrebări Introducerea unei valori

Ferestre modale Blochează aplicaţia în aşteptarea unui răspuns

JOptionPane Tipuri Mesaj

showConfirmDialog()

Confirmare showInputDialog()

Intrare

showMessageDialog()

Opţiune showOptionDialog()

JFileChooser Componentă care permite navigarea prin sistemul de

fişiere Salvare Deschidere

JFileChooser files = new JFileChooser(DEFAULT_DIRECTORY); int result = files.showSaveDialog(frame); File f = files.getSelectedFile();

File Chooser Filtre pentru fişiere FileNameExtensionFilter Crearea propriului filtru prin extinderea clasei FileFilter

FileFilter filter = new FileNameExtensionFilter (“Text files (*.txt)”, ” txt” ); files.addChoosableFileFilter(filter);

JColorChooser Permite alegerea de culori

Moduri disponibile Swatches HSV —Hue-Saturation-Value RGB —Red-Green-Blue HSL —Hue-Saturation-Lightness CMYK – Crayn-Magenda-Yellow-Black

Componente pentru progres şi derulare JSlider

JScrollBar

JProgressBar

JToolTip

Slider JSlider

Utilizat în special dacă avem nevoie să alegem valori din

intervale de numerice cunoscute

Proprietăţi Orientation Extent

Numărul de valori sărite prin folosirea tastelor pageUp şi pageDown minorTickSpacing majorTickSpacing paintTicks paintLabels inverted

Progress Bar JProgressBar

Folosită pentru a indica progresul unei operaţii

consumatoare de timp

Monitorizarea activităţii se face prin metoda setValue()

Bară de defilare JScrollBar

De obiecei se ataşează componentelor pentru a derula

mai uşor conţinutul

Proprietăţi Orientarea Locul unde este poziţionat iniţial indicatorul Mărimea indicatorului

ToolTip JToolTip

Ferestre care permit asocierea de informaţii textuale componentelor aplicaţiei

Vizibile când mouse-ul se află deasupra componentei

void setToolTipText( String text)

Se activează dacă mouseul rămâne 750 ms asupra componentei

Rămâne activat 4000 ms

Dacă intrăm, ieşim din componetă se activează în 500 ms

Perioadele de timp pot fi modificate prin intermediul clasei ToolTipManager

setInitialDelay(), setDismissDelay(), setReshowDelay()

Meniuri Java permite crearea de Bare de meniuri

JMenuBar,

Meniuri JMenu, JMenuItem, JSeparator, JCheckBoxMenuItem,

JRadioButtonMenuItem

Meniuri Popup JPopupMenu

Bare de acţiuni (tool bars) JToolBar

Componentele meniurilor

Meniuri Ierarhia de clase

Meniuri Evenimente

Mouse

Tastatură

Combinaţie de taste echivalentă (mnemonice) Prima literă din submeniu

Acceleratori Permit accesarea directă a unui submeniu

Construirea unui meniu Construire bară meniu:

MenuBar bara = new MenuBar();

Construire meniu Menu meniu = new Menu(“Exemplu”);

Construire elemente şi adăugare la meniu:

meniu.add(new MenuItem(“intrare 1”)); meniu.addSeparator(); meniu.add(new MenuItem(“intrare 2”));

Adăugarea fiecărui meniu la bara meniu:

bara.add(meniu);

Adăugarea barei de meniu la frame: Frame frame = new Frame(“Titlu”); frame.setMenuBar(bara);

Layout-uri Spring BoxLayout Componentele sunt aşezate sub forma unei stive una peste

alta şi pot fi afişate pe orizontală sau verticală GroupLayout Grupează ierarhic componente pentru a le poziţiona în

container SpringLayout Defineşte relaţii (constrângeri) direcţionale între muchiile

componentelor

Alte posibilităţi Crearea de layout customizat Poziţionarea absolută

Look & Feel Swing permite modificarea modului în care arată

componentele Look – se referă la modul cum arată componentele Feel – modul în care se comportă componentele

Tipuri CrossPlatformLookAndFeel

Java L&F - Metal SystemLookAndFeel

L&F nativ sitemului pe care rulează aplicaţia Synth

Creare propriului L&F prin intermediul fişierelor XML Multiplexing

Utilizarea de mai multe L&F în accelaşi timp

Exemple de setare L&F Specificare din program L&F java

UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName());

L&F platformei UIManager.setLookAndFeel(

UIManager.getSystemLookAndFeelClassName());

Specificarea din linia de comanda java -

Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel MyAp

Creare de custom L&F Utilizare L&F Synth Programatic

Moştenirea clasei SynthStyleFactory

Fişiere XML

javax.swing.plaf.synth/doc-files/synthFileFormat.html

class MyStyleFactory extends SynthStyleFactory { public SynthStyle getStyle(JComponent c, Region id) { if (id == Region.BUTTON) { return buttonStyle; } else if (id == Region.TREE) { return treeStyle; } return defaultStyle; } }

Alte facilităţi Alte facilităţi

Gestionarea focusului

Dialoguri

Tipărirea tabelelor

Crearea de splash screens

Ferestre de dialog Dialog Box O fereastră de nivel înalt care are un tilu şi margini şi colecteză

informaţii de la utilizator

Modlă sau nemodală Modal Dialog Box Blochează inputul la ferestrele aplicaţei până când nu este închisă

Modeless Dialog Box Fereastră de dialog care permite operarea cu alate ferestre ale aplicaţiei

cât timp este deschisă

Ferestre de dialog Tipuri (java 1.6) Modeless

Nu blochează nici o altă fereastră când este vizibilă Document-modal

Blochează toate ferestrele din accelaşi document, cu excepţia ferestrelor din ierarhia de copii

Document - ierarhie de ferestre care au aceelaşi părinte Application-modal

Blochează toate ferestrele din aceeaşi aplicaţie, cu excepţia ferestrelor din ierarhia de copii

Toolkit-modal Blochează toate ferestrele din aceelaşi toolkit, cu excepţia ferestrelor din

ierarhia de copii Exclusion mode

Permite marcarea ferestrelor care nu vor fi blocate de o fereastă modală

Crearea de splash screens java -splash:images/splash.gif SplashDemo

final SplashScreen splash = SplashScreen.getSplashScreen(); if (splash == null) { System.out.println("SplashScreen.getSplashScreen() returned null"); return; } Graphics2D g = splash.createGraphics(); if (g == null) { System.out.println("g is null"); return; }

Concluzii Avantaje Swing:

Portabilitatea: conţine mai puţine elemente specifice platformei

Comportament: permite adăugarea unui comportament mai flexibil deoarece legăturile cu platforma nu mai sunt aşa de strânse

Proprietaţi: suportă mai multe proprietăţi ca icoane, tooltips pentru componente

Look and Feel: permite ca aplicaţia să arate la fel pe toate platformele (Windows, Solaris, ...)

Dezavantaje Swing:

Portabilitatea appleturilor: majoritatea browserelor nu includ clasele Swing, deci trebuie folosit un plugin Java

Performanţe: componentele Swing sunt mai lente decât AWT.

Look and Feel: chiar dacă componentele Swing sunt setate să folosescă look and feel-ul sistemului de operare pe care functionează, s-ar putea să nu arate ca şi componentele native.