Bonjour,
est il possible de mettre un addKeyListener dans une classe n˚1 et de mettre le KeyPressed dans une autre classe n˚2 via une fonction de cette classe n˚2 ?
Merci.
Bonjour,
est il possible de mettre un addKeyListener dans une classe n˚1 et de mettre le KeyPressed dans une autre classe n˚2 via une fonction de cette classe n˚2 ?
Merci.
Salut,
Si tu parles d'enregistrer un KeyListener sur une instance d'une classe, dont la méthode keyPressed() appelle une méthode d'une autre instance d'une autre classe, oui, il n'y a aucun problème, si les accès et portées le rendent possible, comme dans n'importe quel cas d'appel de méthode sur une instance dans une méthode d'une autre instance.
Exemple, pour classe 1 qui est Exemple, et classe 2 qui est JFrame :
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 public class Exemple extends JPanel { public Exemple(final JFrame frame) { setFocusable(true); addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if ( e.getKeyCode()==KeyEvent.VK_ENTER ) { System.out.println("keypressed enter"); frame.dispose(); } } }); } public static void main(String[] args) { JFrame frame = new JFrame("Exemple"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new Exemple(frame); frame.add(panel); frame.setSize(200, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); } }
Merci pour cette réponse.
Malheureusement, je me suis mal exprimé. En effet, je voulais parler du cas où… je vais plutôt afficher mon code ça sera plus simple.
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 import javax.swing.JLabel; import javax.swing.JPanel; public class Main{ public static void main(String[] args){ Personnage t = new Personnage(10,10); JPanel p = new JPanel(); Fenetre f = new Fenetre(p); JLabel j = new JLabel(); t.afficher(j, p); f.setVisible(true); while(true){ //ici je devrai mettre ma fonction déplacer et pourquoi pas un repaint() } } }
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 import java.awt.Color; import java.awt.event.KeyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.*; @SuppressWarnings("serial") public class Fenetre extends JFrame implements KeyListener{ Fenetre(JPanel p){ WindowListener l = new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }; addWindowListener(l); setSize(300,400); p.setBackground(Color.WHITE); getContentPane().add(p); addKeyListener(this); } }Ce code ne fonctionne pas, en prime du fait que je doive absolument implémenter les méthodes KeyListener ; ce qui me paraît évident, mais ça me gêne un peu (en fait beaucoup)…
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 import java.awt.event.KeyEvent; import java.awt.event.KeyAdapter; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class Personnage extends JFrame{ int x,y; Personnage(int x, int y){ this.x=x; this.y=y; image = new ImageIcon("image.png"); } public void afficher(JLabel j, JPanel p){ j = new JLabel(image); p.add(j); } public void deplacer(){ addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e) { System.out.print("A"); } }); } private ImageIcon image; }
En espérant que j’ai apporté assez de précision pour que mon problème soit clair.
Merci.
C'est normal de devoir implémenter les méthodes d'une interface dans une classe qui l'implémente : c'est le principe. Par contre, il n'est pas nécessaire que la JFrame implémente KeyListener, il est juste nécessaire qu'on enregistre sur composant qui puisse avoir le focus une classe qui implémente KeyListener pour capter les évenements clavier.
Ensuite, on ne fait pas une boucle qui enregistre des listeners : à chaque itération, un nouveau listener va être enregistré. Un seul est nécessaire et suffisant. Le principe, comme pour tout écouteur d'évenement est d'enregistrer un écouteur sur l'instance qui produit les évenements et de mettre dans les méthodes de l'écouteur le code qui doit y réagir.
Pourquoi Personnage est-il une JFrame ? Autant en faire un JLabel, et ne pas utiliser cette structure avec la méthode afficher : au lieu d'appeler personnage.afficher(label, frame), faire simple frame.add(personnage). Attention, pour pouvoir afficher des composants en coordonnées absolues dans un conteneur, il faudra que ce conteneur ait aucun layout manager, ou un layout manage prévu pour faire de l'affichage absolu. Pas besoin de x et y, un JLabel a déjà des coordonnées.
Il existe une alternative au KeyListener qui te permettra d'écouter globalement les évenements du clavier : le KeyEventDistpatcher.
Ou avec mouvement continu :
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 public class Personnage extends JLabel { private final static ImageIcon ICON = new ImageIcon(Personnage.class.getResource("image.png")); public Personnage() { super(ICON); setSize(new Dimension(ICON.getIconWidth(), ICON.getIconHeight())); } public static void main(String[] args) { JFrame frame = new JFrame("Démo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // pas besoin de WindowwListener qui fait System.exit(0) Personnage personnage = new Personnage(); // je créé un personnage JPanel panel =new JPanel(); panel.setLayout(null); // positionnement absolu panel.add(personnage); // j'ajoute le personnage à mon container sans layout manager frame.getContentPane().add(panel); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() { @Override public boolean dispatchKeyEvent(KeyEvent e) { switch( e.getID() ) { case KeyEvent.KEY_PRESSED: switch( e.getKeyCode() ) { case KeyEvent.VK_UP: move(0,-1); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_DOWN: move(0,1); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_LEFT: move(-1,0); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_RIGHT: move(1,0); return false; // pour que la touche ne soit pas traitée par un autre écouteur } } return true; } private void move(int dx, int dy) { Point location = personnage.getLocation(); location.x+=dx*8; location.y+=dy*8; personnage.setLocation(location); personnage.getParent().repaint(); } }); // j'afffiche ma fenêtre frame.setSize(Toolkit.getDefaultToolkit().getScreenSize()); personnage.setLocation((frame.getWidth()-personnage.getWidth())/2,(frame.getHeight()-personnage.getHeight())/2); // ^position au milieu au départ frame.setLocationRelativeTo(null); frame.setVisible(true); } }
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 public class Personnage extends JLabel { private final static ImageIcon ICON = new ImageIcon(Personnage.class.getResource("image.png")); public Personnage() { super(ICON); setSize(new Dimension(ICON.getIconWidth(), ICON.getIconHeight())); } public static void main(String[] args) { JFrame frame = new JFrame("Démo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // pas besoin de WindowwListener qui fait System.exit(0) Personnage personnage = new Personnage(); // je créé un personnage JPanel panel =new JPanel(true); panel.setLayout(null); // positionnement absolu panel.add(personnage); // j'ajoute le personnage à mon container sans layout manager frame.getContentPane().add(panel); class MovementTask implements ActionListener { int dx; int dy; @Override public void actionPerformed(ActionEvent e) { if ( dx!=0 || dy!=0 ) { Point location = personnage.getLocation(); location.x+=dx*8; boolean stopmove=false; if ( location.x<0 ) { stopmove=true; location.x=0; } else if ( location.x>=panel.getWidth()-personnage.getWidth()) { stopmove=true; location.x=panel.getWidth()-personnage.getWidth(); } location.y+=dy*8; if ( location.y<0 ) { stopmove=true; location.y=0; } else if ( location.y>=panel.getHeight()-personnage.getHeight()) { stopmove=true; location.y=panel.getHeight()-personnage.getHeight(); } personnage.setLocation(location); panel.repaint(); if ( stopmove ) { dx=0; dy=0; } } } public void setMoveX(int dx) { this.dx=dx; } public void setMoveY(int dy) { this.dy=dy; } } MovementTask task = new MovementTask(); Timer timer = new Timer(33, task); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() { @Override public boolean dispatchKeyEvent(KeyEvent e) { switch( e.getID() ) { case KeyEvent.KEY_PRESSED: switch( e.getKeyCode() ) { case KeyEvent.VK_UP: task.setMoveY(-1); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_DOWN: task.setMoveY(1); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_LEFT: task.setMoveX(-1); return false; // pour que la touche ne soit pas traitée par un autre écouteur case KeyEvent.VK_RIGHT: task.setMoveX(1); return false; // pour que la touche ne soit pas traitée par un autre écouteur } } return true; } }); // j'afffiche ma fenêtre frame.setSize(Toolkit.getDefaultToolkit().getScreenSize()); personnage.setLocation((frame.getWidth()-personnage.getWidth())/2,(frame.getHeight()-personnage.getHeight())/2); // ^position au milieu au départ frame.setLocationRelativeTo(null); frame.setVisible(true); timer.start(); } }
Merci,
pour ces très bons conseils et explications, je vais essayer de les appliquer.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager