Interfete grafice Java Swing (javax.swing)
Tipurile de Layout Manager specifice Java Swing
BoxLayout - aranjeaza componentele de-a lungul axelor X, Y ale panel-ului. incearca sa
utilizeze latimea si inaltimea preferate ale componentei.
OverlayLayout – aranjeaza componentele unele peste altele, efectuand o aliniere a
punctului de baza al fiecarei componente intr-o singura locatie.
ScrollPaneLayout – specific pentru “scrolling panes”
ViewportLayout – specific panel-urilor cu “scrolling panes”, aliniaza de-a lungul axei X
Vom prezenta un exemplu pentru tipul BoxLayout (cel mai des utilizat). Acest layout manager organizeaza componentele de-a lungul axelor X, Y ale panel-ului care le detine. Alinierea componentelor se poate face la stanga, la dreapta sau centru (implicit).
Tabbed Panes
O componenta de tipul ”tabbed pane” permite gruparea mai multor pagini de informatie intr-un singur punct de referinta. Se comporta ca orice alta componenta Swing: putem sa ii adaugam un panou (panel), sa ii adaugam componente de obicei sub forma de pagini. Fiecarei pagini ii putem asocia alte componente Java UI.
Selectarea paginilor
Exista 2 mecanisme pentru selectarea unei pagini. Cel mai simplu, utilizatorul va selecta cu un click pagina dorita, iar instanta JTabbedPane va muta automat pagina selectata in fata. Dar se poate scrie si cod pentru aceasta. Se apeleaza metoda setSelectedIndex() cu indexul paginii care se doreste sa apara in fata.
tabbedPanel.setSelectedIndex( iLocation );
O a doua metoda utilizeaza instanta panel-ului care a fost referentiat atunci cand pagina a fost adaugata.
tabbedPanel.setSelectedComponent( pagePanel );
Scrolling panes
in urmatorul exemplu vom crea un “scrolling pane”, si ii vom adauga o instanta JLabel care arata o imagine foarte mare. Pentru ca imaginea este prea mare ca sa fie afisata intreaga, barele de navigare “scroll bars” vor apare automat.
Split panes
Clasa JSplitPane este utilizata pentru a divide doua componente, care prin interventia utilizatorului pot fi redimensionate interactiv. Divizarea se poate face in directia stanga-dreapta utilizand setarea JSplitPane.HORIZONTAL_SPLIT, sau in directia sus-jos utilizand JSplitPane.VERTICAL_SPLIT.
JSplitPane va divide numai doua componente. Daca este nevoie de o interfata mai complexa, se poate imbrica o instanta JSplitPane intr-o alta instanta JSplitPane. Astfel, se va putea intermixa si divizarea orizontala cu cea verticala.
Granita de diviziune poate fi ajustata de catre utilizator cu mouse-ul, dar poate fi setata si prin apelul metodei setDividerLocation(). Atunci cand granita de diviziune este mutata cu mouse-ul de catre utilizator, se vor utiliza setarile dimensiunilor minime si maxime ale componentelor, pentru a determina limitele deplasarii granitei. Astfel, daca dimensiunea minima a doua componente este mai mare decat dimensiunea containerului “split pane”, codul JSplitPane nu va permite redimensionarea frame-urilor separate de granita de diviziune.
Crearea firelor de executie
“Multithreading” inseamna capacitatea unui program de a executa mai multe secvente de cod in acelasi timp. O astfel de secventa de cod se numeste fir de executie sau thread. Limbajul Java suporta multithreading prin clase disponibile in pachetul java.lang. in acest pachet exista 2 clase Thread si ThreadGroup, si interfata Runnable. Clasa Thread si interfata Runnable ofera suport pentru lucrul cu thread-uri ca entitati separate, iar clasa ThreadGroup pentru crearea unor grupuri de thread-uri in vederea tratarii acestora intr-un mod unitar.
Exista 2 metode pentru crearea unui fir de executie: se creeaza o clasa derivata din clasa Thread, sau se creeaza o clasa care implementeza interfata Runnable.
Crearea unui fir de executie prin extinderea clasei Thread
Se urmeaza etapele:
- se creeaza o clasa derivata din clasa Thread
- se suprascrie metoda public void run() mostenita din clasa Thread
- se instantiaza un obiect thread folosind new
- se porneste thread-ul instantiat, prin apelul metodei start() mostenita din clasa Thread. Apelul acestei metode face ca masina virtuala Java sa creeze contextul de program necesar unui thread dupa care sa apeleze metoda run(). Observatie:
Metoda main() are propriul fir de executie. Prin apelul start() se cere JVM crearea si pornirea unui nou fir de executie. Din functia start() se va iesi imediat. Firul de executie corespunzator metodei main() isi va continua executia independent de noul fir de executie creat. Java defineste 3 constante pentru selectarea prioritatilor firelor de executie:
public final static int MAX_PRIORITY; // 10
public final static int MIN_PRIORITY; // 1
public final static int NORM_PRIORITY; // 5
O metoda importanta in contextul utilizarii prioritatilor este
public static native void yield()
care scoate procesul curent din executie si il pune in coada de asteptare.
Iata un exemplu simplu care demonstreaza cum se lucreaza cu prioritatile firelor de executie. Metoda getName() (mostenita din clasa Thread) returneaza numele procesului curent. Observatie:
Implementarile Java depind de platforma. Un program Java care foloseste fire de executie poate avea comportari diferite la executii diferite pentru aceleasi date de intrare. Platformele Windows folosesc cuante de timp (firele de executie sunt administrate intr-o maniera Round-Robin).
Crearea unui fir de executie folosind interfata Runnable
Este o modalitate extrem de utila atunci cand clasa de tip Thread care se doreste a fi implementata mosteneste o alta clasa (Java nu permite mostenirea multipla). Interfata Runnable descrie o singura metoda run().
Se urmeaza etapele:
- se creeaza o clasa care implementeaza interfata Runnable
- se implemeteaza metoda run() din interfata
- se instantiaza un obiect al clasei folosind new
- se creeaza un obiect din clasa Thread folosind un constructor care are ca parametru un obiect de tip Runnable (un obiect al clasei ce implementeaza interfata)
- se porneste thread-ul creat la pasul anterior prin apelul metodei start().
Observatii utile:
Un fir de executie se poate afla la un moment dat in una din urmatoarele stari: running (ruleaza), waiting (adormire, blocare, suspendare), ready (gata de executie, prezent in coada de asteptare), dead (terminat). Fiecare fir de executie are o prioritate de executie. in general thread-ul cu prioritatea cea mai mare este cel care va accesa primul resursele sistem.
O alta clasa aparte de thread-uri sunt cele Daemon care sunt thread-uri de serviciu (aflate in serviciul altor fire de executie). Cand se pornesste masina virtuala Java, exista un singur fir de executie care nu este de tip Daemon si care apeleaza metoda main(). JVM ramane pornita cat exista activ un thread care sa nu fie de tipul Daemon.
2. Excludere mutuala si sincronizare
Presupunem ca doua fire de executie incrementeaza valoarea unui intreg partajat. Pot apare probleme in sensul ca cele 2 fire de executie incrementeaza in acelasi timp intregul, sarindu-se astfel peste valori ale acestuia. Problema se rezolva daca cel mult un fir de executie are acces la acea data la un moment dat. Java implementeaza excluderea mutuala prin specificarea metodelor care partajeaza variabile ca fiind synchronized. Aceste metode trebuie sa fie din aceeasi clasa. Orice fir de executie care incearca sa acceseze o metoda synchronized a unui obiect atita timp cat metoda este utilizata de un alt fir de executie, este blocat pana cand primul fir de executie paraseste metoda.
Drivere JDBC
JDBC (Java DataBase Connectivity) reprezinta API-ul oferit de Sun Microsystems pentru dezvoltarea de aplicatii Java care acceseaza bazele de date gestionate de diverse DBMS-uri (Sisteme de gestiune a bazelor de date). O functie foarte importanta a JDBC este faptul ca lucreaza cu instructiuni SQL. Pentru a utiliza API-ul JDBC cu un DBMS particular este nevoie de un driver JDBC care sa medieze intre tehnologia JDBC si baza de date. Driverul poate fi scris numai in Java sau intr-o combinatie de Java si metode native JNI (Java Native Interface). Ultima specificatie JDBC existenta are vers. 3.0 si contine doua pachete:
1. java.sql
2. javax.sql care ofera capabilitati aditionale pe partea de server
Observatie:
Aplicatiile care utilizeaza baze de date trebuie sa includa pachetul java.sql, ci nu pachetul care contine implementarea driver-ului particular folosit. Totusi calea spre pachetul continand driverul trebuie sa fie prezenta in CLASSPATH.
Exista patru tipuri de drivere JDBC:
1. Puntea JDBC-ODBC. Este reprezentat de clasa sun.jdbc.odbc.JdbcOdbcDriver. Puntea traduce metodele JDBC in apeluri de functii ODBC, si necesita ca bibliotecile ODBC native si driverele ODBC sa fie instalate si configurate pentru fiecare client ce utilizeaza un driver de acest tip. Functioneaza doar pentru sitemele de operare Microsoft Windows si Sun Solaris.
2. Java-API nativ. Folosesc interfata JNI pentru a face apeluri direct la API-ul unei baze de date locale. Sunt mai rapide decit tipul 1. Dar, de asemenea, necesita instalarea si configurarea bibliotecilor client baza de date native pe masina client.
3. Java-protocol de retea. Folosesc un protocol de retea (de obicei, TCP/IP) pentru a comunica cu aplicatia JDBC middleware. Aplicatia JDBC middleware traduce cererile JDBC folosind protocolul de retea in apeluri de functii specifice bazelor de date. Sunt cele mai flexibile, deoarece nu necesita biblioteci de baze de date native pe client si se pot conecta la mai multe
baze de date.
4. Java-protocol baza de date. Implementeaza un protocol de baza de date pentru a comunica direct cu baza de date. Sunt cele mai rapide. De asemenea, nu necesita biblioteci de baze de date native pe client Sunt specifice unui singur DBMS.
Pentru gestiunea driverelor folosite intr-o aplicatie, JDBC API foloseste un manager de drivere reprezentat de o instanta a clasei DriverManager.
2. Utilizarea puntii JDBC -ODBC
in ODBC, bazele de date sunt reprezentate ca surse de date, identificate printr-un nume (DSN – Data Source Name) si accesibile printr-un driver ODBC corespunzator.
Iata un exemplu, care arata cum se procedeaza pentru o baza de date creata in Access, sub sistemul de operare Windows 98. Presupunem ca baza de date a fost deja creata si are numele mesaje.mdb. Pentru a putea face interogari asupra ei, trebuie mai intai sa o introducem ca sursa de date in ODBC. Pentru aceasta, se procedeaza astfel: din Control Panel alegem ODBC Data Sources, ceea ce va determina aparitia unei ferestre ODBC Data Sources Administrator. in rubrica User DSN, folosind butonul Add si wizardul care se declanseaza, selectam pe rand driverul ODBC (spre Access pentru exemplul nostru), respectiv baza de date mesaje.mdb, si punem numele acestei surse de date (Data Source Name) myMessages.mdb. Mai departe, in aplicatia Java, numele bazei de date utilizat va fi numele sursei de date, adica myMessages.mdb.
3. Accesarea unei baze de date folosind JDBC
Trebuie urmati 5 pasi:
1. inregistrarea driver-ului JDBC folosind gestionarul de drivere DriverManager
2. stabilirea unei conexiuni catre baza de date
3. executia unei instructiuni SQL
4. procesarea rezultatelor
5. inchiderea conexiunii catre baza de date
3.1 inregistrarea driver-ului JDBC
Un driver JDBC este inregistrat automat de managerul de drivere atunci cand clasa driver este incarcata dinamic prin meoda Class.forName(). Metoda este statica si permite masinii virtuale Java sa aloce dinamic, sa incarce si sa faca o legatura la clasa specificata ca argument al metodei. in cazul in care clasa nu este gasita, se arunca o exceptie ClassNotFoundException.
Iata un exemplu pentru inregistrarea driver-ului punte JDBC-ODBC:
Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
3.2 Stabilirea conexiunii catre baza de date
O conexiune este identificata printr-un URL specific. Sintaxa standard pentru URL-ul unei
baze de date este:
jdbc<subprotocol>:<nume>
Prima parte arata ca se foloseste JDBC pentru stabilirea conexiunii, <subprotocol> este un nume de driver valid, iar <nume> este un nume logic sau alias care corespunde bazei de date fizice. Daca baza de date este accesata prin Internet, atunci sectiunea <nume> va fi de forma //numeHost:port/numeDB
Pentru stabilirea unei conexiuni la o baza de date, se foloseste metoda statica getConnection() din clasa DriverManager:
Connection con=DriverManager.getConnection(“jdbc:odbc:myMessages”);
sau daca baza de date necesita autentificare:
Connection con=DriverManager.getConnection(“jdbc:odbc:myMessages”,
numeUtilizator,Parola);
JTable
JTable este o componenta Java care permite afisarea unor cantitati mari de date intr-un mod simplu bidimensional. Are o infatisare similara unei foi de calcul (“spreadsheet”). Nu se poate utiliza intocmai ca o foaie de calcul (datorita unor limitari), dar suporta multe alte caracteristici. La fel ca multe alte componente Swing, JTable suporta inlocuirea modelului sau de date implicit cu unul definit de programator, si de asemenea, permite utilizarea unei clase (definita de programator) responsabila pentru desenarea fiecarei celule a tabelului.
in unele situatii, va fi nevoie ca aplicatia sa efectueze sarcini speciale atunci cand mouse-ul este pozitionat pe o anume celula a tabelului. Implicit, clasa JTable nu ofera aceasta capabilitate.
Meniuri
Swing implementeaza o clasa JMenuBar care, pentru compatibilitate, suporta API-ul AWT pentru barele de meniu. Dar, ofera si facilitati in plus, cum ar fi faptul ca barele de meniu Swing pot fi plasate oriunde in ferastra aplicatiei, iar instantele JMenuBar pot fi aplicate si applet-urilor. in Swing, optiunea din meniu de tipul “check box” este implementata intr-o clasa JCheckBoxMenuItem. Ca orice componenta JMenuItem, suporta text sau imagine.
JDialog
Componenta JDialog opereaza asemanator cu JFrame. Sa consideram urmatorul exemplu. Vom crea o aplicatie de tip “frame” care contine un singur buton, care actionat creeaza o noua instanta de tipul JDialog.
Sa observam urmatoarea linie de cod:
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
Aceasta linie de cod controleaza modul cum va reactiona fereastra atunci cand utilizatorul doreste sa o inchida. in cazul nostru, instanta ferestrei dialog va fi distrusa atunci cand utilizatorul va inchide fereastra. (Implicit, fereastra este doar ascunsa.)
in exemplul anterior, am observat ca utilizatorul poate crea un numar nelimitat de ferestre dialog, in timp ce are control independent asupra ferestrei principale a aplicatiei. Acest tip de ferestra dialog se numeste nonmodala deoarece fiecare instanta opereaza independent de celelalte. Clasa JDialog suporta si operatia modala, adica numai o instanta a ferestrei dialog poate fi creata, si atata timp cat aceasta este activa, fereastra sa parinte ignora orice actiune a utilizatorului. in acest caz, se utilizeaza metoda setModal():
TestDialog.setModal( true );
2. JOptionPane
Vezi notiunile teoretice prezentate la curs.
Clasa JOptionPane a fost creata pentru a simplifica procesul de prezentare rapida (“popping up”) a informatiei catre utilizator.
JColorChooser
Vezi notiunile teoretice prezentate la curs.
Clasa JColorChooser se poate utiliza ca o fereastra dialog independenta, returnand culoarea selectata de utilizator, sau poate opera ca o componenta ce poate fi adaugata la o fereastra (“frame”) care deja exista.
Etichete (Labels)
Etichetele sunt string-uri de text care se utilizeaza pentru a identifica alte componente. Pot avea propriul tip de font, propriile culori “foreground” (culoarea textului) si “background” (culoarea de fundal), si pot fi pozitionate oriunde in containerul caruia ii apartin.
Alinierea textului
Interfata SwingConstants contine valori constante pentru toate clasele din biblioteca Swing. Cinci dintre aceste valori constante sunt aplicabile clasei JLabel pentru alinierea textului.
SwingConstants.LEFT - aliniere orizontala stanga
SwingConstants.CENTER - aliniere orizontala centru sau aliniere verticala SwingConstants.RIGHT - aliniere orizontala dreapta
SwingConstants.TOP - aliniere verticala sus
SwingConstants.BOTTOM - aliniere verticala jos
label.setHorizontalAlignment( SwingConstants.RIGHT );
label.setVerticalAlignment( SwingConstants.BOTTOM );
Pentru etichetele care includ atat text cat si imagine, textul poate fi aliniat independent de imagine:
label.setHorizontalTextAlignment( SwingConstants.LEFT ); label.setVerticalTextAlignment( SwingConstants.TOP ); Atasarea unei imagini la o eticheta
Exemplul anterior arata cum se seteaza imaginea in timpul constructiei obiectului JLabel.
Icon image = new ImageIcon( 'myimage.gif' );
JLabel label3 = new JLabel( 'Label3', image,SwingConstants.CENTER );
Se poate proceda si altfel – imaginea sa fie setata la orice moment.
Icon image = new ImageIcon( 'myimage.gif' );
label2.setIcon( image );
Imaginile nu sunt scalate pentru a se potrivi cu limitele dimensiunii etichetei, deci adaugarea unei imagini mari poate cauza efectul de “clipping”. Pentru a se inlatura o imagine a unei etichete se utilizeaza:
label2.setIcon( null );
Butoane
Sa ne amintim ca toate clasele UI sunt derivate din JComponent.
Nu se va utiliza direct clasa AbstractButton, dar in implementarea diferitelor aplicatii se vor utiliza clasele-fiu ale acesteia. Clasa AbstractButton manipuleaza aproape toate functionalitatile celorlalte clase Swing Button, de aceea o vom studia in detaliu.
Tratarea evenimentelor generate de butoane
Cel mai frecvent se utilizeaza interfata ActionListener. Se poate proceda in doua moduri. Se ceeaza o clasa independenta de clasa ce contine instanta butonului, iar aceasta clasa va implementa interfata ActionListener (si va furniza cod pentru metoda actionPerformed() ). Avantajul acestei abordari este ca mai multe butoane din clase diferite ale unui proiect pot fi manipulate de o singura clasa. A doua abordare este de a implementa interfata ActionListener in clasa care detine instanta butonului.
Daca un buton contine o imagine, se pot asigna optional imagini individuale pentru urmatoarele stari ale butonului: normal, selectat, apasat, cursorul mouse-ului se afla deasupra suprafetei butonului, dezactivat. Se utilizeaza urmatoarele metode (vezi documentatie clasa AbstractButton): setIcon(),setDisabledIcon(), setDisabledSelectedIcon(), setPressedIcon(), setRolloverIcon(), setRolloverSelectedIcon(), setSelectedIcon().
Butoane activate si dezactivate
De exemplu, pentru aplicatiile ce contin formulare bazate pe ferestre de dialog, este util sa se dezactiveze butonul OK pana cand utilizatorul completeaza toate campurile obligatorii. Pentru a activa si dezactiva un buton se utilizeaza codul:
button.setEnabled( bState );
unde bState este true (pentru activare) sau false (pentru dezactivare). Daca butonul este dezactivat, va fi redesenat intr-o nuanta de gri sters.
Adaugarea unei combinatii de taste
Se pot crea aplicatii care sa suporte operatii fara mouse, numai prin utilizarea tastaturii. Swing aplica aceasta capabilitate familiei sale de componente vizuale, permitand asignarea unei combinatii de taste (“keyboard mnemonic”) numita si accelerator, pentru orice clasa-fiu a clasei parinte JComponent, inclusiv pentru butoane si “check boxes”. Se utilizeaza codul:
button.setMnemonic( 'R' );
- asigneaza tasta R instantei button. Pentru efectul de apasare a butonului, in loc de a se utiliza un click cu mouse-ul, se poate utiliza combinatia de taste Alt+R.
Daca litera se afla in eticheta butonului, atunci va apare subliniata.
Butoane “Toggle”
Swing furnizeaza si o clasa numita JToggleButton. Butoanele din aceasta clasa au acelasi aspect ca si cele JButton, diferenta constand in faptul ca au 2 stari. Butoanele “Toggle” lucreaza asa cum lucreaza tasta Caps Lock de pe tastatura, in timp ce butoanele JButton opereaza in aceeasi maniera ca tastele ce reprezinta litere sau cifre. Clasa JToggleButton furnizeaza un
mecanism “press-and-hold”, deci sunt ideale pentru interfetele utilizator care necesita operatii modale.
Mai multe butoane JToggleButton pot fi grupate in aceeasi maniera ca si butoanele de tip radio, utilizandu-se clasa ButtonGroup. Butoane “CheckBox”
Swing furnizeaza o clasa, numita JCheckBox, care extinde JToggleButton pentru a implementa un control standard de tip “check box”.
NOTIUNI TEORETICE
Swing este un subset JFC (Java Foundation Classes) si consta dintr-o serie de componente vizuale care extind (imbunatatesc) componentele AWT, si furnizeaza noi facilitati precum tabele si arbori. Structura de clase din Swing este asemanatoare cu cea din AWT, in sensul ca toate componentele interfetei grafice sunt derivate dintr-un singur parinte numit JComponent (care este derivat din clasa AWT Container).
Pachetul de clase Swing reprezinta solutia furnizata de Sun pentru crearea unor interfete utilizator grafice complet portabile pe orice platforma.
in Swing, toate numele claselor incep cu litera J, si atunci cand este posibil, numele este acelasi cu cel al clasei AWT pe care o inlocuieste.
La fel ca la AWT, punctul de plecare pentru un program bazat pe Swing, este clasa JFrame sau clasa JApplet.
JFRAME
JFrame este o versiune extinsa a clasei Frame care adauga suport pentru un comportament de desenare special. Aditional, JFrame permite componentelor Swing MenuBars sa fie atasate nu numai in partea de sus a ferestrei dar oriunde in fereastra.
Toate obiectele asociate unui JFrame sunt manipulate de o instanta a clasei JRootPane, care este singura componenta-fiu a unei instante JFrame. JRootPane este un container simplu pentru alte cateva componente.Iata care este ierarhia de obiecte dintr-o instanta JFrame:
JFrame
JRootPane
glassPane
layeredPane
[menuBar]
contentPane
Este posibil sa se mixeze componentele AWT cu cele Swing, intr-o aplicatie Java Swing, dar in general se recomanda utilizarea exclusiva a componentelor Swing (un posibil efect: componentele AWT sunt desenate mai rapid undeva in coltul din stanga sus al frame-ului inainte de a fi corect pozitionate, rezultand un “flicker” neasteptat in timpul operatiilor de redesenare a ecranului).
Codul din exemplul anterior este foarte simplu si arata ca si cum s-ar fi utilizat componente AWT, cu o singura exceptie:
getContentPane().add( topPanel );
O clasa JFrame prezinta o singura incompatibilitate in raport cu o clasa AWT. in AWT Frame se puteau adauga componente direct la instanta frame (pentru ca clasa AWT Frame creeaza automat o instanta Panel).
frame.add( component );
Pentru JFrame, trebuie sa specificam exact in care subcomponenta a lui JRootPane vom plasa componenta noastra. Cel mai adesea, componentele grafice se vor adauga la contentPane. Trebuie utilizata urmatoarea sintaxa:
myJFrame.getContentPane().add( component );
Cea mai buna solutie este de se crea un Panel, de a se adauga acesta la ContentPane, si de a se adauga apoi toate componentele la Panel-ul nou creat.
JWINDOW
JWindow este similara cu JFrame exceptand faltul ca nu are no “title bar”, nu este redimensionabila, minimizabila, maximizabila, si nu se poate inchide (fara a scrie cod pentru acest lucru). Se utilizeaza in general pentru a mesaje temporare (“splash screen”).
JApplet
JApplet are structura similara cu JFrame. Permite adaugarea de componente MenuBars si toolbars.
JPanel
Echivalentul Swing al clasei AWT Panel este JPanel. JPanel suporta toate tipurile de “layout manager” din AWT, plus cele noi din Swing.
Clasa TestPanel este derivata din JFrame; creeaza o instanta JPanel careia i se aplica “GridLayout manager”. Butoanele sunt adaugate instantei JPanel, ci nu ferestrei principale.
O instanta JPanel este implicit “double buffered”, ceea ce reduce efectul de “flicker” in timpul operatiilor de redesenare a ecranului, pentru programele de animatie. Daca utilizam “double-buffering” pentru o componenta, toti fii acesteia vor utiliza de asemenea “double-buffering” (chiar daca nu este activat). JRootPane este componenta din varful ierarhiei oricarei ferestre Swing, deci activand “double-buffering” pentru JRootPane, toate subcomponentele sale vor fi desenate utilizandu-se tehnica “double-buffering”.
Borders
Pachetul border furnizeaza urmatoarele clase care por fi aplicate oricarei componente Swing:
BevelBorder – o margine 3D cu o infatisare “ridicata” sau nu (respectiv “raised” sau “lowered”).
CompoundBorder - o combinatie de 2 alte tipuri de margini: o margine interioara si o margine exterioara.
EmptyBorder - o margine transparenta utilizata pentru a defini un spatiu vid in jurul unei componente.
EtchedBorder – o margine cu o linie gravata.
LineBorder - o margine cu o grosime si culoare specificate.
MatteBorder - o margine constand fie dintr-o culoare, fie dintr-o imagine repetata (“tiled”).
SoftBevelBorder –o margine 3D cu o infatisare “ridicata” sau nu, si cu capetele rotunjite. TitledBorder – o margine care permite existenta unui titlu intr-o anume pozitie si locatie.