distribuirea componentelor intr-un container

13
1 Distribuirea componentelor într-un container (Layout). Clasele JFrame „Nu spune niciodată nu se poate, ci incepe cu să vedem.” Nicolae Iorga Obiective: Cunoașterea modului în care controalele vor fi distribuite în cadrul containerului Layout-ul („format” predefini, respectiv aspectul containerului) . Layout-urile existente sunt: AWT: BorderLayout, FlowLayout, CardLayout, GridLayout, GridBagLayout. SWING: GroupLayout, BoxLayout. Si SpringLayout. Cuprins: I. Clasele JFrame și JApplet 1.1. Proprietățile și metodele clasei JFrame 1.2. Manipularea componentelor și Layout Manager. II. Distribuirea componentelor într-un container 2.1. Java AWT Layouts 2.2. Java Swing Layouts I. Clasele JFrame Containerul de bază în care este afișată o aplicație este clasa Frame, respectiv, în interpretarea Swing, acea clasă este JFrame moștenitor al clasei java.awt.Frame. JFrame este punctul de început al părții grafice din aplicație. Următorul exemplu crează o fereastră cu dimensiunile 300 x 300 pixeli: import javax.swing.JFrame; public class Main { public static void main(String[] args) { JFrame myFrame = new JFrame(); myFrame.setSize(300, 300); myFrame.setVisible(true); } } 1.1. Proprietățile și metodele clasei JFrame Clasa JFrame moștenește o mulțime de proprietăți de la strămoșii săi, clasele Frame, Window, Container și Component. Constructorul clasei JFrame JFrame mai are încă trei constructori pe lângă cel default. Primul implică un parametru de tip String. Acest parametru va reprezenta titlul din antetul ferestrei: JFrame myFrame = new JFrame("Hello Window"); Al doilea constructor acceptă un parametru de tip GraphicsConfiguration și permite emiterea ferestrei într-un context grafic specific (alt monitor și altele de genul acesta): JFrame myFrame = new JFrame(GraphicsEnvironment.getLocalGraphicsEnvironment().getSc reenDevices()[0].getDefaultConfiguration()); Al treilea constructor acceptă ambii parametri menționați mai sus:

Upload: tirdea-mihai

Post on 09-Nov-2015

296 views

Category:

Documents


2 download

TRANSCRIPT

  • 1

    Distribuirea componentelor ntr-un container (Layout).

    Clasele JFrame

    Nu spune niciodat nu se poate, ci incepe cu s vedem. Nicolae Iorga

    Obiective: Cunoaterea modului n care controalele vor fi distribuite n cadrul containerului Layout-ul (format predefini, respectiv aspectul containerului) . Layout-urile existente sunt:

    AWT: BorderLayout, FlowLayout, CardLayout, GridLayout,

    GridBagLayout.

    SWING: GroupLayout, BoxLayout. Si SpringLayout.

    Cuprins: I. Clasele JFrame i JApplet 1.1. Proprietile i metodele clasei JFrame 1.2. Manipularea componentelor i Layout Manager.

    II. Distribuirea componentelor ntr-un container

    2.1. Java AWT Layouts

    2.2. Java Swing Layouts

    I. Clasele JFrame

    Containerul de baz n care este afiat o aplicaie este clasa Frame, respectiv, n interpretarea Swing, acea clas este JFrame motenitor al clasei java.awt.Frame.

    JFrame este punctul de nceput al prii grafice din aplicaie. Urmtorul exemplu creaz o fereastr cu dimensiunile 300 x 300 pixeli:

    import javax.swing.JFrame; public class Main { public static void main(String[] args) { JFrame myFrame = new JFrame();

    myFrame.setSize(300, 300); myFrame.setVisible(true); } }

    1.1. Proprietile i metodele clasei JFrame Clasa JFrame motenete o mulime de proprieti de la strmoii si, clasele Frame, Window, Container i Component. Constructorul clasei JFrame

    JFrame mai are nc trei constructori pe lng cel default. Primul implic un parametru de tip String. Acest parametru va reprezenta titlul din antetul ferestrei:

    JFrame myFrame = new JFrame("Hello Window");

    Al doilea constructor accept un parametru de tip GraphicsConfiguration i permite

    emiterea ferestrei ntr-un context grafic specific (alt monitor i altele de genul acesta): JFrame myFrame = new

    JFrame(GraphicsEnvironment.getLocalGraphicsEnvironment().getSc

    reenDevices()[0].getDefaultConfiguration());

    Al treilea constructor accept ambii parametri menionai mai sus:

  • 2

    JFrame myFrame = new JFrame("Hello!",

    GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDev

    ices()[0].getDefaultConfiguration());

    Poziionarea. Iniial, JFrame apare pe coordonatele 0,0 n relaie cu containerul printe. Atunci cnd containerul respectiv este sistemul de operare nsui (respectiv, cnd instana clasei JFrame este fereastra principal a aplicaiei), fereastra va aprea n colul din stnga sus a sistemului.

    Vizualizarea i modificarea poziiei pot fi efectuate prin metodele setLocation i getLocation. n clas, locaia ferestrei este stocat n numere ntregi n cmpurile x i y. Cnd dorim s modificm aceste valori, utilizm metoda set - setLocation. Aceast metod poate s accepte numai numere ntregi, fiindc locaia este exprimat n pixeli (puncte pe ecran). De asemenea, setLocation mai conine i Overload, care accept obiectul de tipul Point. Aadar, locaia ferestrei poate fi setat n dou moduri:

    myFrame.setLocation(100, 200);

    sau myFrame.setLocation(new Point(500, 500));

    metoda getLocation returneaz numai valori de tip Point: JOptionPane.showMessageDialog(myFrame, "x:" + myFrame.getLocation().x +

    " y:" + myFrame.getLocation().y );

    Setarea dimensiunii. Setarea i obinerea dimensiunii ferestrei JFrame se efectueaz prin metodele setSize i getSize. setSize accept numere ntregi (lime i nlime) ca parametrii:

    myFrame.setSize(300,300);

    setSize poate de asemenea s accepte un obiect de tipul Dimension myFrame.setSize(new Dimension(300, 400));

    n timpul extragerii, se utilizeaz metoda getSize, care returneaz numai obiectul de tip Dimension:

    JOptionPane.showMessageDialog(myFrame,

    "width:" + myFrame.getSize().width + " height:" + myFrame.getSize().height);

    Afiarea. Fereastra nu va fi afiat pn cnd nu va fi utilizat metoda sa setVisible. Aceast metod poate accepta un singur parametru: true i false:

    ...

    this.setVisible(true); ...

    Cnd activm metoda setVisible (care iniiaz modificarea n cmpul visible al clasei Component), nu vom distruge fereastra, ci doar o vom ascunde. De asemenea, toate valorile

    care sunt situate n ea vor fi acolo atunci cnd afim fereastra din nou, prin metoda setVisible(true).

    Dac dorim s distrugem fereastra cu adevrat, vom utiliza metoda dispose. Aceast metod va dezactiva toate procesele din fereastr i o va nchide n condiii de siguran.

    1.2. Manipularea componentelor i Layout Manager. Pentru Jframe, la fel ca pentru toate celelalte componente, se aplic regula de adugare a copiilor prin metoda add i eliminarea acestora prin metoda remove.

    Urmtorul exemplu adaug un buton cu textul Hello n Frame-ul existent: myFrame.add(new JButton("Hello"));

    Rezultatul nu este satisfctor, deoarece actualul Layout Manager este BorderLayout:

  • 3

    Pentru o reprezentare valid, trebuie s setm un Layout Manager corespunztor prin

    metoda setLayout.

    Urmtorul exemplu modific actualul Layout Manager din BorderLayout n FlowLayout: ... myFrame.setLayout(new FlowLayout()); myFrame.add(new JButton("Hello"));

    ...

    Rezultatul este:

    Pentru a elimina butonul adugat din fereastr, putem utiliza metoda remove. Dac

    definim o component i o plasm ntr-o variabil, atunci numele variabilei poate pur i simplu s fie expediat metodei remove:

    ... JButton btn = new JButton("Hello!"); myFrame.add(btn); ...

    myFrame.remove(btn); ...

    n cazul n care controlul (componenta) a fost adugat anonim: myFrame.add(new JButton("Hello!"));

    trebuie s fie gsit manual i eliminat din container. De exemplu: myFrame.remove(myFrame.getContentPane().getComponent(0));

    S explicm linia precedent. Metoda myFrame.remove este clar, dar nu am explicat getContentPane i getComponent.

    i anume, n exemplul precedent este evident faptul c respectivul control este extras din container prin indexul su din colecia de controale. ns, problema este urmtoarea: cum s ajungem la aceea colecie?

    JFrame este o fereastr care conine numai un control, containerul content pane (de fapt, unul care este important pentru noi n acest moment). Containerele top level, precum

    JFrame, conin cteva obiecte care reprezint diferite nivele, dar vom vorbi despre aceasta mai trziu. Toate celelalte controale din fereastr sunt situate n acest container. Aceasta nseamn c trebuie s extragem containerul mai nti, iar apoi s cutm controalele din el:

    ... myFrame.getContentPane().getComponents() for(int i=0;i<

    myFrame.getContentPane().getComponentCount();i++) myFrame.getContentPane().getComponent(i) ...

    JFrame va fi rar utilizat n forma afiat, ci mult mai mult ca un ablon pentru propria clas. Aadar, vom plasa majoritatea proprietilor acestui obiect n constructorul clasei sale.

  • 4

    De obicei, metoda separat (initComponents sau numai init) care efectueaz setrile obiectului actual este apelat n interiorul constructorului. n aceast clas, vom adresa toate setrile (metodele i proprietile) prin cuvntul cheie this:

    MyFrame.java

    import javax.swing.JFrame; public class MyFrame extends JFrame {

    public MyFrame() { initComponents(); }

    void initComponents() { this.setSize(300, 300);

    this.setVisible(true); } } Program

    public class Main { public static void main(String[] args) { MyFrame mFrame = new MyFrame();

    } }

    n clasa JFrame, cu fiecare redesenare a ferestrei (dac un control trece peste aceasta sau dac o mutm), apare activarea metodei paint, aceasta fiind, aadar, metoda n cadrul creia putem manipula coninutul grafic al clasei:

    @Override public void paint(Graphics g) {

    g.drawString("Hello", 200, 200); }

    II. Distribuirea componentelor ntr-un container

    Distribuia componentelor n interiorul unui container este efectuat n conformitate cu un format predefinit. Acest format se numete Layout, respectiv aspectul containerului. n Swing i n AWT, exist tipuri de layout-uri predefinite (LayoutManager) pe care le putem utiliza.

    Layout este modul n care controalele vor fi distribuite n cadrul containerului. Exist clase speciale pentru acest scop, denumite LayoutManagers, care implementeaz interfaa LayoutManager.

    Layout-urile existente sunt: BorderLayout, FlowLayout, CardLayout, GridLayout,

    GridBagLayout i BoxLayout, GroupLayout i SpringLayout. Dintre acestea, SpringLayout, GroupLayout i BoxLayout fac parte din Swing Layouts.

    S ne reamintim modul n care funcioneaz Layout-urile AWT de baz.

    2.1. Java AWT Layouts Layout-ul default al containerului creat este BorderLayout, ceea ce nseamn c

    ntreaga fereastr va fi mprit n cinci pri: nord, vest, est, sud i mijloc. Respectiv, echivalentele acestora: Page start, Page end, Line start, Center i Line end.

  • 5

    Pentru a poziiona un anumit control ntr-o anumit parte din Layout, trebuie s-l

    accentum n timpul utilizrii metodei add a containerului nsui, atunci cnd vom introduce numele prii containerului ca al doilea parametru. Pentru a umple toate prile containerului din imagine, putem utiliza codul urmtor: import java.awt.*; public class Main { public static void main(String[] args) {

    Frame f = new Frame(); Label l = new Label("Helo from top of the page"); Label l1 = new Label("Helo from center of the page"); Label l2 = new Label("Helo from bottom of the page");

    Label l3 = new Label("left"); Label l4 = new Label("right"); f.add(l,BorderLayout.PAGE_START);

    f.add(l1,BorderLayout.CENTER); f.add(l2,BorderLayout.PAGE_END); f.add(l3,BorderLayout.LINE_START); f.add(l4,BorderLayout.LINE_END);

    f.setSize(300, 300); f.setVisible(true); }

    }

    a) Border Layout este mai dificil, deoarece

    controalele din fiecare parte sunt plasate unul

    peste altul, ceea ce nseamn c putem avea numai un control (sau container) vizibil ntr-

    o parte a Layout-ului.

    b) FlowLayout expune toate controalele unul dup altul, orizontal, pn la captul containerului, dup care trece pe un alt rnd, continund expunerea. Prin default, controalele din acest Layout sunt expuse central, n mijloc, iar dac dorim un alt tip de centrare, trebuie s-l menionm n constructorul FlowLayout.

  • 6

    Avnd n vedere c FlowLayout nu este layout-ul default al Frame-ului, trebuie s indicm explicit c acesta este cel pe care dorim s-l utilizm (acest lucru se aplic tuturor Layout-urilor):

    ... LayoutManager layOut = new FlowLayout(FlowLayout.LEFT); ...

    f.setLayout(layOut); ...

    Cnd atribuim Layout-ul containerului, prin metoda setLayout, care accept obiectul LayoutManager sub form de parametru, toate controalele adugate n container vor fi poziionate n funcie de acest Layout: import java.awt.*; public class Main {

    public static void main(String[] args) { LayoutManager layOut = new FlowLayout(FlowLayout.LEFT); Frame f = new Frame(); f.setLayout(layOut);

    Button b = new Button("button 1"); Button b1 = new Button("button 2"); Button b2 = new Button("button 3");

    f.add(b); f.add(b1); f.add(b2);

    f.setSize(300, 300); f.setVisible(true); } }

    Urmtoarea ieire reprezint un exemplu:

    c) GridLayout creaz un tabel n container, unde fiecare celul din tabel reprezint un spaiu pentru control. Construcia tabelului (numrul de coloane i de rnduri) este creat n constructorul obiectului GridLayout. De exemplu, constructorul pentru un tabel cu dou rnduri i trei coloane va arta astfel:

    LayoutManager layOut = new GridLayout(2, 3);

    Dac numrul de controale depete capacitatea tabelului (exist ase celule n tabel), una dintre dimensiunile tabelului va ctiga prioritate asupra celeilalte. De exemplu, dac ncercm s punem 10 controale n tabelul 2x3, va fi respectat regula de 2 rnduri, dar va crete numrul de coloane. Dac dorim s se respecte numrul de coloane n detrimentul numrului de rnduri, trebuie s setm numrul de rnduri la 0:

    LayoutManager layOut = new GridLayout(2, 3);

    Urmtorul exemplu ilustreaz utilizarea GridLayout-ului (codul pentru adugarea controalelor funcioneaz la fel ca n exemplul precedent, dar este optimizat pentru a economisi spaiu): import java.awt.*; public class Main { public static void main(String[] args) { LayoutManager layOut = new GridLayout(3, 3);

    Frame f = new Frame(); f.setLayout(layOut);

  • 7

    for(int i=0;i

  • 8

    Metoda show a clasei CardLayout accept doi parametri: numele panoului printe (n cazul nostru, acesta este mainPanel) i numele panoului pe care dorim s-l afim. Pentru numele panoului pe care dorim s-l afim, vom introduce numele su logic, adic constraint. Pentru a schimba panoul existent, vom utiliza de asemenea metoda show.

    Urmtorul exemplu ilustreaz schimbarea panoului curent prin activarea butonului: import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;

    public class Main { static CardLayout layOut; static Panel mainPanel; static Frame f;

    public static void main(String[] args) throws

    InterruptedException { f = new Frame();

    mainPanel = new Panel(); layOut = new CardLayout(); mainPanel.setLayout(layOut); Panel firstP = new Panel();

    Panel secondP = new Panel(); Button b = new Button("first panel button"); b.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) { layOut.show(mainPanel, "Second"); } });

    Button b1 = new Button("second panel button"); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {

    layOut.show(mainPanel, "First"); } });

    firstP.add(b);

    secondP.add(b1); mainPanel.add(firstP,"First"); mainPanel.add(secondP,"Second"); f.add(mainPanel);

    f.setSize(300, 300); f.setVisible(true); }

    }

    Ieirea acestui exemplu este urmtoarea:

    2.2. Java Swing Layouts Swing aduce cu sine noi clase LayoutManager: GroupLayout, BoxLayout. Si

    SpringLayout. B) GroupLayout este LayoutManager-ul default al designerului JDeveloper (GUI Builder).

    Acest layout implic o fereastr mprit n grupuri i chiar dac mediul l utilizeaz, acesta nu este foarte simplu de utilizat manual.

  • 9

    GroupLayout implic dou direcii (orizontal i vertical) i dou tipuri de setri ale controalelor (secvenial i paralel).

    Pentru a seta un anumit control, trebuie s crem un grup de un anumit tip. Dac ne

    uitm la imagine ca la un grup orizontal, putem spune c grupul este alctuit din dou butoane. 1: Hello a i 2: Hello b. Acest grup se mut secvenial, de la stnga la dreapta. Dac ne utitm la imagine vertical, de sus n jos, butoanele nu vor fi aranjate secvenial, ci paralel, deoarece sunt plasate unul lng altul pe acelai plan. Acum grupul este: 1: Hello a i 1: Hello b.

    Atunci cnd combinm aceste dou zone, rezultatul este c fereastra conine un grup orizontal, secvenial, de dou butoane i un grup vertical, paralel, de dou butoane. Cnd acest lucru este tradus n Java, rezultatul este codul urmtor: GroupLayout layout = new GroupLayout(this.getContentPane()); this.setLayout(layout); layout.setAutoCreateGaps(true);

    layout.setAutoCreateContainerGaps(true); JButton a = new JButton("Hello a"); JButton b = new JButton("Hello b"); layout.setHorizontalGroup(

    layout.createSequentialGroup() .addComponent(a).addComponent(b) );

    layout.setVerticalGroup( layout.createParallelGroup() .addComponent(a).addComponent(b) );

    Observm c aceleai controale apar att n grupul orizontal, ct i n cel vertical. Aceste controale trebuie s se suprapun pe poziiile or orizontale i verticale, pentru ca Layout-ul c fie creat n mod corespunztor. Aceasta nseamn c controalele nu pot fi create dinamic, motiv pentru care acest Layout nu este convenabil pentru utilizare n afara

    platformei.

    Metodele setAutoCreateGaps i setAutoCreateContainerGaps definesc n mod automat spaiul dintre controalele din cadrul grupului. C) BoxLayout red controalele unul dup altul, pe o anumit ax:

  • 10

    ... this.setLayout(new BoxLayout(this.getContentPane(),

    BoxLayout.Y_AXIS));

    for(int i=0;i

  • 11

    btn.setBorder(BorderFactory.createMatteBorder(15, 5, 15, 5, Color.yellow));

    btn.setBorder(BorderFactory.createTitledBorder("My border title"));

    Proprietatea border poate fi setat i prin GUI Builder. Trebuie s selectm tipul dorit

    al cadrului i s-l tragem n control (sau, pur i simplu, s dm un clic cu tasta stng a mouse-ului pe cadru i nc o dat pe controlul int):

    Pentru a modifica setrile cadrului, n proprietile controlului (Properties), vom selecta opiunea Border:

    Aceasta activeaz instrumentul Border customizer cu care putem modifica

    proprietile i chiar s nlocuim cadrul existent cu altul:

    III. Exerciiu/Tem Problem: Trebuie s facem o aplicaie Java puzzle. Aplicaia va fi alctuit din 12 butoane distribuite pe controlul JFrame, utiliznd GridLayout. Unul dintre butoane va fi

    ntodeauna invizibil i fiecare buton care va fi apsat va fi mutat n locul celui invizibil, n timp ce butonul

    invizibil i va lua locul. Dac butonul activat nu este plasat lng butonul invizibil, nlocuirea butonului ar trebui s fie dezactivat.

    Soluie:

    import java.awt.*; import java.awt.event.*; import javax.swing.JButton; public class Main { static JButton invisible; static void switchButtons(JButton clickedButton) { if( invisible.getLocation().x < (clickedButton.getLocation().x - clickedButton.getSize().width) || invisible.getLocation().x > (clickedButton.getLocation().x + clickedButton.getSize().width) || invisible.getLocation().y < (clickedButton.getLocation().y - clickedButton.getSize().height) ||

  • 12

    invisible.getLocation().y > (clickedButton.getLocation().y + clickedButton.getSize().height) || (invisible.getLocation().y !=clickedButton.getLocation().y && invisible.getLocation().x !=clickedButton.getLocation().x) ) return; Point tmpLoc = clickedButton.getLocation(); clickedButton.setLocation(invisible.getLocation()); invisible.setLocation(tmpLoc); } public static void main(String[] args) { LayoutManager layOut = new GridLayout(3, 3); Frame f = new Frame(); f.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setLayout(layOut); JButton btn = new JButton(); for(int i=1;i

  • 13

    04. Distribuirea componentelor ntr-un container

    1. Cum se numete proprietatea prin care este reprezentat cadrul din control? border

    edge

    stroke

    outline

    2. Care swing layout poziioneaz controalele unul dup cellalt, de-a lungul unei anumite axe?

    FlowLayout

    BoxLayout

    SpringLayout

    GroupLayout

    3. Dac utilizm limitatori pentru a poziiona un control pe layout, despre ce tip de swing layout este vorba?

    BoxLayout

    GroupLayout

    SpringLayout

    FlowLayout

    4. Cum se numete instrumentul care ofer manipularea grafic a cadrelor? Border wizard

    Border customizer

    Border modifier

    Border creator

    5. Care este numele clasei care conine metodele pentru crearea diferitelor obiecte Border? BorderCreator

    Borders

    BorderFactory

    Border

    6. Care metod seteaz proprietatea border a controlului? putBorder

    setBorder

    addBorder

    border

    7. Cnd vorbim despre Group Layout-ul vertical, avem urmtoarele dou tipuri de poziionare a controalelor:

    secvenial i paralel orizontal i vertical nord i sud est i vest