2015-10-30 13 views
5

Nel mio programma, voglio all'utente di:Come evitare nidificazioni di azioni annidate?

  1. selezionamento/aprire un database (come Access) per conto proprio
  2. scegliere una tabella dal database
  3. selezionare la colonna (s) dalla tabella

Nel mio codice, ho una classe che fa qualcosa di simile:

mntmOpenDatabase.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     //open the database 
     //display tables as buttons 
     tableButton.addActionListener(new ActionListener() { // select a table 
      public void actionPerformed(ActionEvent e) { 
       //display the columns of the table selected as buttons 
        colButton.addActionListener(new ActionListener() { 
         public void actionPerformed(ActionEvent e) {// add to the list of columns to be exported } 

E questo si traduce in un blocco di codice molto grande. C'è un modo più semplice e più pulito per farlo?

+2

[Come utilizzare Azioni] (http: // docs. oracle.com/javase/tutorial/uiswing/misc/action.html) – MadProgrammer

risposta

10

La soluzione è quella di refactoring:

  • creare una classe separata e separatamente verificabile per il codice per aprire il database.
  • E una classe separata e verificabile separatamente per la visualizzazione di questi dati.
  • In ActionListener, creare istanze di queste classi o interagire con esse, se già esistono.
  • Imparate i principi di base del modello di progettazione M-V-C (Model-View-Control) e usateli. Non devi essere pedante per loro, e Lord - sa che ci sono molte varianti, ma i loro principi guida generali dovrebbero essere almeno rispettati.
  • Cerca di rendere la tua GUI o visualizza come il più stupido possibile. Sa come visualizzare i suoi dati, ha le funzionalità per consentire al controllo di aggiornare il suo display e sa come notificare il controllo quando l'utente interagisce con esso, e questo è quanto.
  • Raccomandazione laterale 1: assicurarsi che tutte le interazioni del database avvengano in un thread in background.
  • Raccomandazione laterale 2: assicurarsi che quasi tutte le interazioni Swing siano eseguite sullo Swing EDT (il thread di invio evento).

Si prega di guardare questo simile ma più completa domanda e risposta: How can one best avoid writing bloated GUI code?. Le risposte sono buone e mi piacerebbe poterle votare in su in un giro di miliardi di volte.

Ad esempio, il codice di cui sopra potrebbe essere semplice come:

mntmOpenDatabase.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     control.openDatabase(); 
    } 
} 
+0

Quindi alla fine ho fatto un po 'di ricerche su MVC. E penso di avere l'idea di base, comunque mi chiedo ancora, dove dovrei inserire ActionListeners? All'interno del controller o della vista? Sembra che ci siano opinioni diverse su questo. – PuggyLongLegs

+1

@ForeverLearning: è perché entrambi potrebbero funzionare bene.Secondo me, se gli ActionListener sono nella Vista, sono molto semplici e tutto ciò che fanno è chiamare un metodo di controllo equivalente, come mostrato sopra. Altrimenti potresti avere il controllo che inietta azioni nella vista. –

+0

Sembra buono. Penso che ci proverò. Ma sarebbe una buona idea creare una classe Action che contenga tutti gli ascoltatori di azioni o semplicemente metterli tutti nella stessa classe con i componenti che va bene? – PuggyLongLegs

1

Nel tuo esempio si istanziare e aggiungere nuovo listener su ogni ActionEvent. Davvero dovresti configurarlo una volta. Qualcosa di simile a questo:

public class OpenDataBaseListener implements ActionListener{ 
     @Override 
     public void actionPerformed(ActionEvent e){ 
       //your event handling here 
     } 
} 

public class TableButtonListener implements ActionListener{ 
     @Override 
     public void actionPerformed(ActionEvent e){ 
      //your logic 
     } 
} 

ecc ...

E quando si creano i vostri ascoltatori è necessario registrarsi una volta:

mntmOpenDatabase.addActionListener(new OpenDataBaseListener()); 
tableButton.addActionListener(new TableButtonListener()); 
colButton.addActionListener(new ColButtonListener()); 
Problemi correlati