PDA

View Full Version : [Java] Swing: qualche chiarimento.


ndakota
17-12-2009, 12:54
Ciao a tutti, sono ancora io. E' la prima volta che mi cimento nello sviluppo di un applicazione con interfaccia grafica, seppure piccola. Vorrei dunque qualche dritta:

1) Questo è più che altro un problema. Sto utilizzando una JTable e inizialmente appena avviata la finestra, questa non si vede(seppure vuota, parlo dei soli nomi delle colonne). Si vede solo se ridimensiono la finestra(anche rimpicciolendola).

2) Non capisco bene come dev'essere la struttura della GUI. Io per ora ho messo un JFrame che ha sotto di sè un JScrollPane che ha sotto di sè la JTable. Ecco, mi pare di aver capito che non posso aggiungere direttamente la JTable sotto il JFrame. Un po' di chiarimento su questa cosa?

3) La mia applicazione dovrà avere una finestra principale, che diciamo ci sarà sempre e una finestra che apparirà solo all'esigenza. Quest'ultima come conviene farla? Sempre JFrame e tutto il resto sotto?

Grazie :D

banryu79
17-12-2009, 13:30
Ciao a tutti, sono ancora io. E' la prima volta che mi cimento nello sviluppo di un applicazione con interfaccia grafica, seppure piccola.


Ciao, se ti stai cimentando con Swing per la primissima volta, ti linko delle risorse utili per future consultazioni:

-tutorial SwingEspresso by PGI (http://www.hwupgrade.it/forum/showthread.php?t=2005654)
-tutorial GridBagLayout by PGI (http://www.hwupgrade.it/forum/showthread.php?t=2005654)
-Java Tutorial - The Really Big Index [in particolare le due trails intitolate: " Graphical User Interfaces" e " Creating a GUI With JFC/Swing"] (http://java.sun.com/docs/books/tutorial/reallybigindex.html)

Qui ti rispondo di fretta, perchè... sono di fretta (ma va? :D)

1) Questo è più che altro un problema. Sto utilizzando una JTable e inizialmente appena avviata la finestra, questa non si vede(seppure vuota, parlo dei soli nomi delle colonne). Si vede solo se ridimensiono la finestra(anche rimpicciolendola).

2) Non capisco bene come dev'essere la struttura della GUI. Io per ora ho messo un JFrame che ha sotto di sè un JScrollPane che ha sotto di sè la JTable. Ecco, mi pare di aver capito che non posso aggiungere direttamente la JTable sotto il JFrame. Un po' di chiarimento su questa cosa?

3) La mia applicazione dovrà avere una finestra principale, che diciamo ci sarà sempre e una finestra che apparirà solo all'esigenza. Quest'ultima come conviene farla? Sempre JFrame e tutto il resto sotto?

1) Prova ad impostare la preferredSize della JTable.
@EDIT: e a chiamare pack() sul JFrame subito prima del setVisible(true), ovviamente.

2) Alcuni component (come JFrame oppure come JScrollPanel) sono deputati al contenimento di altri component al loro interno, al fine di determinare una gerarchia di components innestati uno dentro l'altro.

Questi components che sono pensati per contenere altri components, vengono chiamati containers.

JFrame e JScrollPane sono entrambi pensati per essere usti come containers, con la differenza che JFrame è anche JWindow, diciamo una finestra vera e propria (può essere visualizzato autonomamente, cioè viene utilizzato come radice di una gerarchia di componenti visualizzabili), mentre JScrollPane no.

I componenti-contenitori utilizzabili come "radici" in Swing sono: JFrame (la classica finestra), JDialog (classica finestra di dialogo modale) JApplet e JDesktopPane (una finestra che funziona come un desktop, che può contenere nei suoi limiti altri JInternalFrame).

Quindi quando tu vuoi visulizzare il tuo componente grafico, nel tuo caso una JTable, hai bisogno di definire una gerarchia di componenti in cui infilarla, non essendo di per se stessa una finestra.
Potresti dunque "infilare" la JTable in un semplice JFrame, ed andrebbe bene.
Ma vuoi anche che la JTable sia sempre visulizzabile, nel caso le sue dimensioni proiettate a video eccedano quelle del JFrame che la contiene (per esempio se il JFrame viene rimpicciolito dall'utente).

In questo caso infili la JTable nello JScrollPane, un componente programmabile dotato di scrollbar che risolve proprio il problema appena illustrato per il componente che contiene; infine infilili il tutto in un componente "radice" per definire correttamente la tua gerarchia di visualizzazione: un JFrame.

La tua gerarchia è così definita:

[x] JFrame (root)
|
---> [x] JScrollPane
|
---> [x] JTable


3) JFrame oppure JDialog, modale o meno (dipende tutto da cosa devi fare) e tutto il resto "all'interno", non "sotto", stiamo pur sempre parlando di contenitori, non di sodomizzatori :D

ndakota
17-12-2009, 14:52
grazie, chiarissimo e divertente :D
Swing espresso di PGI-bis e il the really big index li sto già consultando :Prrr:

banryu79
17-12-2009, 15:50
grazie, chiarissimo e divertente :D
Swing espresso di PGI-bis e il the really big index li sto già consultando :Prrr:
C'è un'altro aspetto di cui tenere conto nella faccenda della gerarchia di componenti, che nel post sopra non ho accennato: i LayoutManager.

Un LayoutManager è un oggetto che, associato a un container ne gestisce la ripartizione dello spazio interno utile per la proiezione grafica a video di tutti i component che il container stesso contiene, secondo una certa politica (che poi appunto caratterizza il LayoutManager e lo distingue dagli altri).

Ogni componente che è anche un container ha un LayoutManager associato di default.
Per JFrame, ad esempio, è un BoderLayout; per JPanel è un FlowLayout.

Nella libreria Swing sono definiti diversi LayoutManager per permettere all'utente di implementare programmaticamente le politiche di ripartizione degli spazi che gli sono neccessarie, di volta in volta.
Alcuni LayoutManagers sono più indicati per un uso "diretto" o "manuale", altri sono stati progettati per essere utilizzati indirettamente, tramite un GUI Builder (come ad esempio quello presente in NetBeans).

Per JFrame, il suo BorderLayout gestisce lo spazio della finestra suddividendolo in 5 regioni o "posizioni", ognuna delle quali può contenere un solo component: NORTH, SOUTH, WEST, EAST e CENTER.

Quando aggiugni il tuo JScrollPane al JFrame, senza specificare esplicitamente la "posizione", esso viene inserito di default in CENTER.

ndakota
17-12-2009, 15:57
C'è un'altro aspetto di cui tenere conto nella faccenda della gerarchia di componenti, che nel post sopra non ho accennato: i LayoutManager.

Un LayoutManager è un oggetto che, associato a un container ne gestisce la ripartizione dello spazio interno utile per la proiezione grafica a video di tutti i component che il container stesso contiene, secondo una certa politica (che poi appunto caratterizza il LayoutManager e lo distingue dagli altri).

Ogni componente che è anche un container ha un LayoutManager associato di default.
Per JFrame, ad esempio, è un BoderLayout; per JPanel è un FlowLayout.

Nella libreria Swing sono definiti diversi LayoutManager per permettere all'utente di implementare programmaticamente le politiche di ripartizione degli spazi che gli sono neccessarie, di volta in volta.
Alcuni LayoutManagers sono più indicati per un uso "diretto" o "manuale", altri sono stati progettati per essere utilizzati indirettamente, tramite un GUI Builder (come ad esempio quello presente in NetBeans).

Per JFrame, il suo BorderLayout gestisce lo spazio della finestra suddividendolo in 5 regioni o "posizioni", ognuna delle quali può contenere un solo component: NORTH, SOUTH, WEST, EAST e CENTER.

Quando aggiugni il tuo JScrollPane al JFrame, senza specificare esplicitamente la "posizione", esso viene inserito di default in CENTER.

Ok, grazie. Tutte cose molto utili. E dei JPanel che mi dici? Pensavo si usassero come container interni al JFrame però ho visto appunto un esempio per la JTable che usava il JScrollPane.

banryu79
17-12-2009, 16:46
Ok, grazie. Tutte cose molto utili. E dei JPanel che mi dici? Pensavo si usassero come container interni al JFrame però ho visto appunto un esempio per la JTable che usava il JScrollPane.
Beh, questo perchè di una JTable in genere si vuole sempre rendere visibile tutta la sua area di proiezione e se lo spazio nel container per visualizzarla tutta in un botto potrebbe non esserci (JFrame ridimensionabile ad libitum dall'utente) JScrollPane è un "operaio specializzato" (internamente lavora con un oggetto che implementa il concetto di "viewport" ["oblò", in italiano] e le scrollbar per permette all'utente di controllarlo) alle cui cure affidare la tabella.

JPanel invece punta molto sulla semplicità: descrive semplicemente un'area rettangolare, un pannello, appunto.
E' un contenitore generico, molto versatile; dato che gli puoi associare diversi layout managers lo puoi usare come uno strumento per gestire e suddividere lo spazio.

Ad esempio con il tuo JFrame: supponi di aver aggiunto lo scrollpane con la table nel CENTER del BorderLayout.
Ora supponi di aver bisogno di piazzare nell'area a sinistra (WEST) tre sotto aree, una sopra l'altra, per gestire tre diversi gruppi di componenti.

Abbiamo detto che dentro un singola regione/"posizione" definita da un BorderLayout si può inserire un solo component: come fare?

Una soluzione consiste nel inserire un JPanel nella "posizione" (WEST) desiderata (la occuperà tutta), e poi suddividere l'interno di quel JPanel in modo opportuno (potremmo imporre a quel JPanel un FlowLayout orientato in verticale, e inseririci dentro tre nuovi JPanel (magari con un bordo visibile), uno per ognuno dei tre diversi gruppi di componenti).

Un'immagine vale più di mille parole: ecco un JFrame con BordeLayout che nella regione WEST ha inserito un JPanel definito più o meno come ti ho descritto:
http://www.freeimagehosting.net/uploads/84abd375cd.png (http://www.freeimagehosting.net/)
In CENTER c'è un JPanel, anche questo con un layout manager che dispone in verticale i componenti interni, che contiene nell'ordine: un JPanel, uno JScrollPane (che a sua volta contiene altra roba) e un altro JPanel, in posizione EAST c'è un'orribile toolbar e al JFrame è stata imposta una JMenuBar.