Bonjour, je me suis mis en tête d'apprendre le java et j'ai un peu de mal a saisir les nuances, subtilités et intérêts des canvas, frames et autres JFrames.
Je m'explique :
Je suis en train de regarder comment marche le double buffering; je souhaite à terme faire des petites applis 2D avec des trucs qui bougent.
J'en suis maintenant à essayer d'avoir une gestion de l'affichage bien propre et bien gérée
Donc :
Tiré d'un article du site ([https://java.developpez.com/faq/gui?...ering-hardware), je parviens a faire tourner le petit bidule suivant :
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
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
 
public class GuiDbHard extends Frame{ 
	RenderingThread renderingThread = new RenderingThread();  
	BufferStrategy strategy;  
	Graphics buffer;  
	int x;
	String message = "!";
	public GuiDbHard(){ 
		setSize(600, 400);
		setTitle("GuiDbHard_Frame");
		setVisible( true ); 
		setIgnoreRepaint( true );  
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		addKeyListener(new KeyInputHandler());
		requestFocus();		
		//buffering
		createBufferStrategy( 2 );  
		strategy = getBufferStrategy();  
		buffer = strategy.getDrawGraphics(); 
		renderingThread.start();   
   } 
   public void graphicalRender(){ 
	   buffer.setColor( Color.black ); 
	   buffer.fillRect( 0, 0, this.getWidth(),this.getHeight() ); 
	   buffer.setColor( Color.white); 
	   buffer.drawString( "GuiDbHard_Frame", x, 390); 
	   buffer.drawString( message, 10, 50); 	
	   if(x>this.getWidth()) x = 0; 
	   strategy.show(); 
   } 
   class RenderingThread extends Thread{ 
      public void run(){ 
         x =0;
    	  while( true ){ 
            try { 
               graphicalRender(); 
               sleep( 10 ); 
        	   x++; 
            } catch ( Exception e ) {}  
         } 
      } 
   } 
	private class KeyInputHandler extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
			message = "key " + e.getKeyCode(); 
		}
		public void keyReleased(KeyEvent e) {
			message = "!"; 	
		}		
	}
   public static void main(String[] args){
	   new GuiDbHard();
   }
}
Ça ouvre une fenêtre, fond noir, un texte défile, et ça m'indique le keycode de la touche enfoncée. Tout vas bien.

Sur un tuto d'un autre site (http://www.cokeandcode.com/info/tut2d.html), c'est un canvas qui est utilisé, et non un Frame. et dans ce canvas, il est ajouté JFrame et JPanel
J'ai repris ce code pour qu'il ne fasse rien de plus que le précédent, ça me donne ça :

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
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
 
public class Gui extends Canvas {
	RenderingThread renderingThread = new RenderingThread();  
	BufferStrategy strategy;
	Graphics buffer;  
 
	int x;
 
	JFrame container;
	JPanel panel;
 
	String message = "!";
 
	public Gui() {
		JFrame container = new JFrame("GuiDbHard_canvas");
		JPanel panel = (JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(600,400));
		panel.setLayout(null);
		setBounds(0,0,600,400);
		panel.add(this);
 
		setIgnoreRepaint(true);
		container.pack();
		container.setVisible(true);
 
		container.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		addKeyListener(new KeyInputHandler());
		requestFocus();
 
		//buffering
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		buffer = strategy.getDrawGraphics(); 		
		renderingThread.start(); 
	}
	class RenderingThread extends Thread{ 
		public void run(){ 
			x =0;
			while( true ){ 
				try { 
					graphicalRender(); 
					sleep( 10 ); 
					x++; 
				} catch ( Exception e ) {}  
			} 
		} 
	}
	private void graphicalRender() {
		   buffer.setColor( Color.black ); 
		   buffer.fillRect( 0, 0, this.getWidth(),this.getHeight() ); 
		   buffer.setColor( Color.white); 
		   buffer.drawString( "GuiDbHard_canvas", x, 390); 
		   buffer.drawString(message, 10, 50); 		   
		   if(x>this.getWidth()) x = 0; 
		   strategy.show(); 
	}
	private class KeyInputHandler extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
			message = "key " + e.getKeyCode(); 
		}
		public void keyReleased(KeyEvent e) {
			message = "!"; 	
		}		
	}
	public static void main(String[] args){new Gui();}
 
}
Ça ouvre une fenêtre, fond noir, un texte défile, et ça m'indique le keycode de la touche enfoncée. Pareil qu'avant, tout vas bien. C'était l'idée.

La seule différence visible est qu'avec le canvas, la dimension "utile" ne semble pas être rognée par la zone de titre et les bordures de fenêtre. En tout cas, j'ai demandé dans les deux cas du 600x400, et avec le Frame (version 1), c'est plus petit, je n'ai pas mes 600x400 visibles.(je note peut etre également un pb de vitesse de défilement moins régulier en méthode canvas, mais pas certain, j'investiguerais plus.)

J'ai lu également ici qu'il était souhaitable de ne pas mélanger awt et swing, ce que semble faire la version canvas (la 2), en ajoutant du jframe et du jpanel. Mais ça marche ...
(et pour ensuite mettre des composants swing, c'est peut être pratique, sait on jamais ...)

Ma question est donc la suivante : les deux marchent, super ! Mais quelle version est préférable ?

Et en question subsidiaire : dans la première version, avec Frame, ça marche également nickel si je remplace le Frame par un JFrame. Et la, je pourrais peut être ajouter un Jpanel et/ou divers composants swing ? ou ça vas me poser des pb de double buffering (comme vu également sur le site) ?

Merci beaucoup pour vos lumières .