prima prova di GUI - swing

Stato
Discussione chiusa ad ulteriori risposte.

petrusic

Utente Attivo
227
20
CPU
AMD Athlon - X86_64
Scheda Madre
Acer RS780HVF
HDD
SSD PLUS da 240GB (ospita 3 S.O Linux), WDC WD10EFRX-68F da 1000GB (ospita solo archivi dati)
RAM
n.2 DDR" per 2GB
OS
fedora 28 Mate, Ubuntu Mate, Linux Mint 19
Per provare particamente la GUI con le modalità swing ho avviato un nuovo progetto che riporto per intero
Codice:
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TstContFam {
    private static JButton p2 = null;
   
    private int sw = 0;
   
    public static void main(String[] args) {
        // TODO Stub di metodo generato automaticamente
        JFrame fMain = new JFrame("Verifica congruità Tabelle del DB.ContabFam");
        fMain.setBounds(50, 50, 800, 480);        //limiti(bounds): x=, y=, w=800, h=480
        Container mainForm = fMain.getContentPane();
        mainForm.setLayout(new BoxLayout(mainForm, BoxLayout.Y_AXIS)); 
                // disegno un contenitore 'Panel con sviluppo verticale
//        |--------------------------------------------------------------------------
        JPanel sup = new JPanel();
            sup.setLayout(new BoxLayout(sup, BoxLayout.X_AXIS));
//                |------------------------------------------------------------------               
                JPanel arTb = new JPanel();
                    arTb.setLayout(new BoxLayout(arTb, BoxLayout.X_AXIS));
//                  |--------------------------------------------------------------
                    JPanel col1 = new JPanel();
                        col1.setLayout(new BoxLayout(col1, BoxLayout.Y_AXIS));
                            JLabel l1 = new JLabel();
                            col1.add(l1);
                            JCheckBox cb2 = new JCheckBox("componfam");
                            col1.add(cb2);
//                    |--------------------------------------------------------------
                    JPanel col2 = new JPanel();
                        col2.setLayout(new BoxLayout(col2, BoxLayout.Y_AXIS));
                            JLabel c2l1 = new JLabel("Letti");
                            col2.add(c2l1);
                            JLabel c2l2 = new JLabel("etichetta");
                            col2.add(c2l2);
//                    |--------------------------------------------------------------
                    JPanel col3 = new JPanel();
                        col3.setLayout(new BoxLayout(col3, BoxLayout.Y_AXIS));
                            JLabel c3l1 = new JLabel("Modificati");
                            col3.add(c3l1);
                            JLabel c3l2 = new JLabel("etichetta");
                            col3.add(c3l2);
//                |------------------------------------------------------------------               
                JPanel arMsg = new JPanel();
//                    arMsg.setLayout(new BoxLayout(arMsg, BoxLayout.X_AXIS));
//                    |--------------------------------------------------------------
                    JLabel lMsg = new JLabel("Messaggistica operativa");
                            arMsg.add(l1);
//        |--------------------------------------------------------------------------
        JPanel inf = new JPanel();
            inf.setLayout(new BoxLayout(inf, BoxLayout.X_AXIS));
//            |--------------------------------------------------------------           
            JButton p1 = new JButton("E S C I");
                arMsg.add(p1);
//riga 64----------------------------------------------------------
                 p1.addActionListener(new clicPuls1());
//---------------------------------------------------------------------- ERRORE ERRORE ERRORE
//             JButton p2
                p2.setText(("AVVIA VERIFICA"));
                arMsg.add(p2);
                p2.addActionListener(new clicPuls2());
    }
   
    private class clicPuls1 implements ActionListener {        // classe privata interna alla principale
//         TODO Stub di costruttore generato automaticamente
            public void actionPerformed(ActionEvent ev1) {
            }
    }
   
    private class clicPuls2 implements ActionListener {        // classe privata interna alla principale
//         TODO Stub di costruttore generato automaticamente
            public void actionPerformed(ActionEvent ev2) {
                if (sw == 0) {
                    sw = 1;
                    p2.setBackground(Color.YELLOW);
                }
                else {
                    sw = 0;
                    p2.setBackground(Color.CYAN);
                }
            }
    }
}
Non capisco l'errore che viene segnalato alla riga 64
Non è possibile accedere a nessuna istanza di inclusione di tipo TstContFam. È necessario qualificare l'allocazione con un'istanza di inclusione di tipo TstContFam (esempio: x.new A() dove x è un'istanza di TstContFam).
Ciò anche perchè lo stesso codice è ripetuto sotto, alla riga 68, senza alcuna segnalazione d'errore, ma anche perchè, ripetendo i criteri di utilizzo illustrati nella lez.7 del videocorso, secondo me quello che ho scritto doveva essere corretto.
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Le classi devi chiamarle con un nome che inizia per maiuscola (non è questo l'errore naturalmente);
l'errore te lo dice il compilatore: stai cercando di usare una variabile non statica (clickPls) dentro un contesto statico e questo non si può fare
 

petrusic

Utente Attivo
227
20
CPU
AMD Athlon - X86_64
Scheda Madre
Acer RS780HVF
HDD
SSD PLUS da 240GB (ospita 3 S.O Linux), WDC WD10EFRX-68F da 1000GB (ospita solo archivi dati)
RAM
n.2 DDR" per 2GB
OS
fedora 28 Mate, Ubuntu Mate, Linux Mint 19
Grazie BAT000cent. Il programmino scritto doveva servire ad ottenere la prima finestra grafica di esercitazione.
Io ho cercato di capire come risolvere l'anomalia incontrata, ma la mia inesperienza mi faceva perdere troppo tempo.
Ecco per cui ho chiesto cortese aiuto.
Ho letto la tua risposta, ma, avendo troppo curiosità visiva, ho sostituito ai pulsanti tre label ed ho ottenuto il risultato allegato
prova_gui.png
Per ottenere ciò hio dovuto modificare il programma sostituendo ai pannelli con orientamento verticale, altri pannelli con orientamento orizzontale. Riporto perciò soltanto un piccolo scorcio di programma:
Codice:
public static void main(String[] args) {
        // TODO Stub di metodo generato automaticamente
        JFrame fMain = new JFrame("Verifica congruità Tabelle del DB.ContabFam");
        fMain.setBounds(50, 50, 600, 400);        //limiti(bounds): x=, y=, w=800, h=480
        fMain.setLocationRelativeTo(null);        // centra la finestra sullo schermo
        Container mainForm = fMain.getContentPane();
        mainForm.setLayout(new BoxLayout(mainForm, BoxLayout.X_AXIS));
                // disegno un contenitore 'Panel con sviluppo verticale
//        |--------------------------------------------------------------------------
            JPanel sx = new JPanel();
            sx.setLayout(new BoxLayout(sx, BoxLayout.X_AXIS));
            mainForm.add(sx);
//                |------------------------------------------------------------------              
                JPanel arTb = new JPanel();
                arTb.setLayout(new BoxLayout(arTb, BoxLayout.Y_AXIS));
                sx.add(arTb);
//                  |--------------------------------------------------------------
                    JPanel r1 = new JPanel();
                    r1.setLayout(new BoxLayout(r1, BoxLayout.X_AXIS));
                    arTb.add(r1);
                        JLabel r1l1 = new JLabel("etich.prova");
                        r1.add(r1l1);
                        JLabel r1l2 = new JLabel("Letti      ");
                        r1.add(r1l2);
                        JLabel r1l3 = new JLabel("Modificati ");
                        r1.add(r1l3);
                    JPanel r2 = new JPanel();
                    r2.setLayout(new BoxLayout(r2, BoxLayout.X_AXIS));
                    arTb.add(r2);
                        JCheckBox cb1 = new JCheckBox("causalifreq");
                        r2.add(cb1);
                        JLabel r2l1 = new JLabel("--- letti - cb1 ---");
                        r2.add(r2l1);
                        JLabel r2l2 = new JLabel("--- modif - cb1 ---");
                        r2.add(r2l2);
// --- bla bla bla ---                      
    fMain.setVisible(true);
            fMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
A mio avviso è un vero disastro. Come dovrei procedere per ottenere allineamenti decenti e regolare la distanza tra un oggetto ed il successivo della stessa riga. Inoltre la label situata sul lato destro della finestra me l'aspettavo al centro del proprio pannello.
Ho pensato di abbinare ai singoli oggetti interni ai pannelli un'istruzione simile a quella usata per il dimensionamento del JFrame:
Codice:
r3.setBounds(0, 0, 65, 400);
che, naturalmente ho provato, ma non ha funzionato.
E allora come faccio?
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
La gestione del layout con Swing è complicata. Ti suggerisco di usare il BorderLayout combinato con layout del flusso (dove semplicemente aggiungi componenti una dietro l'altra), abbastanza semplice e, se capisci il meccanismo, ti permette di creare interfacce decenti. In pratica si tratta di definire una finestra principale con BorderLayout, dove "appendi" componenti a nord, sud, est ovest e centro. Solo che ad ogni zona puoi aggiungere una sola componente: per es. se aggiungi un bottone a nord, esso si estende per tutta la larghezza della finestra. Il trucco sta nell'aggiungere altri pannelli ai quali a loro volta inserisci una o più componenti usanod il layotut del flusso.
Ti allego un file scritto in Java 8 che stavo usando l'anno scorso per mostrare ad un amico come si poteva fare una GUI;
scaricalo, elimina l'estensione .txt, compilalo ed eseguilo e vedrai una semplice GUI (non è un'applicazione, non fa niente è solo una dimostrazione di GUI) . Il codice è completamente commentato e vedrai che è di facile comprensione. Guarda il metodo main alla fine: in pratica sono solo 3 righe, ed è il metodo standard suggerito da Java Tutorial ufficiale per mostrare una GUI in Swing.
Tu stai costruendo l'intera GUI dentro il main, non va assolutamente bene: la GUI la devi costruire pezzo per pezzo con metodi "piccoli", testabili uno per uno (quella dell'allegato è fatta a mano, senza usare IDE che permettono la costruzione di GUI per via grafica, solo Bluej). Il main deve servire esclusivamente alle istruzioni di visualizzazione.

Scaricati il Java tutorial dal sito Oracle (https://docs.oracle.com/javase/tutorial/), è molto utile e contiene tutta una serie di lezioni sulle GUI Swing.
 

Allegati

  • TestGUI.java.txt
    11.2 KB · Visualizzazioni: 70
Ultima modifica:

petrusic

Utente Attivo
227
20
CPU
AMD Athlon - X86_64
Scheda Madre
Acer RS780HVF
HDD
SSD PLUS da 240GB (ospita 3 S.O Linux), WDC WD10EFRX-68F da 1000GB (ospita solo archivi dati)
RAM
n.2 DDR" per 2GB
OS
fedora 28 Mate, Ubuntu Mate, Linux Mint 19

petrusic

Utente Attivo
227
20
CPU
AMD Athlon - X86_64
Scheda Madre
Acer RS780HVF
HDD
SSD PLUS da 240GB (ospita 3 S.O Linux), WDC WD10EFRX-68F da 1000GB (ospita solo archivi dati)
RAM
n.2 DDR" per 2GB
OS
fedora 28 Mate, Ubuntu Mate, Linux Mint 19
Mi dispisace, ho sospeso tutto perchè questo tipo di GUI mi sembra tutt'altro che governabile. Credo di avere perso un sacco di tempo.
Sto pensando se non sia il caso di guardare verso un altro linguaggio.
A tale proposito aprirò una nuova discussione.
 
Stato
Discussione chiusa ad ulteriori risposte.

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!