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

2D Java Discussion :

Optimisation de graphics2D


Sujet :

2D Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Optimisation de graphics2D
    Bonjour tout le monde,

    Je suis nouveau sur le forum et débutant en programmation

    J'ai besoin pour un projet de développer un oscilloscope logiciel pour afficher des signaux traités sur un arduino, les données sont envoyée sur le pc en rs232 à 9600bauds.

    Ça fonctionne plutôt bien, mis a part le fait que j’obtiens une bonne dizaine de seconde de latence a partir de cinq secondes de fonctionnement ce qui rend son utilisation peu pratique.

    J'aurai donc voulu savoir si ma méthode est bonne et si java est adapté à ce genre de contraintes (car le même code compilé sous processing en c++ est beaucoup plus reactif), merci d'avance.

    j'ai simplifié le code au maximum pour simplifier la lecture

    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
     
     
    private void drawWave(){//affiche la courbe
     
            graph.setColor(Color.red);
     
     
            for(int i = 0 ; i<this.getWidth()-1 ; i++2){
     
                graph.drawLine(i, wave[i], i+1 , wave[i+1]);
     
            }
        }
     
     
        @Override
        protected void paintComponent(Graphics g){
     
            graph = (Graphics2D) g;
     
     
            graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
            graph.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
            graph.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
     
            this.drawWave();
     
        }
     
     
     
        public void setWave(int data){//recois les donnees rs232
     
            for(int i=0 ; i<this.getWidth()-1 ; i++){//décale toutes les valeurs
                    wave[i]=wave[i+1];    
            }
     
            wave[this.getWidth()-1]= data;//charge la derniere valeur
     
            this.repaint(); //actualise
        }

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Premièrement, utilise System.arrayCopy() pour faire le décalage de tableau. Essaye déjà comme ça.

    Ensuite, je tenterais de passer par une image (dont les dimensions sont celles du panel), que j'écrirais sur elle-même décalée de 1 pixel, en ne dessinant que la dernière ligne (en effaçant la dernière "colonne" de pixels), plutôt que de redessiner tout à chaque fois. Premièrement, tu n'aurais plus à décaler de tableau (mémoriser uniquement 2 valeurs, la dernière et l'avant-dernière (plus l'avant-avant-dernière si tu veux optimier l'effacement de la dernière colonne de pixels, en n'effaçant que la zone concernée), sauf si tu veux pouvoir redimensionner ta fenêtre à volontée. Deuxièment, rend ton panel non opaque : tu écomiseras l'effacement du fond du panel, qui n'est plus nécessaire, puisqu'on va dessiner l'image en entier à chaque fois et que sa taille est celle du panel.

    En plus, si tu utilises 2 images, en alternant (en dessinant la courbe dans l'une, pendant que c'est l'autre qui est dessinée dans la méthode paintComponent), tu simularas du double buffering, ce qui devrait en plus améliorer la fluidité du scrolling. En plus, tu n'auras pas à te préoccuper des conflits entre le thread de mise à jour de ta courbe et celui de SWING.

    Utilise-tu un JPanel ou un Canvas ? Le JPanel intègre un certain nombre de comportements inutiles pour ton cas et un Canvas pourrait peut-être améliorer encore les performances.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Tout d'abord merci pour ta réponse complète

    Alors j'ai essayé avec System.arrayCopy() mais malheureusement ça n'a pas suffit, du coup j'ai essayé avec une BufferedImage en ne dessinant que la zone a modifier, seulement je me suis un peu perdu en chemin parce que j'avais déjà un graphics2D servant a dessiner la grille (par ailleurs je ne sais pas si elle était redessinée à chaque rafraichissements...). Je dois avouer que le fonctionnement de graphics2D m'échappe un peu (ça devrait se voir dans le code ), du coup je suis un peu bloqué
    Par ailleurs je ne parviens pas à trouver de méthode pour copier le rendu graphique (l'image affiché dans diag), si tu as des conseilles je suis preneur . Merci.

    Voici le code et une idée du rendu que j'avais au début:
    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
     
    public class Screen extends JPanel{
     
        Graphics2D graph;
        Graphics2D diag;
        BufferedImage img, imgCrop;
        int[] wave;
     
        public void init(){   
     
         this.setOpaque(false); //panel non opaque
     
         img=imgCrop= new BufferedImage(this.getWidth(), this.getHeight(), TYPE_USHORT_555_RGB);
     
         diag = (Graphics2D) img.getGraphics();//graphics de la courbe
         diag.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
         diag.setColor(Color.red);
     
         wave = new int[2];
         wave[0]=wave[1]=this.getHeight()/2;
     
        }
     
        private void drawGrid(){//dessine la grille
     
            graph.setColor(Color.black);
            graph.fillRect(0, 0, this.getWidth(), this.getHeight());
     
            for(int i=0 ; i<10 ; i++){//Horizontal
                if(i==5){graph.setColor(Color.white);}else{graph.setColor(Color.GRAY);}
                graph.drawLine(0, i*this.getHeight()/10, this.getWidth(), i*this.getHeight()/10);
            }
     
            for(int i=0 ; i<10 ; i++){//Vertical
                if(i==5){graph.setColor(Color.white);}else{graph.setColor(Color.GRAY);}
                graph.drawLine(i*this.getWidth()/10, 0, i*this.getWidth()/10, this.getHeight());
            }  
     
        }
     
     
        private void drawWave(){//dessine la courbe
     
            //img = copie de l'affichage ??
            imgCrop =  img.getSubimage(1, 0, this.getWidth()-1, this.getHeight());//rogne la partie gauche de l'image d'1 pixel
     
            diag.drawLine(this.getWidth()-2, wave[0], this.getWidth()-1, wave[1]);//dessine la partie droite de l'image
     
            diag.dispose();
            graph.drawImage(imgCrop, -1, 0, null);affiche l'image decalee d'1 pixel
     
        }
     
        @Override
        public void paintComponent(Graphics g){
     
            graph = (Graphics2D) g;
     
            graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
            graph.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
            graph.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
            graph.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
     
            this.drawGrid();
            this.drawWave();
     
        }
     
     
     
        public void setWave(int data){//charge les coordonnees de la courbe dans wave
     
            wave[0]=wave[1];
            wave[1]=(int) ((this.getHeight()/2)-data/zoomY);
     
            this.repaint(); 
        }
     
    }
    Nom : scop.png
Affichages : 451
Taille : 65,9 Ko

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Ah oui, le fait d'avoir une grille en plus complique un tout petit peu, mais pas tant que ça. Déjà, tu peux dessiner ta grille dans une image. Tu ne me l'as pas précisé, mais il semble que tu désires que ta fenêtre soit redimensionnable. Cela complique un tout petit peu : il faudrait recréer l'image à chaque redimensionnement, ce qu'on peut faire sur l'évenement écoutable par ComponentListener, sur le panel/canvas, mais ça va t'obliger de. De la même façon, tu peux gérer les 2 images servant à la courbe. Pour ces 2 images, faire une image transparente (type TYPE_INT_ARGB), que tu pourras ainsi redessiner au dessus de ta grille. Pour dessiner dans une image, il faut faire un createGraphics(), pas un getGraphics(). Pour déplacer l'image, il suffit de redessiner l'image précéddente déclalée. Le dessin d'image est très optimisée en Java2D, car ça utilise les optimisations système et hardware de ton système.

    Il faut par contre, bien pense à créer 2 instances d'image distinctes.

    En gros, le principe, dans ta méthode paint(), tu ne fais que dessiner des images :

    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    g.drawImage( grille ) ;
    g.drawImage( imageCourbeCourante ) ;

    Dans la méthode de dessin de la courbe, qui peut être dans son propre thread (autre que le thread SWING) donc qui ne bloque pas l'UI :

    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    dessin dans imageCourbeTemporaire de imageCourbeCourante décalée de -largeurdeladernierecolonne
    dessin de la dernière colonne avec les dernières données dans imageCourbeTemporaire
     
    imageSwap = imageCourbeCourante;
    imageCourbeCourante = imageCourbeTemporaire;
    imageCourbeTemporaire = imageSwap;
     
    repaint(); // pour mettre à jour l'affichage

    Sinon, tu peux également te reposer sur la classe BufferedStrategy. Il y a un exemple dans la javadoc. Ou procéder un peu comme j'ai fait dans cet exemple.

    Je n'ai pas trop le temps ce soir, mais j'essayerai de mon côté de mettre au point un tel système pour voir si je vois d'autres points particuliers et difficultés à contourner et je te tiens au courant.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Premièrement, utilise System.arrayCopy() pour faire le décalage de tableau. Essaye déjà comme ça.
    Un circular buffer ca n'irait pas bien aussi pour eviter la recopie et le decalage ?
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par wax78 Voir le message
    Un circular buffer ca n'irait pas bien aussi pour eviter la recopie et le decalage ?
    Je n'en ai pas parlé parce que je me doutais que c'était surtout l'aspect rendu qu'il fallait travailler : j'ai essayé de mon côté, et ça ne change pas grand chose (sauf vraiment si on veut pouvoir changer l'échelle (et encore : le temps d'affichage des frames "vides" qu'on a si on ne conserve que les 2 dernières valeurs est faible - surtout pour un signal sinusoïdale, qui nécessite un échantillonnage à forte fréquence - pour un signal carré de faible fréquence, effectivement, ce pourrait avoir son intérêt). Le problème est surtout le rendu graphique : parcourir un buffer circulaire ou pas ne change pas grand chose. Mais c'est sûr, qu'avec un buffer circulaire, on a un temps similaire à celui de la version à 2 int, tout en ayant à dispo l'ensemble des n dernières valeurs (d'un côté on a une affectation pour faire le décalage, de l'autre un incrément plus un self-modulo (%=) , ou un test + affectation, pour faire la rotation - le premier va de toute manière plus vite).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Je crois que j'ai compris les grandes lignes, mais il y a quand même un point qui me pose problème, c'est au moment de rogner l'image pour redessiner dedans, j'utilise getsubimage sauf que les dimensions de la nouvelle image sont forcément inférieures ou égales à la précédente et je ne parviens pas à redimensionner ma bufferedimage.
    Sinon, en utilisant un décalage sur drawimage, celle-ci doit être effacée puis recréée lorsque le décalage atteint la largeur de l'écran.
    En gros je patauge

    Auriez vous un exemple de drawWave avec des BufferedImage svp?

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    J'ai fait différents essais pour voir, et la version qui me semble la plus intéressante combine double buffering (quoique je n'ai pas essayé avec plus de 2), et circular buffer (quoique qu'il faudrait que je fasse encore des tests avec des copies de raster, mais le problème globalement est qu'à cause de la grille en background, en raster, il faut travailler avec un masque, ce qui demande un peu plus de temps à mettre au point).

    La classe de démo final :

    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
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    public class OscilloscopeExemple extends Canvas {
     
    	private static final int BUFFER_SIZE = 1000;
    	private static final Color MAIN_GRID_COLOR = Color.WHITE;
    	private static final Color SECONDARY_GRID_COLOR = Color.GRAY;
    	private static final int HORIZONTAL_GRID_DIVISION_NUMBER = 10;
    	private static final int VERTICAL_GRID_DIVISION_NUMBER = 10;
    	private static final Color SIGNAL_COLOR = Color.RED;
     
    	private FunctionThread thread;
    	private final BackgroundGrid grid;
    	private double[] buffer;
    	private int next;
    	private volatile boolean bufferFilled;
    	private final AtomicLong lastInput;
    	private int lastWidth;
    	private int lastHeight;
    	private BufferStrategy buffereStrategy;
    	private float scalex;
    	private float scaley; 
    	private double adaptedScalex;
    	private final IFuntion function;
    	private int midy; 
    	private final int updateRate;
    	private Timer timer;
     
    	public OscilloscopeExemple(int bufferSize, float scalex, float scaley, IFuntion function) {
    		this(bufferSize, scalex, scaley, function, -1);
    	}
    	/**
             * 
             * @param bufferSize nombre de mesures conservées
             * @param scalex facteur d'échelle x
             * @param scaley facteur d'échelle y
             * @param function function de signal
             * @param fps frame rate (si <0, on dessine en RT, sinon on dessin à intervalle régulier)
             */
    	public OscilloscopeExemple(int bufferSize, float scalex, float scaley, IFuntion function, int fps) {
    		this.function = function;
    		buffer = new double[bufferSize];
    		next = 0;
    		bufferFilled = false;
    		lastInput = new AtomicLong();
    		grid = new BackgroundGrid(MAIN_GRID_COLOR, SECONDARY_GRID_COLOR,
    				HORIZONTAL_GRID_DIVISION_NUMBER, VERTICAL_GRID_DIVISION_NUMBER);
    		lastWidth = lastHeight = -1;
     
    		this.scalex=scalex;
    		this.scaley=scaley;
    		if ( fps<=0 ) {
    			updateRate=-1;
    		}
    		else {
    			updateRate = 1000/fps;
    		}
     
    		setIgnoreRepaint(true); 
    		addComponentListener(new ComponentAdapter() { 
     
    			@Override
    			public void componentResized(ComponentEvent e) {
    				initOrReset();
    			}
    		});
    	}
     
    	private synchronized void initOrReset() {
     
    		final int width = getWidth();
    		final int height = getHeight();
     
    		if (lastWidth != width || lastHeight != height) {
     
    			grid.setSize(width, height);
     
    			midy = height >> 1;  
     
    			adaptedScalex = (scalex * width)/buffer.length;
     
    		}
    	}
     
    	public void setScaleX(float scalex) {
    		this.scalex=scalex;
    		adaptedScalex = (scalex * getWidth())/buffer.length;
    		draw();
    	}
     
    	public void setScaleY(float scaley) {
    		this.scaley=scaley;
    		draw();
    	}
     
    	public synchronized void start() {
    		if (thread == null) {
    			initOrReset();
    			createBufferStrategy(2);
    			buffereStrategy = getBufferStrategy();
    			thread = new FunctionThread();
    			thread.start();
    			if ( updateRate>0 ) {
    				timer = new Timer();
    				timer.scheduleAtFixedRate(new TimerTask() {
     
    					@Override
    					public void run() {
    						draw();
    					}
    				}, updateRate, updateRate);
    			}
    		}
    	}
     
    	public synchronized void stop() {
    		if (thread != null) {
    			thread.stopThread();
    			thread = null;
    			buffereStrategy.dispose();
    			buffereStrategy=null;
    			if ( timer!=null ) {
    				timer.cancel();
    			}
    		}
    	}
     
    	private void draw() {
     
    		if ( buffereStrategy==null ) return;
     
    		Graphics2D grBuffer = (Graphics2D) buffereStrategy.getDrawGraphics();
     
    		grBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     
    		grBuffer.drawImage(grid.getImage(), 0, 0, null);
     
    		synchronized (this) {
    			grBuffer.setColor(SIGNAL_COLOR);
    			if ( bufferFilled ) {
    				double prevx=0;
    				int prevy=0; 
    				for(int i=next; i<buffer.length; i++) {
    					if ( i==0 ) {
    						prevx = 0;
    						prevy = (int)(midy + buffer[i]*scaley);
    					}
    					else {
    						double x = prevx+adaptedScalex;
    						int y = (int)(midy + buffer[i]*scaley);
    						grBuffer.drawLine( (int)prevx, prevy, (int)x, y);
    						prevx = x;
    						prevy = y;
    					}
    				}
    				for(int i=0; i<next; i++) { 
    					double x = prevx+adaptedScalex;
    					int y = (int)(midy + buffer[i]*scaley);
    					grBuffer.drawLine( (int)prevx, prevy, (int)x, y);
    					prevx = x;
    					prevy = y; 
    				}
    			}
    			else {
    				double prevx=0;
    				int prevy=0; 
    				for(int i=0; i<next; i++) {
    					if ( i==0 ) {
    						prevx = 0;
    						prevy = (int)(midy + buffer[i]*scaley);
    					}
    					else {
    						double x = prevx+adaptedScalex;
    						int y = (int)(midy + buffer[i]*scaley);
    						grBuffer.drawLine( (int)prevx, prevy, (int)x, y);
    						prevx = x;
    						prevy = y;
    					}
    				}
    			}
    		}
     
    		grBuffer.dispose();
     
    		buffereStrategy.show();
     
    	}  
     
    	@Override
    	public void paint(Graphics g) {
    		// ne fait rien
    	}
     
    	@Override
    	public void paintAll(Graphics g) {
    		// ne fait rien
    	}
     
    	public void updateFunction(long newValue) {
    		if (lastInput.compareAndSet(lastInput.longValue(), newValue)) {
    			synchronized (this) {
    				buffer[next++] =  this.function.getValue(newValue);
    				if (next == buffer.length) {
    					next = 0;
    					bufferFilled = true;
    				}
    			}
    			if ( timer==null ) draw();
    		}
    	}
     
    	private class FunctionThread extends Thread {
     
    		private volatile boolean running = true;
     
    		@Override
    		public void run() {
    			while (running) {
    				updateFunction(System.currentTimeMillis());
    			}
    		}
     
    		public void stopThread() {
    			running = false;
    		}
     
    	}
     
    	@FunctionalInterface
    	public interface IFuntion {
     
    		double getValue(long t);
     
    	}
     
     
    	// *************************** METHODES DE TEST ***************************
     
    	public static void main(String[] args) {
     
    		SwingUtilities.invokeLater(() -> run());
     
    	}
     
    	public static void run() {
     
    		//System.setProperty("sun.java2d.transaccel", "True");
    		// System.setProperty("sun.java2d.ddforcevram", "True");
     
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		OscilloscopeExemple panel = new OscilloscopeExemple(BUFFER_SIZE, 1, 1, (t)-> Math.sin(t/30d) * 100 );
    		frame.getContentPane().add(panel);
     
    		frame.setSize(300, 300);
    		frame.setLocationRelativeTo(null);
     
    		frame.addWindowListener(new WindowAdapter() {
     
    			@Override
    			public void windowOpened(WindowEvent e) {
    				panel.start();
    			}
     
    			@Override
    			public void windowClosed(WindowEvent e) {
    				panel.stop();
    			}
     
    		});
     
    		frame.setVisible(true);
     
    	}
     
    	// ************************************************************************************
     
    }
    La classe pour la grille, et qui te donnera un exemple de dessin dans une image :

    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
    package net.developpez.oscillo;
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
     
     
    public class BackgroundGrid {
     
    	private final Color mainColor;
    	private final Color secondaryColor;
    	private final int divWidth;
    	private final int divHeight;  
    	private volatile Image image;
     
    	public BackgroundGrid(Color mainColor, Color secondaryColor, int divWidth, int divHeight) { 
    		this.mainColor=mainColor==null?Color.WHITE:mainColor;
    		this.secondaryColor=secondaryColor==null?this.mainColor:secondaryColor;
    		this.divWidth=divWidth-divWidth%2;
    		this.divHeight=divHeight-divHeight%2; 
    	}
     
    	public void setSize(int width, int height) { 
     
    		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    		Graphics2D g = image.createGraphics();
    		try {
    			 final double mx = width/2;
    			 final double my = height/2;
     
    			 final double stepX = width/divWidth;
    			 final double stepY = height/divHeight;
     
    			 g.setColor(secondaryColor);
    			 for(double i=mx-stepX; i>0 ; i-=stepX) {
    				 g.drawLine((int)i, 0, (int)i, height);
    			 }
    			 for(double i=mx+stepX; i<width; i+=stepX) {
    				 g.drawLine((int)i, 0, (int)i, height);
    			 }
    			 for(double i=my-stepY; i>0 ; i-=stepY) {
    				 g.drawLine(0, (int)i, width, (int)i);
    			 }
    			 for(double i=my+stepY; i<height; i+=stepY) {
    				 g.drawLine(0, (int)i, width, (int)i);
    			 }
     
    			 g.setColor(mainColor);
    			 g.drawLine((int)mx, 0, (int)mx, height);
    			 g.drawLine(0, (int)my, width, (int)my);
    		}
    		finally {
    			g.dispose();
    		} 
    		this.image=image;
    	}
     
    	public Image getImage() {
    		return image;
    	} 
     
    }
    EDIT : Nouvelle version corrigée, un peu améliorée, expurgée des parties qui ne marchaient pas très bien dans la précédente version. Tout n'est pas réglé, mais c'est une bonne base. OscilloscopeExemple.java
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Super, merci beaucoup!
    Je vais essayer de décortiquer ça!

Discussions similaires

  1. Optimisation de votre SGBDR et de vos requêtes...
    Par SQLpro dans le forum Langage SQL
    Réponses: 35
    Dernier message: 11/01/2013, 11h49
  2. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 4
    Dernier message: 05/02/2003, 08h54
  3. [VB6] [BDD] Optimisation de l'accès aux données
    Par LadyArwen dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 30/01/2003, 13h27
  4. [langage]Problème de temps de lecture, optimisation
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 08/01/2003, 08h47
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

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