L'uso di più JFrame: buona o cattiva pratica? [Chiuso]
Sto sviluppando un'applicazione che visualizza immagini e riproduce suoni da un database. Sto cercando di decidere se utilizzare o meno un JFrame separato per aggiungere immagini al database dalla GUI.
Mi chiedo solo se sia una buona pratica utilizzare più finestre JFrame?
Risposte
Mi chiedo solo se sia una buona pratica utilizzare più JFrame?
Cattiva (cattiva, cattiva) pratica.
- Scortese per l'utente: l'utente vede più icone nella barra delle applicazioni quando si aspetta di vederne solo una. Inoltre gli effetti collaterali dei problemi di codifica ..
- Un incubo da programmare e mantenere:
- Una finestra di dialogo modale offre la facile opportunità di focalizzare l'attenzione sul contenuto di quella finestra di dialogo: scegli / correggi / annulla, quindi procedi. Più fotogrammi non lo fanno.
- Una finestra di dialogo (o barra degli strumenti mobile) con un genitore verrà in primo piano quando si fa clic sul genitore: dovresti implementarlo nei frame se questo fosse il comportamento desiderato.
Esistono diversi modi per visualizzare molti elementi in una GUI, ad esempio:
- CardLayout(breve demo. ). Buono per:
- Visualizzazione di finestre di dialogo simili a procedure guidate.
- Visualizzazione delle selezioni di elenchi, alberi, ecc. Per gli elementi a cui è associato un componente.
- Passaggio da nessun componente a componente visibile.
- JInternalFrame/JDesktopPane tipicamente utilizzato per un MDI .
- JTabbedPane per gruppi di componenti.
- JSplitPane Un modo per visualizzare due componenti la cui importanza tra l'una o l'altra (la dimensione) varia a seconda di ciò che sta facendo l'utente.
- JLayeredPane molti componenti ben stratificati.
- JToolBarin genere contiene gruppi di azioni o controlli. Può essere trascinato all'interno della GUI o completamente in base alle esigenze dell'utente. Come accennato in precedenza, minimizzerà / ripristinerà secondo il genitore che lo fa.
- Come elementi in a JList(semplice esempio di seguito).
- Come nodi in un file JTree.
- Layout annidati .
Ma se queste strategie non funzionano per un particolare caso d'uso, prova quanto segue. Stabilisci un singolo main JFrame
, quindi fai apparire JDialogo JOptionPaneistanze per il resto degli elementi fluttuanti, usando il frame come genitore per le finestre di dialogo.
Molte immagini
In questo caso in cui gli elementi multipli sono immagini, sarebbe meglio utilizzare invece uno dei seguenti:
- Un unico
JLabel
(centrato in un riquadro di scorrimento) per visualizzare qualsiasi immagine a cui l'utente è interessato in quel momento. Come visto in ImageViewer.
- Una sola riga
JList
. Come si vede in questa risposta . La parte "singola riga" funziona solo se hanno tutte le stesse dimensioni. In alternativa, se si è pronti a ridimensionare le immagini al volo, e hanno tutte le stesse proporzioni (ad esempio 4: 3 o 16: 9).
L' JFrame
approccio multiplo è stato qualcosa che ho implementato da quando ho iniziato a programmare le app Swing. Per la maggior parte, l'ho fatto all'inizio perché non sapevo niente di meglio. Tuttavia , quando ho maturato la mia esperienza e conoscenza come sviluppatore e ho iniziato a leggere e assorbire le opinioni di tanti sviluppatori Java più esperti online, ho tentato di allontanarmi dall'approccio multiplo JFrame
(sia nei progetti attuali che in quelli futuri ) solo per incontrare ... ottenere questa ... resistenza dai miei clienti! Quando ho iniziato a implementare finestre di dialogo modali per controllare le finestre "figlio" JInternalFrame
es per componenti separati, i miei clienti hanno iniziato a lamentarsi! Sono rimasto piuttosto sorpreso, poiché stavo facendo quello che pensavo fosse la migliore pratica! Ma, come si suol dire, "Una moglie felice è una vita felice". Lo stesso vale per i tuoi clienti. Ovviamente sono un appaltatore, quindi i miei utenti finali hanno accesso diretto a me, lo sviluppatore, il che ovviamente non è uno scenario comune.
Quindi, spiegherò i vantaggi dell'approccio multiplo JFrame
, oltre a sfatare alcuni dei contro che altri hanno presentato.
- Massima flessibilità nel layout - Consentendo messaggi separati
JFrame
, offri all'utente finale la possibilità di distribuire e controllare ciò che è sul suo schermo. Il concetto sembra "aperto" e non costrittivo. Perdi questo quando vai verso un grandeJFrame
e un mucchio diJInternalFrame
s. - Funziona bene per applicazioni molto modulari - Nel mio caso, la maggior parte delle mie applicazioni ha 3 - 5 grandi "moduli" che in realtà non hanno nulla a che fare l'uno con l'altro. Ad esempio, un modulo potrebbe essere un dashboard di vendita e uno potrebbe essere un dashboard di contabilità. Non parlano tra loro o altro. Tuttavia, il dirigente potrebbe voler aprire entrambi e il fatto di essere frame separati sulla barra delle applicazioni gli rende la vita più facile.
- Rende facile per gli utenti finali fare riferimento a materiale esterno - Una volta, ho avuto questa situazione: la mia app aveva un "visualizzatore di dati", da cui si poteva fare clic su "Aggiungi nuovo" e si apriva una schermata di immissione dei dati. Inizialmente, entrambi erano
JFrame
s. Tuttavia, volevo che la schermata di immissione dei dati fosse ilJDialog
cui genitore era il visualizzatore di dati. Ho apportato la modifica e immediatamente ho ricevuto una chiamata da un utente finale che faceva molto affidamento sul fatto che poteva ridurre a icona o chiudere il visualizzatore e tenere aperto l' editor mentre faceva riferimento a un'altra parte del programma (o un sito web, non non ricordo). E ' non è su un multi-monitor, in modo che gli serviva la finestra di ingresso di essere il primo e qualcos'altro di essere secondo, con i dati spettatore completamente nascosti. Questo era impossibile con aJDialog
e certamente sarebbe stato impossibile anche con aJInternalFrame
. A malincuore l'ho cambiato di nuovo per essere separatoJFrames
per la sua sanità mentale, ma mi ha insegnato una lezione importante. - Mito: difficile da codificare - Questo non è vero nella mia esperienza. Non vedo perché sarebbe più facile creare a
JInternalFrame
rispetto aJFrame
. In effetti, secondo la mia esperienza,JInternalFrames
offrono molta meno flessibilità. Ho sviluppato un modo sistematico di gestire l'apertura e la chiusura dei messaggi di postaJFrame
elettronica nelle mie app che funziona davvero bene. Controllo il frame quasi completamente dall'interno del codice del frame stesso; la creazione del nuovo frame,SwingWorker
che controlla il recupero dei dati sui thread in background e il codice della GUI su EDT, ripristinando / portando in primo piano il frame se l'utente prova ad aprirlo due volte, ecc. Tutto ciò che serve per aprire il mioJFrame
è chiama un metodo statico pubblicoopen()
e il metodo open, combinato con unwindowClosing()
evento, gestisce il resto (il frame è già aperto? non è aperto, ma è in caricamento? ecc.) Ho reso questo approccio un modello quindi non è difficile da implementare per ogni frame . - Mito / non provato: risorse pesanti - Mi piacerebbe vedere alcuni fatti dietro questa affermazione speculativa. Anche se, forse, potresti dire che a ha
JFrame
bisogno di più spazio di aJInternalFrame
, anche se apri 100JFrame
secondi, quante risorse in più consumeresti davvero? Se la tua preoccupazione è la perdita di memoria a causa delle risorse: la chiamatadispose()
libera tutte le risorse usate dal frame per la garbage collection (e, di nuovo dico, aJInternalFrame
dovrebbe invocare esattamente la stessa preoccupazione).
Ho scritto molto e mi sento come se potessi scrivere di più. Ad ogni modo, spero di non essere screditato semplicemente perché è un'opinione impopolare. La domanda è chiaramente preziosa e spero di aver fornito una risposta valida, anche se non è l'opinione comune.
Un ottimo esempio di più frame / singolo documento per frame ( SDI ) vs singolo frame / più documenti per frame ( MDI ) è Microsoft Excel. Alcuni dei vantaggi di MDI:
- è possibile avere alcune finestre di forma non rettangolare, in modo che non nascondano il desktop o altre finestre da un altro processo (es. browser web)
- è possibile aprire una finestra da un altro processo su una finestra di Excel mentre si scrive nella seconda finestra di Excel: con MDI, provare a scrivere in una delle finestre interne darà il focus all'intera finestra di Excel, nascondendo quindi la finestra da un altro processo
- è possibile avere documenti diversi su schermi diversi, il che è particolarmente utile quando gli schermi non hanno la stessa risoluzione
SDI (Single-Document Interface, ovvero ogni finestra può avere un solo documento):
MDI (Multiple-Document Interface, ovvero ogni finestra può avere più documenti):
Vorrei contrastare l'argomento "non user friendly" con un esempio di cui sono stato appena coinvolto.
Nella nostra applicazione abbiamo una finestra principale in cui gli utenti eseguono vari "programmi" come schede separate. Per quanto possibile abbiamo cercato di mantenere la nostra applicazione su questa singola finestra.
Uno dei "programmi" eseguiti presenta un elenco di report che sono stati generati dal sistema e l'utente può fare clic su un'icona su ciascuna riga per aprire una finestra di dialogo del visualizzatore di report. Questo visualizzatore mostra l'equivalente delle pagine A4 verticale / orizzontale del rapporto, quindi agli utenti piace che questa finestra sia piuttosto grande, quasi riempiendo i loro schermi.
Alcuni mesi fa abbiamo iniziato a ricevere richieste dai nostri clienti per rendere non modali queste finestre del visualizzatore di report, in modo che potessero avere più report aperti contemporaneamente.
Per un po 'ho resistito a questa richiesta perché non pensavo fosse una buona soluzione. Tuttavia, la mia mente è cambiata quando ho scoperto come gli utenti stavano aggirando questa "carenza" del nostro sistema.
Stavano aprendo un visualizzatore, utilizzando la funzione "Salva con nome" per salvare il report come PDF in una directory specifica, utilizzando Acrobat Reader per aprire il file PDF, quindi avrebbero fatto lo stesso con il report successivo. Avrebbero più lettori Acrobat in esecuzione con i vari output di report che volevano esaminare.
Così ho ceduto e ho reso lo spettatore indifferente. Ciò significa che ogni visualizzatore ha un'icona sulla barra delle applicazioni.
Quando l'ultima versione è stata rilasciata loro la scorsa settimana, la risposta travolgente da parte loro è che lo ADORANO. È stato uno dei nostri miglioramenti recenti più popolari al sistema.
Quindi vai avanti e dici ai tuoi utenti che quello che vogliono è male, ma alla fine non ti farà alcun favore.
ALCUNE NOTE:
- Sembra essere una buona pratica usare JDialog per queste finestre non modali
- Utilizza i costruttori che utilizzano l' argomento new
ModalityType
anziché booleanomodal
. Questo è ciò che dà a queste finestre di dialogo l'icona della barra delle applicazioni. - Per i dialoghi non modali, passare un genitore nullo al costruttore, ma individuarli rispetto alla loro finestra "genitore".
- La versione 6 di Java su Windows ha un bug che significa che la tua finestra principale può diventare "sempre in primo piano" senza che tu lo dica. Esegui l'upgrade alla versione 7 per risolvere questo problema
Crea un jInternalFrame nel frame principale e rendilo invisibile. Quindi puoi usarlo per ulteriori eventi.
jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
È passato un po 'di tempo dall'ultima volta che tocco lo swing, ma in generale è una cattiva pratica farlo. Alcuni dei principali svantaggi che mi vengono in mente:
È più costoso: dovrai allocare molte più risorse per disegnare un JFrame che altro tipo di contenitore di finestre, come Dialog o JInternalFrame.
Non facile da usare: non è facile navigare in un gruppo di JFrame attaccati insieme, sembrerà che la tua applicazione sia un insieme di applicazioni incoerenti e di scarsa progettazione.
È facile usare JInternalFrame Questo è un po 'retorico, ora è molto più semplice e altre persone più intelligenti (o con più tempo libero) di quanto pensassimo già attraverso il pattern Desktop e JInternalFrame, quindi consiglierei di usarlo.
Sicuramente una cattiva pratica. Uno dei motivi è che non è molto "user-friendly" per il fatto che ogni JFrame
mostra una nuova icona sulla barra delle applicazioni. Controllare più JFrame
s ti farà strappare i capelli.
Personalmente, userei ONE JFrame
per il tuo tipo di applicazione. I metodi per visualizzare più cose dipendono da te, ce ne sono molti. Canvas
ES, JInternalFrame
, CardLayout
, anche JPanel
s possibilmente.
Oggetti JFrame multipli = Dolore, guai e problemi.
Penso che l'utilizzo di più messaggi di posta Jframe
elettronica non sia una buona idea.
Invece possiamo usare JPanel
s più di uno o più JPanel
nello stesso JFrame
.
Inoltre possiamo passare da questo JPanel
s. Quindi ci dà la libertà di mostrare più che su cosa nel file JFrame
.
Per ognuno JPanel
possiamo progettare cose diverse e tutto questo JPanel
può essere visualizzato su JFrame
una alla volta.
Per passare da uno all'altro JPanel
, usa JMenuBar
con JMenuItems
for each JPanel
o 'JButton for each
JPanel`.
Più di uno JFrame
non è una buona pratica, ma non c'è niente di sbagliato se ne vogliamo più di uno JFrame
.
Ma è meglio cambiarne uno JFrame
per le nostre diverse esigenze piuttosto che avere più messaggi JFrame
.
Se i frame avranno le stesse dimensioni, perché non creare il frame e passare il frame come riferimento ad esso.
Quando hai superato il frame puoi decidere come popolarlo. Sarebbe come avere un metodo per calcolare la media di un insieme di cifre. Creeresti il metodo più e più volte?
Non è una buona pratica, ma anche se desideri usarlo puoi usare il pattern singleton come buono. Ho usato i modelli singleton nella maggior parte del mio progetto, è buono.