JPanel ed architettura

di il
7 risposte

JPanel ed architettura

Salve ragazzi, ho un problema con una interfaccia grafica.
vorrei fare una interfaccia di base unica, ed a seconda del pulsante cliccato cambiare solo il pannello centrale. Su questo codice:
public class Dipendente_Fram extends JFrame{

    // Creo i 3 pannelli divisori.
    JPanel header = new JPanel(); // Pannello di intestazione, quello in alto
    JPanel content = new JPanel(); // Pannello centrale, dove è contenuto il corpo della finestra
    JPanel footer = new JPanel(); // Pannello a pie' pagina, dove si trovano le info dell'utente.

   // Costruttore

    public Dipendente_Fram() {
        super("Bla bla bla");

        Container c = getContentPane();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setMinimumSize(new Dimension(800, 600));




        // Il GridBagLayout. Mi servono 3 righe, due piccole, una in basso ed una in alto ed una grande nel centro.

        GridBagLayout lay = new GridBagLayout();
        lay.rowWeights = new double [] {1, 5, 0.7};
        lay.columnWeights = new double [] {1};
        GridBagConstraints g = new GridBagConstraints();
        g.fill = GridBagConstraints.BOTH;
        c.setLayout(lay);

        // Inserimento dei pannelli
                g.gridx=0;
                g.gridy=0;
                c.add(header, g);


                g.gridy++;
                c.add(content, g);

                g.gridy++;
                c.add(footer, g); 
                
                ...
E quello che vorrei poi fare, nell'action listener dei pulsanti che metterò, è un qualcosa di questo tipo:

Dipendente_Fram.content = pannellox;

Dove pannello x sarà uno dei tanti pannelli che vorrei creare, solo che ho questi dubbi:

In che classe dovrei creare i pannelli? In una interfaccia creata ad hoc? In che package la devo mettere quell'eventuale classe?
I pannelli li devo dichiarare privati e poi usare un getter?

Grazie a tutti.

7 Risposte

  • Re: JPanel ed architettura

    TKingu ha scritto:


    E quello che vorrei poi fare, nell'action listener dei pulsanti che metterò, è un qualcosa di questo tipo:

    Dipendente_Fram.content = pannellox;
    Aggiornare la variabile di istanza che tiene il pannello centrale "corrente", ovviamente va bene ed è ok. Ma NON è questo di per sé che fa cambiare il pannello nel layout. Serve altro.
    E vedo che usi GridBagLayout che è più critico da modificare dopo che la finestra è visibile. Inoltre vedo che dici:

    "Mi servono 3 righe, due piccole, una in basso ed una in alto ed una grande nel centro."

    Questa è la descrizione .... del BorderLayout! Quindi direi che il GridBagLayout NON ti serve.

    TKingu ha scritto:


    In che classe dovrei creare i pannelli?
    Se intendi dire "dove vanno istanziati", dipende. Dipende se sono pochi/tanti, se hanno una inizializzazione "pesante" oppure no e quanto/quando saranno usati.
    Bisogna anche vedere COSA fa cambiare i pannelli, se è per via di eventi esterni ai pannelli o se ciascun pannello "sa" di dover mostrare certi altri pannelli.
    Tutta questa architettura va pensata BENE.

    TKingu ha scritto:


    In una interfaccia creata ad hoc? In che package la devo mettere quell'eventuale classe?
    I pannelli li devo dichiarare privati e poi usare un getter?
    Domande un po' vaghe ...
  • Re: JPanel ed architettura

    Innanzitutto ti ringrazio per la risposta, cercherò di spiegarmi meglio su quello che avrei intenzione di fare.

    andbin ha scritto:


    TKingu ha scritto:


    E quello che vorrei poi fare, nell'action listener dei pulsanti che metterò, è un qualcosa di questo tipo:

    Dipendente_Fram.content = pannellox;
    Aggiornare la variabile di istanza che tiene il pannello centrale "corrente", ovviamente va bene ed è ok. Ma NON è questo di per sé che fa cambiare il pannello nel layout. Serve altro.
    E vedo che usi GridBagLayout che è più critico da modificare dopo che la finestra è visibile. Inoltre vedo che dici:

    "Mi servono 3 righe, due piccole, una in basso ed una in alto ed una grande nel centro."

    Questa è la descrizione .... del BorderLayout! Quindi direi che il GridBagLayout NON ti serve.
    Uso il GridBagLayout solo perchè molto più comodo e versatile, ho provato con il Border, ma avevo dei problemi con le dimensioni..
    Per il come cambia andrò a cercare su internet, per ora ho solo una beta dove il pannello viene tolto e ne viene inserito un altro, mal che vada farò in quel modo.

    andbin ha scritto:


    TKingu ha scritto:


    In che classe dovrei creare i pannelli?
    Se intendi dire "dove vanno istanziati", dipende. Dipende se sono pochi/tanti, se hanno una inizializzazione "pesante" oppure no e quanto/quando saranno usati.
    Bisogna anche vedere COSA fa cambiare i pannelli, se è per via di eventi esterni ai pannelli o se ciascun pannello "sa" di dover mostrare certi altri pannelli.
    Tutta questa architettura va pensata BENE.
    Purtroppo essendo il mio primo corso di programmazione ad oggetti, non sono pratico ed esperto, per cui volevo chiedere delucidazioni prima di mettere mani al codice.

    Quel che devo fare è una interfaccia per l'utente collegato che può essere di 3 diverse tipologie, con ovviamente dei metodi diversi e quindi delle viste diverse. Di base, però, quel che cambia nella vista è solo il pannello centrale, il content.
    public class Dipendente_Fram extends JFrame{
    
        // Creo i 3 pannelli divisori.
        JPanel header = new JPanel(); // Pannello di intestazione, quello in alto
        JPanel content = new JPanel(); // Pannello centrale, dove è contenuto il corpo della finestra
        JPanel footer = new JPanel(); // Pannello a pie' pagina, dove si trovano le info dell'utente.
    
    il problema però è che non so se al livello di architettura sia possibile, anche perché non saprei dove istanziarli.
    I pannelli dovranno essere 3 per ogni tipologia, con una JTable ed un paio di pulsanti, ai quali verrà aggiunto un action listener che si occuperà di posizionare il corretto pannello al click dell'opportuno pulsante, dunque i pannelli dovranno switcharsi al click di pulsanti contenuti nei pannelli stessi.
    Avevo intenzione di creare una classe per ogni tipologia ed inserire un costruttore che mi costruisca i pannelli, andando a lanciare un "new tipologiax" ( dove ipoteticamente tipologiax è la classe che mi istanzia i pannelli per il dipendente di tipologia x) nel metodo che mi differenzia il tipo di utente una volta loggato, ma non so se questo metodo di procedere sia corretto

    andbin ha scritto:


    TKingu ha scritto:


    In una interfaccia creata ad hoc? In che package la devo mettere quell'eventuale classe?
    I pannelli li devo dichiarare privati e poi usare un getter?
    Domande un po' vaghe ...
    Hai ragione, spero che ora sia stato sufficientemente preciso, ti ringrazio ancora per la risposta datami e spero che potrai darmi un paio di dritte.
  • Re: JPanel ed architettura

    TKingu ha scritto:


    Uso il GridBagLayout solo perchè molto più comodo e versatile
    Ma ti darà problemi quando cercherai di "cambiare" componenti al suo interno.

    TKingu ha scritto:


    ho provato con il Border, ma avevo dei problemi con le dimensioni..
    In BorderLayout per NORTH/SOUTH viene rispettato il preferred height e su questo dovresti basarti.
  • Re: JPanel ed architettura

    Ti ringrazio per la dritta sul border, magari farò qualche prova.

    Per quanto riguarda l'architettura del frame, può andar bene dichiarare i pannelli in delle classe apposite, magari del model?
  • Re: JPanel ed architettura

    Salve,

    alla fine ho usato un border per il frame principale ed ho implementato alcuni dei pannelli, ma facendo qualche prova il risultato non è come avrei voluto e non capisco il motivo!
    Premetto che il codice che ho usato l'ho copiato da un altro pannello, quello con cui ho fatto qualche prova su un vecchio codice, e lì funziona.

    Di seguito posto il codice:
    Pannelli_Dipendente pannelli = new Pannelli_Dipendente(this);
    	// Costruttore
    	
    	public Dipendente_Fram() {
    		super("Bla bla bla");
    		
    		Container c = getContentPane();
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);
    		int larghezza = 800;
    		setMinimumSize(new Dimension(larghezza, 600));
    	
    		
    		
    		
    		// Il GridBagLayout. Mi servono 3 righe, due piccole in basso ed una grande in alto.
    //		GridBagLayout lay = new GridBagLayout();
    //		lay.rowWeights = new double [] {1, 5, 0.2};
    //		lay.columnWeights = new double [] {1};
    //		GridBagConstraints g = new GridBagConstraints();
    //		g.fill = GridBagConstraints.BOTH;
    		
    		// Con il Grid bag non riesce, provo con il border.
    		BorderLayout lay = new BorderLayout();
    		c.setLayout(lay);
    		
    		c.add(header, BorderLayout.NORTH);
    		header.setPreferredSize(new Dimension(larghezza, 100));
    		//content = pannelli.getJpCarrello();
    		c.add(content, BorderLayout.CENTER);
    		c.add(footer, BorderLayout.SOUTH);
    
    
    		
    		// Inserimento dei pannelli
    //				g.gridx=0;
    //				g.gridy=0;
    //				c.add(header, g);
    //				
    			
    //				g.gridy++;
    //				c.add(content, g);
    //
    //				g.gridy++;
    //				c.add(footer, g);
    //	
    		// Creazione del layout per i pannelli.
    		GridBagLayout l = new GridBagLayout();
    		GridBagConstraints j = new GridBagConstraints();
    		footer.setLayout(l);
    		header.setLayout(l);
    		content.setLayout(l);
    		
    		
    		
    		
    		// Inserimento dei componenti nei pannelli.
    		j.insets.top=10;
    		j.insets.bottom=10;
    		j.insets.right=10;
    		j.insets.left=10;
    		j.weightx=1;
    		j.weighty=1;
    		j.fill = GridBagConstraints.BOTH;
    		header.add(prova1, j);
    		j.fill = GridBagConstraints.NONE;
    		footer.add(intestazione_utente, j);
    		footer.add(utente, j);
    		footer.add(intestazione_magazzino, j);
    		footer.add(magazzino, j);
    		footer.add(logout, j);
    		content.add(pannelli.getJpCarrello(), j);
    		
    		
    		
    	
    		
    	}
    E qui la classe dove ho scritto il pannello:
    public final class Pannelli_Dipendente {
    	
    	private JTable jtcatalogo = new JTable();
    	private JTable jtcarrello = new JTable();
    	private JButton jbCarrello = new JButton("VAI AL CARRELLO");
    	private JButton jbCatalogo = new JButton("VAI AL CATALOGO");
    	private JButton cerca = new JButton("CERCA");
    	private JTextField find = new JTextField(15);
    	private JButton add = new JButton("AGGIUNGI AL CARRELLO");
    	private JButton buy = new JButton("EFETTUA ORDINE");
    	private JPanel jpCatalogo = new JPanel();
    	private JPanel jpCarrello = new JPanel();
    	
    	Dipendente_Fram dip;
    	
    	
     public  Pannelli_Dipendente (Dipendente_Fram dip){
    	 this.dip=dip;
    	 
    	 GridBagLayout gbl = new GridBagLayout();
    	 GridBagConstraints pan = new GridBagConstraints();
    	 
    	 jpCatalogo.setLayout(gbl);
    	 jpCarrello.setLayout(gbl);
    	
    		
    		pan.gridx=0;
    		pan.fill = GridBagConstraints.BOTH;
    		pan.gridy=0;
    		pan.weightx=6;
    		pan.weighty=2;
    		pan.gridheight=2;
    		jpCatalogo.add(jtcatalogo, pan);
    		jpCarrello.add(jtcarrello, pan);
    		
    		
    		pan.fill= GridBagConstraints.NONE;
    		pan.gridx++;
    		pan.gridheight=1;
    		pan.weightx=0.3;
    		jpCatalogo.add(jbCarrello, pan);
    		jpCarrello.add(jbCatalogo, pan);
    		
    		pan.gridy++;
    		jpCatalogo.add(add, pan);
    		jpCarrello.add(buy, pan);
    	 
     }
    
    public JPanel getJpCatalogo() {
    	return jpCatalogo;
    }
    
    public JPanel getJpCarrello() {
    	return jpCarrello;
    }
     
     
    	
    	
    
    }
    Quello che mi esce sono solo i pulsanti "Vai al catalogo" ed "effettua ordine" uno sotto l'altro se uso il codice
    content.add(pannelli.getJpCarrello(), j);
    affiancati se invece uso
    		content = pannelli.getJpCarrello();
    Potete spiegarmi come mai? Grazie mille.
  • Re: JPanel ed architettura

    Ciao!

    Ho provato a sistemare un po' il codice per compilare ed eseguire e rendermi conto visivamente del problema, ma mancano parecchi pezzi (utente,intestazione_utente,magazzino,logout...).

    Quindi consiglio: quando posti codice abituati a mettere quello che viene definito un SSCCE , cioè un esempio che mostra il problema (soprattutto se ,come in questo caso, è anche un problema "visivo" e non solo teorico) e che sia il più possibile corto (ma rimuovi solo ciò che è superfluo), auto contenuto , corretto e compilabile.
    In questo modo chi legge non deve perdere tempo a inserire gli import, aggiungere pezzi mancanti, "inventarsi" un metodo main etc., ma può direttamente copiare, incollare ed eseguire il programma (è molto più facile aiutarti se si ha tutto sotto mano).

    Alle tue domande iniziali (dove/come creare i pannelli etc.) è abbastanza difficile rispondere, come diceva andbin sono abbastanza vaghe per chi non ha in testa la dimensione finale dell'applicazione, il numero di classi, il design che hai pensato etc...

    Ma guardando il tuo codice io non userei una classe come Pannelli_Dipendente, scritta come è scritta ora. In generale non va molto bene esporre all'esterno di una classe i componenti, in questo caso i sotto pannelli.
    Meglio per me avere due classi separate che modellino i pannelli del catalogo e del carrello, che estendano JPanel. Se ti accorgi che le classi hanno parecchio in comune puoi anche inserire una classe intermedia, che gestisca la logica comune alle classi, ed estendere questa di classe.
    Personalmente poi io detesto l'uso del GridBagLayout, preferisco combinare tra loro layout più semplici, ma questa è una mia preferenza...

    Ma ripeto, è tutta questione di scelte e design, se intanto posti il codice completo è più facile farsi un' idea
  • Re: JPanel ed architettura

    Purtroppo al momento il codice che c'è dietro al programma non esiste, dato che al momento vorrei finire l'interfaccia grafica per poi passare ad i metodi dietro ad i bottoni..

    Comunque ho fatto un paio di screen.
    con il codice
    Pannelli_Dipendente pannelli = new Pannelli_Dipendente(this);
    	// Costruttore
    	
    	public Dipendente_Fram() {
    		super("Bla bla bla");
    		
    		Container c = getContentPane();
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);
    		int larghezza = 800;
    		setMinimumSize(new Dimension(larghezza, 600));
    	
    		
    		
    		
    		// Il GridBagLayout. Mi servono 3 righe, due piccole in basso ed una grande in alto
    		
    		BorderLayout lay = new BorderLayout();
    		c.setLayout(lay);
    		
    		c.add(header, BorderLayout.NORTH);
    		header.setPreferredSize(new Dimension(larghezza, 100));
    		//content = pannelli.getJpCarrello();    <--------- Commentato
    		c.add(content, BorderLayout.CENTER);
    		c.add(footer, BorderLayout.SOUTH);
    
    
    		// Creazione del layout per i pannelli.
    		GridBagLayout l = new GridBagLayout();
    		GridBagConstraints j = new GridBagConstraints();
    		footer.setLayout(l);
    		header.setLayout(l);
    		content.setLayout(l);
    		
    		
    		
    		
    		// Inserimento dei componenti nei pannelli.
    		j.insets.top=10;
    		j.insets.bottom=10;
    		j.insets.right=10;
    		j.insets.left=10;
    		j.weightx=1;
    		j.weighty=1;
    		j.fill = GridBagConstraints.BOTH;
    		header.add(prova1, j);
    		j.fill = GridBagConstraints.NONE;
    		footer.add(intestazione_utente, j);
    		footer.add(utente, j);
    		footer.add(intestazione_magazzino, j);
    		footer.add(magazzino, j);
    		footer.add(logout, j);
    		content.add(pannelli.getJpCarrello(), j);  <------ Non commentato
    		


    Invece con il codice
    Pannelli_Dipendente pannelli = new Pannelli_Dipendente(this);
    	// Costruttore
    	
    	public Dipendente_Fram() {
    		super("Bla bla bla");
    		
    		Container c = getContentPane();
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);
    		int larghezza = 800;
    		setMinimumSize(new Dimension(larghezza, 600));
    	
    		
    		
    		
    		// Il GridBagLayout. Mi servono 3 righe, due piccole in basso ed una grande in alto
    		
    		BorderLayout lay = new BorderLayout();
    		c.setLayout(lay);
    		
    		c.add(header, BorderLayout.NORTH);
    		header.setPreferredSize(new Dimension(larghezza, 100));
    		content = pannelli.getJpCarrello();    <--------- Non Commentato
    		c.add(content, BorderLayout.CENTER);
    		c.add(footer, BorderLayout.SOUTH);
    
    
    		// Creazione del layout per i pannelli.
    		GridBagLayout l = new GridBagLayout();
    		GridBagConstraints j = new GridBagConstraints();
    		footer.setLayout(l);
    		header.setLayout(l);
    		content.setLayout(l);
    		
    		
    		
    		
    		// Inserimento dei componenti nei pannelli.
    		j.insets.top=10;
    		j.insets.bottom=10;
    		j.insets.right=10;
    		j.insets.left=10;
    		j.weightx=1;
    		j.weighty=1;
    		j.fill = GridBagConstraints.BOTH;
    		header.add(prova1, j);
    		j.fill = GridBagConstraints.NONE;
    		footer.add(intestazione_utente, j);
    		footer.add(utente, j);
    		footer.add(intestazione_magazzino, j);
    		footer.add(magazzino, j);
    		footer.add(logout, j);
    		//content.add(pannelli.getJpCarrello(), j);   <----- Commentato questo 
    		




    Quando dovrebbe uscire:


    Il link si riferisce al solo pannello, scusate se sono un po' grandi, ma non sono riuscito a ridimensionarle con Gimp..
Devi accedere o registrarti per scrivere nel forum
7 risposte