IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

PrintWriter : affichage "live"


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut PrintWriter : affichage "live"
    Bonjour à tous,


    Je suis en train de coder une petite application basée sur un MVC classique et basique. Mon interface graphique est composée d'un panel gauche contenant un JTree et d'un panel droit de type JTabbedPane contenant lui-même des JTabbedPane.

    Chaque feuille du JTree représente un scénario de test. Chaque test est composé de plusieurs processus. Ainsi, lors de l'exécution d'un scénario, un nouveau JTabbedPane est créé et dans celui-ci, un nouveau JTabbedPane est créé pour chaque nouveau processus démarré.

    Mon problème se situe au niveau de l'affichage des résultats de chaque processus : j'aimerais que celui-ci se fasse à la volée, alors qu'avec mon code actuel, les résultats sont affichés en une fois à la fin du processus.
    C'est assez embêtant car si le processus prend plusieurs minutes, je n'ai aucune idée de son avancement...

    J'ai utilisé la classe PrintWriter (au plus simple) mais j'ai dû passer à côté de quelque chose.

    Voici les différentes classes utilisées (tout du moins, celles qui ont un intérêt à mes yeux) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    public class MyApplicationGUI extends MyApplicationView implements ActionListener {
     
        private JFrame mainFrame = null;
        private JTabbedPane rightPane = null;
        private JTree tree;
        private PrintWriter guiPrintWriter = null;
     
     
        /**
         * 
         * @param controller
         */
        public MyApplicationGUI(MyApplicationController controller){
            super(controller); 
     
            // Setup the frame, panels, menu, etc...
            buildFrame();
        }
     
        ...
     
        /**
         * 
         * @return
         */
        @Override
        public PrintWriter getGuiPrintWriter() {
            return guiPrintWriter;
        }
     
        ...
     
     
        /**
         * New process means new sub-tab to be opened under the corresponding 
         * scenario tab in the right pane.
         * 
         * @param event
         */
        public void processChanged(ProcessChangedEvent event) {
            String currentScenarioName = event.getCurrentScenarioName();
            String newProcessName = event.getNewProcess();
     
            // Retrieve the JTabbedPane of the scenario (should be the one active)
            JTabbedPane scenTabPane = getScenarioTabbedPane(currentScenarioName);
     
            // Close the previous stream if any
            if (guiPrintWriter != null) {
                guiPrintWriter.close();
            }
     
            if (scenTabPane != null) {
                LogPane pane = new LogPane();
                scenTabPane.add(newProcessName, pane.getPanel());
                scenTabPane.setSelectedComponent(pane.getPanel());
                guiPrintWriter = new PrintWriter(pane, true);
            }
        }
     
    	...
     
        private JTabbedPane getScenarioTabbedPane(String scenarioName) {
            return (JTabbedPane) rightPane.getComponentAt(rightPane.indexOfTab(scenarioName));
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public class MyApplicationController {
        public MyApplicationView maGUI = null;
        private MyApplicationModel maModel = null;
     
        ...
     
        public MyApplicationController (MyApplicationModel model) {
            this.maModel = model;
     
            maGUI = new MyApplicationGUI(this);
     
            addListenersToModel();
        }
     
        ...
     
        private void executionMode1(Scenario currentScenario) {
            String scenarioName = currentScenario.getScenarioName();
     
            Collection<ScenarioProcess> scenarioProcesses = currentScenario.getScenarioProcesses();
     
            for (ScenarioProcess currentProcess : scenarioProcesses) {
                String processName = currentProcess.getProcessName();
     
                model.setCurrentProcess(processName);
     
                ScenarioProcessFactory scenarioProcessFactory = ScenarioProcessFactory.newInstance();
                ScenarioProcessInterface scenarioProcess = scenarioProcessFactory.createScenarioProcess(currentProcess.getProcessType());
     
                if (scenarioProcess != null) {
                    if (!scenarioProcess.execute(scenarioName, currentProcess.getScenarioData(), maGUI.getGuiPrintWriter())) {
                        // Put the current sub-tab in red and go on with the next processes
                        maGUI.scenarioProcessFailure(scenarioName, processName);
                    }
                }
            }
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Process1 implements ScenarioProcessInterface {
     
        private PrintWriter process1PrintWriter = null;
     
    	...
     
        public synchronized boolean execute(String scenarioName, Collection<ScenarioData> scenarioData, PrintWriter guiPrintWriter) {
            this.process1PrintWriter = guiPrintWriter;
     
            ...
     
    		process1PrintWriter.println("Start of the execution...");
     
    		...
     
    		process1PrintWriter.println("End of the execution...");
    	}
     
    }

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Ton PrintWriter écrit dans un LogPane. C'est quoi exactement ? On pourrait voir son code ?

    Sinon tes "processus" sont bien exécutés en arrière tâches ?

    a++

  3. #3
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,
    Ton PrintWriter écrit dans un LogPane. C'est quoi exactement ? On pourrait voir son code ?
    Oui, bien sûr ! Pour info, je n'en suis pas l'auteur...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import java.io.IOException;
    import java.io.OutputStream;
     
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.ScrollPaneConstants;
     
     
    public class LogPane extends OutputStream {
        private JTextArea mainTextArea;
        private JPanel mainPanel;
        private StringBuffer sb = new StringBuffer(255);
     
     
        public LogPane() {
            JScrollPane mainScrollingPane;
     
            mainPanel = new JPanel(new java.awt.BorderLayout());
            mainTextArea = new JTextArea();
            mainScrollingPane = new JScrollPane(mainTextArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            mainScrollingPane.setWheelScrollingEnabled(true);
            mainPanel.add(mainScrollingPane, java.awt.BorderLayout.CENTER);
            mainTextArea.setEditable(false);
        }
     
     
        public JPanel getPanel() {
            return mainPanel;
        }
     
     
        public void set(String text) {
            mainTextArea.setText(text);
            mainTextArea.setCaretPosition(mainTextArea.getText().length());
        }
     
     
        public void append(String text) {
            mainTextArea.append(text);
            mainTextArea.setCaretPosition(mainTextArea.getText().length());
        }
     
     
        public void clear() {
            mainTextArea.setText("");
        }
     
     
        public JTextArea getMainTextArea() {
            return mainTextArea;
        }
     
     
        public String getSelection() {
            return mainTextArea.getSelectedText();
        }
     
     
        public void write(int b) throws IOException {
            Integer i = Integer.valueOf(b);
            char c = (char) i.byteValue();
            sb.append(c);
            if (c == '\n' || sb.length() == 255) {
                flush();
            }
        }
     
     
        public void flush() throws IOException {
            append(sb.toString());
            sb = sb.delete(0, sb.length());
        }
     
     
        public void close() throws IOException {
            flush();
        }
     
    }
    Citation Envoyé par adiGuba Voir le message
    Sinon tes "processus" sont bien exécutés en arrière tâches ?

    a++
    Les processus sont liés à des calculs et des manipulations de données dans une base de données. Aucune influence sur l'affichage, donc. Le PrintWriter ne sert vraiment qu'à tenir informé l'utilisateur de l'avancement du processus.

  4. #4
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Le problème ne vient pas de l'utilisation du PrintWriter, parce que le JTabbedPane du scénario lui-même n'est créé qu'à la fin du premier processus !

    Je pense qu'il est dès lors bon de préciser que la méthode executionMode1 du controleur est appelée de la façon suivante, dans le controleur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        public void notifyMyApplicationChanged(ActionEvent evnt) {
            ...
     
            Scenario monScenario = new Scenario(maGUI.getSelectedScenario());
     
            model.setCurrentScenario(monScenario);
     
            executionMode1(monScenario);
        }
    et que le modèle est codé ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    import javax.swing.event.EventListenerList;
     
    public class MyApplicationModel {
        private Scenario currentScenario;
        private EventListenerList listeners;
     
        public MyApplicationModel(){
            super();
     
            this.currentScenario = null;
     
            listeners = new EventListenerList();
        }
     
        public void setCurrentScenario(Scenario theCurrentScenario) {
            currentScenario = theCurrentScenario;
     
            fireCurrentScenarioChanged();
        }
     
        public void fireCurrentScenarioChanged(){
            MyApplicationListener[] listenerList = (MyApplicationListener[])listeners.getListeners(MyApplicationListener.class);
     
            for (MyApplicationListener listener : listenerList){
                listener.currentScenarioChanged(new CurrentScenarioChangedEvent(this, getCurrentScenario().getScenarioName()));
            }
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public class CurrentScenarioChangedEvent extends EventObject {
        private static final long serialVersionUID = 1L;
        private String newCurrentScenarioName;
     
        public CurrentScenarioChangedEvent(Object source, String aNewCurrentScenarioName){
            super(source);
     
            this.newCurrentScenarioName = aNewCurrentScenarioName;
        }
     
        public String getNewCurrentScenarioName(){
            return newCurrentScenarioName;
        }
     
    }
    Bref, lorsqu'un nouveau scénario est exécuté, le controleur notifie le modèle qui lui-même notifie la vue. Cette dernière devrait donc créer un nouveau JTabbedPane AVANT d'appeler executionMode1 ! Mais ce n'est pas le cas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        public void currentScenarioChanged(CurrentScenarioChangedEvent event) {
            String newScenarioName = event.getNewCurrentScenarioName();
     
            int index = rightPane.indexOfTab(newScenarioName);
     
            if (index != -1) {
                closeScenarioTabAtIndex(index);
            }
     
            JTabbedPane newScenPane = new JTabbedPane();
     
            rightPane.add(newScenarioName, newScenPane);
            rightPane.setSelectedComponent(newScenPane);
        }

  5. #5
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Etant donné que le problème se situe plutôt au niveau affichage Swing, est-ce qu'un modérateur pourrait déplacer ce sujet vers la catégorie " Interfaces Graphiques en Java > AWT/SWING " ?

    Merci à lui !

  6. #6
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    J'ai reformulé ma question dans une autre discussion à un endroit plus approprié (EDT/Swing). Je mets donc cette discussion en délestage.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo