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

AWT/Swing Java Discussion :

afficher une fonction mathématique.


Sujet :

AWT/Swing Java

  1. #1
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut afficher une fonction mathématique.
    Bonjour.

    Je suis en train de faire un programme à qui on donne:
    _ une fonction (par exemple x^2)
    _ une borne min et une borne max
    _ un nombre d'iterations

    (Pas besoin de cocher le bouton radio "valeur", ou aucune des autres checkbox)

    et qui doit afficher la fonction, et une "pluie" de points qui tombent aléatoirement sur le graphe.
    Je souhaiterai obtenir qqch comme ce qu'on trouve ici

    Une fois les données entrées, on clique sur OK. ActionPerformed appelle alors la méthode go() de la classe Fenetre qui à son tour fait une boucle dans laquelle elle appelle la méthode repaint() avec un Thread.sleep(10) entre chaque iteration.

    Le problème qui se pose c'est que la boucle "tourne" plusieurs fois, mais j'ai l'impression que paintComponent() n'est appellée qu'une fois, puisqu'à la fin j'ai bien ma fonction de déssinée, mais un seul point est affiché.

    Voila une partie du code source, en version simplifiée...
    J'ai mis en piece jointe un fichier zip contenant le jar necessaire au parsing de la fonction mathematique.(pour ceux qui auraient le courage ou l'infini bonté de vouloir tester mon code)

    Main.java
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package montecarlo;
     
    /**
     *
     * @author Abdelhamid
     */
    import java.io.*;
    import java.util.*;
    import java.math.*;
    import org.nfunk.jep.*;
     
    public class Main {
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
     
            Fenetre it = new Fenetre();
        }
    }
    graphique1.java
    C'est la classe qui lance le panel pour dessiner la fonction, et UN seul point aux coordonnées aléatoires.
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package montecarlo;
     
    import javax.swing.*;
    import java.util.*;
     
    public class graphique1 extends JPanel {
     
        int X[] = new int[10000];
        int Y[] = new int[10000];
        int min, max;
        Random rand = new Random();
        int randX = 0;
        int randY = 0;
     
        /** Creates new form Graphique */
        public graphique1(Integrale I) {
            min = (int) I.borneMin - 100;
            max = (int) I.borneMax + 100;
            for (int i = min; i < max; i++) {
                X[i - min] = i + 300;
                Y[i - min] = (int) (225 - 0.1 * I.evaluer(i));
            }
            this.setPreferredSize(new java.awt.Dimension(600, 450));
     
        }
     
        @Override
        public void paintComponent(java.awt.Graphics g) {
            g.setColor(new java.awt.Color(255, 255, 255));
            g.fill3DRect(0, 0, 599, 449, true);
            g.setColor(new java.awt.Color(0, 0, 0));
     
            randX = rand.nextInt(100) + -5 + 300;
     
            randY = 225 - rand.nextInt(100);
     
            g.drawLine(randX, randY, randX, randY);
     
            g.drawPolygon(X, Y, max - min);
        }
    }
    Fenetre.java
    C'est la classe qui lance le JFrame. Tout le début n'est que déclarations de JtextField etc...
    La méthode go() tout en bas se charge d'appeller repaint() et Thread.sleep(10) au sein d'une boucle. De cette facon la fonction est (sensée etre) redessinée plusieurs fois, mais c pas grave on ne voit pas de difference. PUIS un seul point aux coordonées aléatoire est (sensé etre) dessiné à chaque iteration.
    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
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package montecarlo;
     
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.event.*;
     
    public class Fenetre {
     
        private JFrame fenetre = new JFrame("PFE MONTE CARLO 2008") {
     
            {
                addWindowListener(new WindowAdapter() {
     
                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                    }
                });
            }
        };
        final int cte = 400;
        private JPanel[] panel;
        private JButton button;
        private JLabel[] label;
        private javax.swing.JTextField[] jText;
        private javax.swing.JRadioButton[] jRadio;
        private javax.swing.JCheckBox[] jCheck;
        //graphique1 graph;
     
        public Fenetre() {
            panel = new JPanel[12];
            for (int i = 0; i < 12; i++) {
                panel[i] = new JPanel();
            }
            label = new JLabel[13];
            jText = new JTextField[5];
            jRadio = new JRadioButton[2];
            jCheck = new JCheckBox[4];
            jText[0] = new JTextField(25);
            jText[1] = new JTextField(8);
            jText[2] = new JTextField(8);
            jText[3] = new JTextField(14);
            jText[4] = new JTextField(14);
            jCheck[0] = new JCheckBox("Monte Carlo  ");
            jCheck[1] = new JCheckBox("Rectangle    ");
            jCheck[2] = new JCheckBox("Trapezes     ");
            jCheck[3] = new JCheckBox("Simpson      ");
            jRadio[0] = new JRadioButton("Iterations");
            jRadio[1] = new JRadioButton("Valeur        ");
            label[0] = new JLabel("f(x)=");
            label[1] = new JLabel("min");
            label[2] = new JLabel("max");
            label[3] = new JLabel(" Complexité");
            label[4] = new JLabel("Resultats");
            label[5] = new JLabel("0.000000");
            label[6] = new JLabel("0.000000");
            label[7] = new JLabel("0.000000");
            label[8] = new JLabel("0.000000");
            label[9] = new JLabel("0.000000");
            label[10] = new JLabel("0.000000");
            label[11] = new JLabel("0.000000");
            label[12] = new JLabel("0.000000");
            jText[3].setPreferredSize(new Dimension(100, 25));
            jText[4].setPreferredSize(new Dimension(100, 25));
            for (int i = 3; i < 13; i++) {
                label[i].setPreferredSize(new Dimension(100, 25));
            }
            button = new JButton("ok");
            button.addActionListener(new ActionListener() {
     
                public void actionPerformed(ActionEvent e) {
                    go();
                }
            });
     
            panel[0].add(label[0]);
            panel[0].add(jText[0]);
            panel[0].add(button);
            panel[0].setPreferredSize(new Dimension(cte, 30));
     
            panel[7].add(label[1]);
            panel[7].add(label[2]);
            panel[7].setPreferredSize(new Dimension(25, 60));
     
            panel[8].add(jText[1]);
            panel[8].add(jText[2]);
            panel[8].setPreferredSize(new Dimension(150, 60));
     
            panel[1].add(panel[7]);
            panel[1].add(panel[8]);
            panel[1].setPreferredSize(new Dimension(cte, 60));
     
            panel[2].add(jRadio[0]);
            panel[2].add(jRadio[1]);
            panel[2].setPreferredSize(new Dimension(80, 60));
     
            panel[3].add(jText[3]);
            panel[3].add(jText[4]);
            panel[3].setPreferredSize(new Dimension(250, 60));
     
            panel[11].add(panel[2]);
            panel[11].add(panel[3]);
            panel[11].setPreferredSize(new Dimension(cte, 80));
     
            panel[6].add(new JPanel() {
     
                {
                    setPreferredSize(new Dimension(100, 25));
     
                }
            });
            panel[6].add(jCheck[0]);
            panel[6].add(jCheck[1]);
            panel[6].add(jCheck[2]);
            panel[6].add(jCheck[3]);
     
            panel[4].add(label[3]);
            panel[4].add(label[5]);
            panel[4].add(label[7]);
            panel[4].add(label[9]);
            panel[4].add(label[11]);
     
     
            panel[5].add(label[4]);
            panel[5].add(label[6]);
            panel[5].add(label[8]);
            panel[5].add(label[10]);
            panel[5].add(label[12]);
     
            panel[4].setPreferredSize(new Dimension(100, 200));
     
            panel[5].setPreferredSize(new Dimension(100, 200));
     
            panel[6].setPreferredSize(new Dimension(100, 200));
     
            panel[9].add(panel[0]);
            panel[9].add(panel[1]);
            panel[9].add(panel[2]);
            panel[9].add(panel[3]);
            panel[9].add(panel[11]);
            panel[9].add(panel[6]);
            panel[9].add(panel[4]);
            panel[9].add(panel[5]);
            panel[9].setPreferredSize(new Dimension(cte, 450));
     
            panel[10].add(panel[9]);
            fenetre.add(panel[10]);
            fenetre.setVisible(true);
            fenetre.pack();
        }
     
        public void go() {
            String fonction = jText[0].getText();
            float min = Float.parseFloat(jText[1].getText());
            float max = Float.parseFloat(jText[2].getText());
     
            int nbOpns = Integer.parseInt(jText[3].getText());
     
            Integrale uneIntegrale = new Integrale(fonction, min, max);
     
     
            graphique1 graph = new graphique1(uneIntegrale);
            panel[10].add(graph);
            fenetre.pack();
            for (int i = 0; i < 1000; i++) {
     
                graph.repaint();
                try {
     
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("awakened prematurely");
     
                }
            }
        }
    }
    Integrale.java
    Cette classe est utile pour "parser" une chaine de caractères par exemple "x^2" en une fonction mathématique evaluable. Ceci grace au jar de jep
    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package montecarlo;
     
    import org.nfunk.jep.*;
     
    /**
     *
     * @author Abdelhamid
     */
    public class Integrale {
     
        org.nfunk.jep.JEP fonction;
        protected int nbOperateurs=0;
     
        protected double borneMin;
        protected double borneMax;
        protected double valeurAttendue;    
     
        public Integrale(String fonc, double min, double max) {
     
            fonction = new JEP();
     
            fonction.addStandardFunctions();
            fonction.addStandardConstants();
            fonction.addVariable("x", 0);
            fonction.parseExpression(fonc);
     
            borneMin = min;
            borneMax = max;
     
            int i = 0;
            while (i != fonc.length()) {
                if (fonc.charAt(i) == '+' || fonc.charAt(i) == '-') {
                    nbOperateurs++;
                } else if (fonc.charAt(i) == '*' || fonc.charAt(i) == '/') {
                    nbOperateurs++;
                } else if (fonc.charAt(i) == '^') {
                    nbOperateurs+=Integer.parseInt(""+fonc.charAt(i+1));
                }
                i++;
            }
        }
     
        public Integrale(String fonc, double min, double max, double val) {
            this(fonc, min, max);
            valeurAttendue = val;
        }
     
        public double evaluer(double val) {
            fonction.addVariable("x", val);
            return fonction.getValue();
        }
     
        public double getMin() {
            return borneMin;
        }
     
        public double getMax() {
            return borneMax;
        }
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Je sais que je devrais ajouter plus de commentaires, mais pour vous simplifier la comprehension, je pense qu'il faut juste regarder Fenetre.go() (tout en bas de la classe Fenetre) et la classe graphique1...

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Ton Thread.sleep et tes calculs ne doivent pas être réalisé dans le thread d'affichage (thread dans lequel tu es par défaut).

    Donc deux solutions:
    • créer un thread responsable du calcul et de la demande de repaint de ton Composant
    • Utiliser un Timer Swing qui se déclenche toutes les n millisecondes, et qui lance le calcul puis demande au composant de se redessiner
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  4. #4
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par sinok Voir le message
    Ton Thread.sleep et tes calculs ne doivent pas être réalisé dans le thread d'affichage (thread dans lequel tu es par défaut).

    Donc deux solutions:
    • créer un thread responsable du calcul et de la demande de repaint de ton Composant
    • Utiliser un Timer Swing qui se déclenche toutes les n millisecondes, et qui lance le calcul puis demande au composant de se redessiner
    Je n'ai pas tres bien compris ce que tu me proposes.

    Ton Thread.sleep et tes calculs ne doivent pas être réalisé dans le thread d'affichage (thread dans lequel tu es par défaut).
    Le thread d'affichage c'est bien paintComponent, non?
    Le Thread.sleep n'est pas dans paintComponent...

    créer un thread responsable du calcul et de la demande de repaint de ton Composant
    C'est ce que je fais deja avec la methode go(), qui demande la méthode repaint.

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par abdelhamidem Voir le message
    Le thread d'affichage c'est bien paintComponent, non?
    Le Thread.sleep n'est pas dans paintComponent...
    La thread d'affichage c'est l'EDT (Event Dispatch Thread) qui sert a la fois a l'affichage et a la gestion des evenements. Donc, generalement, l'integralite du code d'un composant graphique est execute a un moment ou a un autre dans cette Thread. Il ne faut pas faire de sleep() ou de wait() ou de traitements trop longs dedans.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    D'accord, mais ca me semble un peu flou tout ca.
    Il est où l'EDT dans mon cas?

    Dans la classe Fenetre qui fait le JFrame, ou dans graphique1 qui s'occupe juste de dessiner le panel avec ma fonction et mes points?

  7. #7
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    dans ton cas la méthode go est exécutée entièrement dans l'EDT car appelée par un actionPerformed, méthode se déroulant dans l'EDT.
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  8. #8
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    D'accord je comprends un peu mieux.
    Je vais prendre la voie du Timer Swing, pcq les threads je maitrise pas encore beaucoup...
    Timer Swing non plus à vrai dire , mais ca me semble plus simple.

  9. #9
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Merci beaucoup pour votre aide, maintenant ca marche.

    Voila la nouvelle classe graphique1 (que j'ai renommé Graphique à ce propos)

    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package montecarlo;
     
    import javax.swing.*;
    import javax.swing.event.*;
    import java.util.*;
    import java.awt.*;
    import java.awt.event.*;
     
    public class Graphique extends JPanel implements ActionListener {
     
        int X[] = new int[10000];
        int Y[] = new int[10000];
        int min, max;
        Random rand = new Random();
        int randX = 0;
        int randY = 0;
        boolean functionDrawed = false;
        double zoom = 10;
        Integrale integrale;
        javax.swing.Timer t;
     
        public Graphique(Integrale I) {
            integrale = I;
            min = (int) I.borneMin - 100;
            max = (int) I.borneMax + 100;
            for (int i = min; i < max; i++) {
                X[i - min] = (int) zoom * i + 300;
                Y[i - min] = (int) (225 - zoom * I.evaluer(i));
            }
            this.setPreferredSize(new java.awt.Dimension(600, 450));
            repaint();
            t = new javax.swing.Timer(100, this);
            t.start();
        }
     
        @Override
        public void paintComponent(java.awt.Graphics g) {
            if (!functionDrawed) {
                g.setColor(new java.awt.Color(255, 255, 255));
                g.fill3DRect(0, 0, 599, 449, true);
                g.setColor(new java.awt.Color(0, 0, 0));
                g.drawPolygon(X, Y, max - min);
                functionDrawed = true;
            }
            randX = rand.nextInt(100) + -5 + 300;
            randY = 225 - rand.nextInt(100);
            if ((225 - zoom * integrale.evaluer((randX - 300) / zoom)) > randY) {
                g.setColor(new java.awt.Color(255, 0, 0));
            } else {
                g.setColor(new java.awt.Color(0, 0, 255));
            }
            g.drawLine(randX, randY, randX, randY);
        }
     
        public void actionPerformed(ActionEvent e) {
            repaint();
        }
     
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Transcrire une fonction mathématique en code Matlab
    Par casper84 dans le forum MATLAB
    Réponses: 1
    Dernier message: 30/03/2007, 17h04
  2. Tracer ellipse à partir d'une fonction mathématique
    Par juli1_h dans le forum Mathématiques
    Réponses: 2
    Dernier message: 13/03/2007, 09h43
  3. Afficher une fonction avec une autre
    Par renaud26 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 28/08/2006, 14h29
  4. codage du calcul de dérivée d'une fonction mathématique
    Par pispa2005 dans le forum Mathématiques
    Réponses: 5
    Dernier message: 08/01/2005, 20h54
  5. Créer une fonction mathématique pendant l'exécution
    Par zeprogrameur dans le forum Langage
    Réponses: 5
    Dernier message: 09/07/2004, 11h36

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