Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it L'avatar di nether
    Registrato dal
    Dec 2006
    Messaggi
    376

    [GUI swing] esecuzione thread e visualizzazione standard out

    Ciao a tutti,

    cerco di esporvi il mio problema. Io ho una classe java molto semplice scritta per essere eseguita dal prompt dei comandi. L'unico input da parte dell'utente avviene come parametro della riga di comando e l'output sono una serie di righe stampate sullo standard out (System.out.print senza ridefinizione dell'outputstream).

    Ora ho l'esigenza di fornire una sorta di "frontend" che permetta in modo intuitivo l'esecuzione di questa classe. Quindi prendendo spunto da un tutorial sun ho preparato un interfaccia bruttissima e banalissima utilizzando le librerie swing, composta essenzialmente da 2 elementi degni di nota: un JButton (collegato ad un JFileChooser) e una JTextArea.

    Avviando l'interfaccia grafica e cliccando sul pulsante, riesco a scegliere correttamente il File da processare. In seguito alla selezione istanzio un oggetto della mia classe (che si chiama PdfParser), setto il parametro richiesto "parser.setFile(file);" e faccio partire il fatidico "parser.run();".

    Problema n.1: la gui rimane completamente grigia e "bloccata" mentre la classe PdfParser fa il suo lavoro.
    Problema n.2: e' possibile "catturare" tutto cioe' che la classe "PdfParser" stampa sullo standard out e "ridirigerlo" all'interno della textarea presente sulla gui? E, se questo non fosse possibile, avete qualche consiglio su come strutturare la parte di output in modo che sia flessibile? Non voglio pensare che la classe PdfParser debba sapere che esiste una JTextArea nella quale scrivere il suo output...

    Qualsiasi tipo di aiuto anche a livello logico (senza codice) e' apprezzato, purtroppo non ho mai lavorato con l'interfaccia grafica nativa di java.. grazie a chiunque vorra' darmi una mano

    Qui di seguito c'e' un estratto del codice della gui, nel caso possa servire.
    Codice PHP:
    public class Gui extends JPanel implements ActionListener {

        static private final 
    String newline "\n";
        
        private 
    JButton processFileButton;
        private 
    JFileChooser fileChooser;
        private 
    JTextArea log;

    //...

    public void actionPerformed(ActionEvent e) {

            
    //Handle process file button action.
            
    if (e.getSource() == this.processFileButton) {
                
    int returnVal this.fileChooser.showOpenDialog(Gui.this);
                if (
    returnVal == JFileChooser.APPROVE_OPTION) {
                    
    File file this.fileChooser.getSelectedFile();
                    
                    
    //qui dovrebbe partire il thread di elaborazione
                    
    PdfParser parser = new PdfParser();
                    
    parser.setFile(file);
                    
    parser.run();
                    
                    
                    
    this.log.append("Elaborazione file \"" file.getName() + "\" terminata." newline);
                } else {
                    
    this.log.append("Selezione file annullata." newline);
                }
                
    this.log.setCaretPosition(this.log.getDocument().getLength());
            }
        }

    //...



  2. #2
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    906
    1) Per far partire i thread in maniera concorrente si utilizza la chiamata al metodo start e non run (anche se quello che devi sovrascrivere nella classe che estende thread e' il metodo run).

    2) Per la reindirizazione dello standard output si puo' usare il metodo setOut() che prende come parametro un PrintStream. La cosa piu' semplice e' realizzarsi una classe che estende OutputStream, passargli come parametro la JTextArea via costruttore ed implementare il metodo write in modo che scriva sulla JTextArea. Nella classe che mandi in esecuzione istanzi uno stream di questo tipo, lo incapsuli in un PrintStream e lo passi a System.setOut().

    Ti posto un po' di codice d'esempio.
    codice:
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    
    public class GUI extends JFrame implements ActionListener {
        private JButton bottone;
        private JScrollPane scroll;
        private JTextArea log;
        
        public GUI() {
            super("Test");
    
            //Inizializzo i componenti
            bottone = new JButton("Process");
            bottone.addActionListener(this);
            log = new JTextArea();
            log.setEditable(false);
            scroll = new JScrollPane(log);
    
            //Li posiziono nel frame
            this.add(bottone, BorderLayout.NORTH);
            this.add(scroll, BorderLayout.CENTER);
    
            //Setto lo stream di output
            System.setOut(new PrintStream(new TextAreaOutputStream(log)));
    
            //Setto le impostazioni del frame
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            this.setSize(200,100);
            this.setVisible(true);
        }
        
        //Faccio partire un thread in maniera concorrente ad ogni pressione
        public void actionPerformed(ActionEvent e) {
            SimThread t = new SimThread();
            t.start(); //INVECE CHE t.run()
        }
        
        //Classe che scrive uno stream su una JTextArea
        class TextAreaOutputStream extends OutputStream{
            private JTextArea console;
            
            public TextAreaOutputStream(JTextArea console) {
                this.console = console;
            }
            
            public void write(int b) throws IOException {
                char[] c = Character.toChars(b);
                for(char tmp : c)
                    console.append(Character.toString(tmp));
                console.setCaretPosition(console.getDocument().getLength());
            }
        }
        
        //Thread che simula un lavoro(con un'attesa) e poi stampa una stringa
        class SimThread extends Thread {
            public void run(){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                System.out.println("STAMPO IL PARSING");
            }
        }
        
        public static void main(String[] args) {
            new GUI();
        }
    }

  3. #3
    Utente di HTML.it L'avatar di nether
    Registrato dal
    Dec 2006
    Messaggi
    376
    fantastico, grazie mille.. la logica e l'esempio sono chiarissimi

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.