Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    Raggruppamento eventi in un JFrame

    ciao a tutti!

    avrei bisogno di un consiglio, probabilmente su un argomento banale.

    ho un JFrame con parecchi bottoni, voci di menu, input text, ecc.
    ed ho anche parecchi eventi.
    per ora il codice degli eventi l'ho messo tutto nel costruttore del JFrame.
    ad esempio:
    codice:
    // EVENTI MENU
            itemSaveTxt.addActionListener((ActionEvent e) -> {
                try {
                    FileChooser fc = new FileChooser();
                    fc.salvaTxt(tableData);
                } catch (IOException | WriteException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            });
    
            itemSavePdf.addActionListener((ActionEvent e) -> {
                try {
                    FileChooser fc = new FileChooser();
                    fc.salvaPdf(jsonRead.getAllBooks());
                } catch (IOException | DocumentException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            });
    
            itemSaveXls.addActionListener((ActionEvent e) -> {
                try {
                    FileChooser fc = new FileChooser();
                    fc.salvaXls(tableData);
                } catch (IOException | WriteException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            });
    
            itemPrint.addActionListener((ActionEvent e) -> {
                try {
                    tableData.print(JTable.PrintMode.FIT_WIDTH);
                } catch (PrinterException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            });
    
            itemAuthorsChart.addActionListener((ActionEvent e) -> {
                FormGraph fg = new FormGraph(UrlAndPath.GRAPH_AUTHORS);
                fg.setVisible(true);
            });
    
            itemEditorsChart.addActionListener((ActionEvent e) -> {
                FormGraph fg = new FormGraph(UrlAndPath.GRAPH_EDITORS);
                fg.setVisible(true);
            });
    
            itemEsc.addActionListener((ActionEvent e) -> {
                close();
            });
    
            itemAbout.addActionListener((ActionEvent e) -> {
                FormAbout about = new FormAbout();
                about.setVisible(true);
            });
    
            itemSaveXml.addActionListener((ActionEvent e) -> {
                try {
                    FileChooser fc = new FileChooser();
                    fc.salvaXml(tableData);
                } catch (JAXBException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            });
    tanto per metterne qualcuno (relativi solo al menu, ne ho molto di più se considero anche gli altri componenti).
    quello che volevo capire è se esiste un modo miglire, dal punto di vista stilistico, per scrivere il codice degli eventi.
    oppure va bene metterli così nel costruttore??

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    quello che volevo capire è se esiste un modo miglire, dal punto di vista stilistico, per scrivere il codice degli eventi.
    Se l'action listener non deve avere "stato" differente per i vari tipi di componenti gestiti, puoi anche avere una singola implementazione del ActionListener e distinguere il componente "sorgente" dal getSource() dell'evento.
    Vedi un mio sorgente di esempio qui
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    ciao andbin!

    ho guardato il tuo esempio.
    direi che è chiaro.
    però scusa l'ignoranza, per "stato" cosa intendi?

    se dovessi raggruppare gli eventi per "tipologia", dovrei intercettare:
    - quando viene premuto un item menu
    - quando viene premuto un bottone
    - il tasto invio su alcune caselle di input
    - il cambiamento del valore selezionato di una combo box

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    però scusa l'ignoranza, per "stato" cosa intendi?
    Si intende l'insieme di informazioni contenute in un oggetto .... che poi banalmente sono le variabili di "istanza" della classe.

    Quote Originariamente inviata da fermat Visualizza il messaggio
    se dovessi raggruppare gli eventi per "tipologia", dovrei intercettare:
    - quando viene premuto un item menu
    - quando viene premuto un bottone
    - il tasto invio su alcune caselle di input
    - il cambiamento del valore selezionato di una combo box
    Menù item/pulsanti si gestiscono con ActionListener. L'invio su un JTextField idem con ActionListener. Per JComboBox ci sono ItemListener ("un elemento ha cambiato stato" ma si usa di rado) o ActionListener ("è stato selezionato un elemento").
    Quindi in sostanza tutti si possono gestire con ActionListener. Pertanto che tu ne abbia N, una implementazione per ciascun caso o uno unico distinguendo il source .... per Swing è indifferente. Sono solo questioni di "design" delle classi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    capito!

    allora direi che lo stato è lo stesso.
    anche perchè gli elementi sono tutti nello stesso JFrame e quindi le variabili d'istanza sono le stesse (se ho capito bene).

    a questo seguo il tuo esempio e poi posto il codice!

    intanto grazie per le ottime info!!

  6. #6
    allora, seguendo il tuo consiglio ho fatto così:
    codice:
            itemSaveTxt.addActionListener(cal);
            itemSaveXls.addActionListener(cal);
            itemPrint.addActionListener(cal);
            itemAbout.addActionListener(cal);
            itemSavePdf.addActionListener(cal);
            itemAuthorsChart.addActionListener(cal);
            itemEditorsChart.addActionListener(cal);
            itemSaveXml.addActionListener(cal);
            itemEsc.addActionListener(cal);
    
            // EVENTI BUTTON
            btnConnect.addActionListener(cal);
    ..................
    
        private class CustomActionListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent ev) {
                Object source = ev.getSource();
                try {
                    if (source == itemAbout) {
                        FormAbout about = new FormAbout();
                        about.setVisible(true);
                    } else if (source == itemPrint) {
                        tableData.print(JTable.PrintMode.FIT_WIDTH);
                    } else if (source == itemSaveTxt) {
                        FileChooser fc = new FileChooser();
                        fc.salvaTxt(tableData);
                    } else if (source == itemSaveXls) {
                        FileChooser fc = new FileChooser();
                        fc.salvaXls(tableData);
                    } else if (source == itemSavePdf) {
                        FileChooser fc = new FileChooser();
                        fc.salvaPdf(jsonRead.getAllBooks());
                    } else if (source == itemAuthorsChart) {
                        FormGraph fg = new FormGraph(UrlAndPath.GRAPH_AUTHORS);
                        fg.setVisible(true);
                    } else if (source == itemEditorsChart) {
                        FormGraph fg = new FormGraph(UrlAndPath.GRAPH_EDITORS);
                        fg.setVisible(true);
                    } else if (source == itemSaveXml) {
                        FileChooser fc = new FileChooser();
                        fc.salvaXml(tableData);
                    } else if (source == itemEsc) {
                        close();
                    } else if (source == btnConnect) {
                        createConnection();
                    }
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } catch (WriteException | PrinterException | DocumentException | JAXBException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }
            }
    
        }
    (e ancora ne devo aggiungere).
    potrebbe andare?

    ho pensato anche di "accorpare" la gestione delle eccezioni qui (visto che parecchi metodi ne lanciano di simili).
    potrebbe andare questo approccio o è sbagliato??

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    allora, seguendo il tuo consiglio ho fatto così:
    (e ancora ne devo aggiungere).
    potrebbe andare?
    In linea di massima sì, cerca però di tenere il actionPerformed il più breve possibile. Per ogni singola azione, invece di gestirla lì direttamente nella catena di if, magari invoca un metodo privato della classe contenitore (come nel mio esempio) in modo che nel actionPerformed ci sia meno logica possibile.

    Quote Originariamente inviata da fermat Visualizza il messaggio
    ho pensato anche di "accorpare" la gestione delle eccezioni qui (visto che parecchi metodi ne lanciano di simili).
    potrebbe andare questo approccio o è sbagliato??
    Sì più o meno ... però così può risultare poco chiaro. Ad esempio quali di quei metodi invocati possono lanciare JAXBException? Io sapendo cosa è e solo vedendo cosa fai potrei provare ad indovinare.
    Potresti anche valutare di creare eccezioni custom di più alto livello in modo da "appiattire" le differenze tra certe gestioni simili ma qui entriamo nel solito argomento di "design" generale delle classi e della applicazione.


    P.S. Cosa è/fa FileChooser? Ho la "impressione" che faccia un po' troppe cose ....
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    ok, ti rispondo per punti.

    per quanto riguarda la gestione delle azioni, ok.
    adesso raggruppo in metodi privati come nel tuo esempio.

    per quanto riguarda le eccezioni, potre anche farle gestire ai metodi privati direttamente, invece che nell'actionPerformed.
    poi magari, messo a posto il resto, sistemo anche la gestione delle eccezioni con una customizzata.

    per quanto riguarda il FileChooser:
    codice:
    public class FileChooser {
    
        private static File f = null;
    
        public void salvaPdf(ArrayList<ArrayList<String>> map) throws FileNotFoundException, DocumentException {
            JFileChooser fc = new JFileChooser();
            fc.setDialogTitle("Save PDF");
            fc.setApproveButtonText("Save");
            fc.setApproveButtonToolTipText("Approve file");
    
            FileFilter pdfFilter = new GenericFileFilter("File *.pdf", "pdf");
            //fc.addChoosableFileFilter(pdfFilter);
            fc.setFileFilter(pdfFilter);
    
            int returnVal = fc.showSaveDialog(fc);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                f = fc.getSelectedFile();
                FileFilter selectedFilter = fc.getFileFilter();
                if (f.getName().indexOf('.') == -1) {
                    if (selectedFilter == pdfFilter) {
                        f = new File(f.getPath() + ".pdf");
                    } else {
                        f = new File(f.getPath() + ".pdf");
                    }
                }
                if (f.exists()) {
                    String msg = MessageFormat.format("The entry ''{0}'' already exists.\nDo you want to replace it?", new Object[]{f});
                    int r = JOptionPane.showConfirmDialog(null, msg, "Confirm", JOptionPane.YES_NO_OPTION);
                    if (r == JOptionPane.NO_OPTION) {
                        return;
                    }
                }
                ExportPdf pdf = new ExportPdf();
                pdf.createPdf(map, f.toString());
            }
        }
    
        public void salvaXls(JTable table) throws IOException, WriteException {
            JFileChooser fc = new JFileChooser();
            fc.setDialogTitle("Save XLS");
            fc.setApproveButtonText("Save");
            fc.setApproveButtonToolTipText("Approve file");
    
            FileFilter xlsFilter = new GenericFileFilter("File *.xls", "xls");
            fc.setFileFilter(xlsFilter);
    
            int returnVal = fc.showSaveDialog(fc);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                f = fc.getSelectedFile();
                FileFilter selectedFilter = fc.getFileFilter();
                if (f.getName().indexOf('.') == -1) {
                    if (selectedFilter == xlsFilter) {
                        f = new File(f.getPath() + ".xls");
                    } else {
                        f = new File(f.getPath() + ".xls");
                    }
                }
                if (f.exists()) {
                    String msg = MessageFormat.format("The entry ''{0}'' already exists.\nDo you want to replace it?", new Object[]{f});
                    int r = JOptionPane.showConfirmDialog(null, msg, "Confirm", JOptionPane.YES_NO_OPTION);
                    if (r == JOptionPane.NO_OPTION) {
                        return;
                    }
                }
                ExportXls test = new ExportXls();
                test.create(table, f.toString());
            }
        }
    
        public void salvaTxt(JTable table) throws IOException, WriteException {
            JFileChooser fc = new JFileChooser();
            fc.setDialogTitle("Save TXT");
            fc.setApproveButtonText("Save");
            fc.setApproveButtonToolTipText("Approve file");
    
            FileFilter txtFilter = new GenericFileFilter("File *.txt", "txt");
            //fc.addChoosableFileFilter(txtFilter);
            fc.setFileFilter(txtFilter);
    
            int returnVal = fc.showSaveDialog(fc);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                f = fc.getSelectedFile();
                FileFilter selectedFilter = fc.getFileFilter();
                if (f.getName().indexOf('.') == -1) {
                    if (selectedFilter == txtFilter) {
                        f = new File(f.getPath() + ".txt");
                    } else {
                        f = new File(f.getPath() + ".txt");
                    }
                }
                if (f.exists()) {
                    String msg = MessageFormat.format("The entry ''{0}'' already exists.\nDo you want to replace it?", new Object[]{f});
                    int r = JOptionPane.showConfirmDialog(null, msg, "Confirm", JOptionPane.YES_NO_OPTION);
                    if (r == JOptionPane.NO_OPTION) {
                        return;
                    }
                }
                ExportTxt txt = new ExportTxt();
                txt.salva(table, f);
            }
        }
    
        public void salvaXml(JTable table) throws JAXBException {
            JFileChooser fc = new JFileChooser();
            fc.setDialogTitle("Save XML");
            fc.setApproveButtonText("Save");
            fc.setApproveButtonToolTipText("Approve file");
            FileFilter xlsFilter = new GenericFileFilter("File *.xml", "xml");
            fc.setFileFilter(xlsFilter);
            int returnVal = fc.showSaveDialog(fc);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                f = fc.getSelectedFile();
                FileFilter selectedFilter = fc.getFileFilter();
                if (f.getName().indexOf('.') == -1) {
                    if (selectedFilter == xlsFilter) {
                        f = new File(f.getPath() + ".xml");
                    } else {
                        f = new File(f.getPath() + ".xml");
                    }
                }
                if (f.exists()) {
                    String msg = MessageFormat.format("The entry ''{0}'' already exists.\nDo you want to replace it?", new Object[]{f});
                    int r = JOptionPane.showConfirmDialog(null, msg, "Confirm", JOptionPane.YES_NO_OPTION);
                    if (r == JOptionPane.NO_OPTION) {
                        return;
                    }
                }
                ExportXml ex = new ExportXml();
                ex.createXml(table, f);
            }
        }
    }
    sicuramente lo devo mettere a posto.
    il problema è che all'epoca avevo fretta e non ne uscivo fuori!

  9. #9
    a parte il FileChooser (che è un discorso a parte), ho fatto così:
    codice:
            // EVENTI MENU
            itemSaveTxt.addActionListener(cal);
            itemSaveXls.addActionListener(cal);
            itemPrint.addActionListener(cal);
            itemAbout.addActionListener(cal);
            itemSavePdf.addActionListener(cal);
            itemAuthorsChart.addActionListener(cal);
            itemEditorsChart.addActionListener(cal);
            itemSaveXml.addActionListener(cal);
            itemEsc.addActionListener(cal);
    
            // EVENTI BUTTON
            btnConnect.addActionListener(cal);
            btnModify.addActionListener(cal);
            btnDelete.addActionListener(cal);
            btnAddBook.addActionListener(cal);
            btnAddAuthor.addActionListener(cal);
            btnUpAuthor.addActionListener(cal);
            btnDelAuthor.addActionListener(cal);
            btnAddEditor.addActionListener(cal);
            btnUpEditor.addActionListener(cal);
            btnDeleteEditor.addActionListener(cal);
    
        private class CustomActionListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent ev) {
                Object source = ev.getSource();
                if (source == itemAbout) {
                    formAbout();
                } else if (source == itemPrint) {
                    printTable();
                } else if (source == itemSaveTxt) {
                    fileChooser("txt");
                } else if (source == itemSaveXls) {
                    fileChooser("xls");
                } else if (source == itemSavePdf) {
                    fileChooser("pdf");
                } else if (source == itemAuthorsChart) {
                    formGraph(UrlAndPath.GRAPH_AUTHORS);
                } else if (source == itemEditorsChart) {
                    formGraph(UrlAndPath.GRAPH_EDITORS);
                } else if (source == itemSaveXml) {
                    fileChooser("xml");
                } else if (source == itemEsc) {
                    close();
                } else if (source == btnConnect) {
                    createConnection();
                } else if (source == btnModify) {
                    getTableData();
                    tableData.requestFocus();
                } else if (source == btnDelete) {
                    deleteBook();
                    tableData.requestFocus();
                } else if (source == btnAddBook) {
                    addBook();
                } else if (source == btnAddAuthor || source == txtAddAuthor) {
                    addAuthor();
                } else if (source == btnUpAuthor || source == txtUpAuthor) {
                    upAuthor();
                } else if (source == btnDelAuthor) {
                    deleteAuthor();
                } else if (source == btnAddEditor || source == txtAddEditor) {
                    addEditor();
                } else if (source == btnUpEditor || source == txtUpEditor) {
                    upEditor();
                } else if (source == btnDeleteEditor) {
                    deleteEditor();
                }
            }
        }
    ogni if richiama un metodo.
    dentro al metodo gestisco eventuali eccezioni (poi magari sistemerò meglio anche quelle, ma anche qui è un discorso a parte).
    mi sembra funzioni tutto.

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    ogni if richiama un metodo.
    dentro al metodo gestisco eventuali eccezioni (poi magari sistemerò meglio anche quelle, ma anche qui è un discorso a parte).
    mi sembra funzioni tutto.
    Va bene, è ok/accettabile.
    Ma devo confermare la mia impressione iniziale .... FileChooser fa "troppe" cose. Tra l'altro ognuno dei metodi salvaXYZ ha la doppia funzionalità di selezione grafica del file e di invocazione della esportazione (sebbene la logica di esportazione, fortunatamente non sia lì nei salva). E comunque ci sono evidentissime ripetizioni di logica che "non cambia" da un salva all'altro.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.