Domanda

Ho un JFrame che contiene un " display " JPanel con JTextField e un "controllo" JPanel con pulsanti che dovrebbero accedere al contenuto del display JPanel . Penso che il mio problema sia legato all'uso del modello di osservatore, che in linea di principio capisco. Devi posizionare i listener e aggiornare i messaggi, ma non ho idea di dove inserirli, come accedere da un pannello all'altro e forse, se necessario, introdurre un "datamodel" classe. Ad esempio, desidero accedere al contenuto di JTextField dal pannello di controllo e utilizzo un listener di azioni anonimo come segue:

JButton openfile = new JButton("Convert file");
openfile.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
        openButtonPressed();
    }           
});
È stato utile?

Soluzione

Devi ridurre l'accoppiamento tra questi oggetti.

Puoi avere un oggetto master, che possiede tutti i campi di testo e il pulsante (i pannelli sono irrilevanti)

Quindi un listener di azioni separato all'interno di quell'oggetto master (lo chiamo mediatore, vedi schema mediatore)

Quel listener di azioni esegue un metodo sul mediatore che a sua volta prende i valori dai campi di testo e crea forse un oggetto di trasferimento.

In questo modo riduci l'accoppiamento tra i pannelli, i campi di testo ecc. e lasci che il controllo sia in un posto (il mediatore), cioè non gli fai conoscere l'un l'altro.

Puoi dare un'occhiata al codice in questa domanda: https://stackoverflow.com/questions/324554/#324559

Mostra questi concetti in esecuzione del codice.

A proposito, il modello di osservatore è già implementato in JTextField, JButton, ActionListener ecc. Devi solo aggiungere gli hook.

Spero che questo aiuti.

MODIFICA Unite due risposte in una.

Questo è il codice.

class App { // this is the mediator

    // GUI components.
    private JFrame frame;
    private JTextField name;
    private JTextField count;
    private JTextField date;
    // Result is displayed here.
    private JTextArea textArea;

    // Fired by this button.
    private JButton   go;

    private ActionListener actionListener;


    public App(){
        actionListener = new ActionListener(){
            public void actionPerformed( ActionEvent e ){
                okButtonPressed();
            }
        };
    }

    private void okButtonPressed(){
         // template is an object irrelevant to this code.
         template.setData( getData() );
         textArea.setText( template.getTransformedData() );
    }


    public void initialize(){

        frame     = new JFrame("Code challenge v0.1");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        name     = new JTextField();
        count    = new JTextField();
        date     = new JTextField();
        textArea = new JTextArea();
        go       = new JButton("Go");
        go.addActionListener( actionListener ); // prepare the button.

        layoutComponents(); // a lot of panels are created here. Irrelevant.
    }
}

Il codice completo e funzionante può essere recuperato qui:

È importante favorire la composizione rispetto all'eredità, quando possibile.

Altri suggerimenti

Rende il codice più pulito se si creano i modelli in un livello e si aggiunge uno o due livelli sopra per creare i componenti e il layout. Certamente non estendere artisti del calibro di JFrame e JPanel .

Non senti la necessità di far corrispondere esattamente la gerarchia della composizione nel livello del modello al display. Quindi si tratta solo di prendere il testo dal Document e di eseguire l'operazione pertinente.

Okay, forse non è così semplice. I modelli Swing sono un po 'disordinati. In particolare ButtonModel è danneggiato al cervello e l'area del codice del controller potrebbe non essere del tutto pura.

Abbiamo i cosiddetti costruttori, che costruiranno il pannello genitore dai figli. In questo builder avrai accesso a tutti i sottocomponenti che devi ascoltare e puoi quindi implementare qualsiasi logica lì.

Alla fine il builder restituirà quindi il pannello padre con la logica completa.

Una volta che hai il pannello principale è davvero un casino arrivare ai componenti figlio e farli fare qualsiasi cosa.

Grazie. Ho aggiunto un livello di modello di dati che gestisce in qualche modo la comunicazione tra i pannelli.

Ho anche trovato utile questo link su Ascoltatori su JTextField:

text link

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top