Bonjour,
J'utilise une image de fond pour une JFrame en la mettant dans un JLabel. Est-il possible d'une manière quelconque de faire glisser l'image vers le haut (de manière fluide) au clic sur l'image ?
Bonjour,
J'utilise une image de fond pour une JFrame en la mettant dans un JLabel. Est-il possible d'une manière quelconque de faire glisser l'image vers le haut (de manière fluide) au clic sur l'image ?
Salut,
Dans le principe, oui. Mais ce serait plus simple d'utiliser un JPanel, dans lequel tu dessines l'image, par drawImage, soit en faisant varier son ordonnée, soit en utilisant une translation, parce que si tu utilises un JLabel, il va falloir déplacer le JLabel, donc supprimer le layout manager de son Container, et ce n'est jamais une bonne idée de se passer de layout manager. Pour la fluidité, la classe JPanel offre une fonctionnalité de double buffering simple à activer (méthode setDoubleBuffered). Pour gérer l'animation, utilise un thread, qui fait varier la coordonnée, ou la valeur de la translation.
Un exemple de principe :
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 public class ImageScrollDemo extends JPanel { private final BufferedImage image; private int translationY; private volatile AnimationThread animationThread; /** * @throws IOException * */ public ImageScrollDemo(File imageFile) throws IOException { setDoubleBuffered(true); // évite le flickering image = ImageIO.read(imageFile); translationY = 0; } @Override public void paint(Graphics g) { super.paint(g); // l'image est afficher sur la totalité du panel, sans se préoccuper de // la déformation due à la taille du panel par rapport à la taille de // l'image g.drawImage(image, 0, translationY, getWidth(), getHeight(), this); } public boolean isAnimated() { return animationThread != null; } public void startAnimation(int speedInc) { if (animationThread == null) { animationThread = new AnimationThread(speedInc); animationThread.start(); } } public void stopAnimation() { if (animationThread != null) { animationThread.stopRunning(); } } private class AnimationThread extends Thread { private volatile boolean running; // permet de jouer/arrêter l'animation private int speedInc; /** * * @param speedInc * vitesse de translation (incrément de déplacement) */ public AnimationThread(int speedInc) { this.speedInc = speedInc; } @Override public void run() { running = true; while (running) { translationY -= speedInc; // on vait varier l'ordonnée de // l'incrément repaint(); // on informe SWING qu'on veut que l'affichage du // panel soit rafraichi if (translationY <= -getHeight()) { // on arrête l'animation quand l'image n'est plus visible // dans le panel running = false; } else { // on met en pause le thread try { Thread.sleep(33); // (33ms pour 30 images par seconde) } catch (InterruptedException e) { running = false; } } } // on arrête l'animation, // 1) on remet à zéro la position de l'image translationY = 0; // 2) pour permettre de relancer l'animation animationThread = null; // pour rafraichir l'affichage repaint(); } public void stopRunning() { interrupt(); // permet de terminer l'animation même lorsqu'elle est // en pause running = false; } } public static void main(String[] args) { try { runDemo(); } catch (IOException e) { e.printStackTrace(); } } public static void runDemo() throws IOException { JFrame frame = new JFrame("Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); File imageFile = new File( "C:/Documents and Settings/Joël/Mes documents/Mes images/avatar/suricate.carre.jpg"); final ImageScrollDemo demo = new ImageScrollDemo(imageFile); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(demo, BorderLayout.CENTER); final JSlider speedSlider = new JSlider(1, 17, 9); panel.add(speedSlider, BorderLayout.SOUTH); frame.getContentPane().add(panel); demo.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (demo.isAnimated()) { demo.stopAnimation(); } else { demo.startAnimation(speedSlider.getValue()); } } }); frame.setSize(300, 300); frame.setVisible(true); } }
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.
Moi qui m'attendais à une solution assez simple lol. En tout cas merci je vais me pencher là-dessus, l'exemple me sera très utile je pense.
EDIT : ton exemple est-il sensé être fonctionnel ? Car j'ai beaucoup d'erreurs.Par exemple le repaint() non défini pour le type ImageScrollDemo.AnimationThread
Tout dépend ce que tu appelles simple. Personnellement, je ne vois pas ce qu'il y a de compliqué la dedans : un redéfinition de méthode, un Thread avec une boucle super simple, et quelques composants dans une frame, avec un BorderLayout, rien que du classique. C'est sûr que si tu t'attendais à appeler une méthode scrollToUp(), il y'a un peu plus de code.
Mon code fonctionne très bien, tant qu'il n'est pas modifié. Il n'y a qu'une seule classe, qui va dans un fichier ImageScrollDemo.java : j'ai même pas mis de package en plus. La méthode repaint() appelée dans la méthode run() du thread est une méthode de JPanel (AnimationThread est une classe interne de ImageScrollDemo) : donc, oui, elle existe bien et c'est une méthode standard des composants SWING.
EDIT : Je n'ai mis aucun import, parce qu'aucun d'eux ne portait d’ambiguïté, et que les mettre chargeait inutilement le post. Tu les a bien ajoutés ?
Au cas ou :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider;
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.
Oulà autant pour moi, en adaptant ton code j'ai oublié le extends JPanel ce qui explique tout. *je suis un boulet*
Pour ce qui est de la simplicité, oui je m'attendais a une dizaine de lignes de code mais bon j'ai peut-être jugé trop vite. En même temps je ne suis pas trop familiarisé avec les threads.
En tout cas merci pour ton coup de main.
EDIT : En fait du coup j'ai un problème, ce que je comptais faire c'était mettre une image "par dessus" un formulaire et que lors du clic l'image monte en dévoilant le formulaire mais j'ai beau mettre ce que je veux dessous, lorsque l'image monte la fenetre ou le panel dessous est vierge (meme plus la couleur de background).
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.
Je tentes le coup avec le GlassPane mais j'ai quelques soucis :
Voilà mon code pour la fenetre mais lorsque je le lance, j'ai l'image en tout petit au centre de la fenetre. Si j'enleve le panel "pan" là aucun soucis donc je suppose un problème entre GridBagLayout et le GlassPane.
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 /** Repertoire de l'image */ private static final String IMAGE = "accueil.jpg"; /** Image de fond */ private ImageScroll image; private final JPanel glass; /** Element de test */ private final JPanel pan = new JPanel(); private final JButton b = new JButton("test"); /** Dimensions de la fenêtre */ private static final int HAUTEURF = 578; private static final int LARGEURF = 1024; /** Nombre de composants */ private final int NBCOMPO = 2; /** Abscisse du coin supérieur gauche des composants */ private static final int[] X = {0, 0}; /** Ordonnées du coin supérieur gauche des composants */ private static final int[] Y = {0, 0}; /** Largeur des composants */ private static final int[] LARGEURC = {LARGEURF, LARGEURF/2}; /** Hauteur des composants */ private static final int[] HAUTEURC = {HAUTEURF, HAUTEURF/3}; /** Poids des compoosants sur l'axe des abscisses */ private static final int[] POIDSX = {1, 0}; /** Poids des composants sur l'axe des ordonnées */ private static final int[] POIDSY = {1, 0}; /** Mode de remplissage du composant dans la fenêtre */ private static final int[] REMPLIR = {GridBagConstraints.BOTH, GridBagConstraints.HORIZONTAL}; /** Points d'ancrages des composants dans la cellule */ private static final int[] ANCRAGE = {GridBagConstraints.FIRST_LINE_START, GridBagConstraints.FIRST_LINE_START}; /** Marge au-dessus des composants */ private static final int[] MARGEH = {0, 0}; /** Marge à gauche des composants */ private static final int[] MARGEG = {0, 0}; /** Marge en dessous des composants */ private static final int[] MARGEB = {0, 0}; /** Marge à droite des composants */ private static final int[] MARGED = {0, 0}; /** * Constructeur de la fenêtre */ public Fenetre_principale() { setTitle(TITRE); setSize(LARGEURF, HAUTEURF); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // On centre la fenêtre dans l'écran setResizable(false); getContentPane().setLayout(new GridBagLayout()); // Layout de la JFrame /* * GlassPane contenant l'image d'accueil * L'image slide vers le haut lors du clic sur la JFrame */ glass = (JPanel) this.getGlassPane(); glass.setLayout(new BorderLayout()); // On ajoute l'image try { image = new ImageScroll(new File(IMAGE)); glass.add(image, BorderLayout.CENTER); glass.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if(!image.isAnimated()) image.startAnimation(10); } }); } catch (IOException e) { e.printStackTrace(); } glass.setVisible(true); /* Tableau contenant tous les composants */ pan.setLayout(new BorderLayout()); pan.add(b, BorderLayout.NORTH); pan.setVisible(true); JComponent[] composants = {glass, pan}; /* Contrainte des composants */ GridBagConstraints contrainte = new GridBagConstraints(); /* Ajout des composants */ for(int i = 0; i < NBCOMPO-1; i++){ // On prépare la contrainte de l'image contrainte.gridx = X[i]; // Position sur l'axe des abscisses contrainte.gridy = Y[i]; // Position sur l'axe des ordonnées contrainte.gridwidth = LARGEURC[i]; // Largeur contrainte.gridheight = HAUTEURC[i]; // Hauteur contrainte.weightx = POIDSX[i]; // Poids sur l'axe des abscisses contrainte.weighty = POIDSY[i]; // Poids sur l'axe des ordonnées contrainte.fill = REMPLIR[i]; // Remplissage de la zone contrainte.insets = // Marge autour du composant new Insets(MARGEH[i], MARGEG[i], MARGEB[i], MARGED[i]); contrainte.anchor = ANCRAGE[i]; // Point d'ancrage } // On ajoute le composant getContentPane().add(composants[i], contrainte); setVisible(true); } @Override public void actionPerformed(ActionEvent e) { } public static void main(String[] args){ new Fenetre_principale(); }
Autre chose : J'ai fais un test en mettant juste le glass (contenant l'image) et un bouton directement sur le getContentPane de la JFrame et j'ai 2 pb :
- Le bouton s'affiche par-dessus l'image alors que le GlassPane est censé etre au 1er plan (je penses qu'en utilisant d'autres panels pour les boutons ca devrait plus le faire, a confirmer)
- Le bouton disparait toujours lorsque je lance l'animation.
Salut,
Le problème principal est que tu ajoutes le Glass Pane dans le Content Pane. Comme un composant Swing ne peut avoir qu'un seul parent (n'être qu'à un seul endroit), le fait de mettre le Glass Pane dans le Content Pane fait que ce n'est plus un Glass Pane, mais un simple composant. Le Glass Pane et le Content Pane doivent rester des composants indépendants, qui sont gérés comme des layers : le Glass Pane devant le Content Pane, au sein de la JFrame.
Ensuite, je suppose que le bouton disparaît parce que l'animation fait un repaint() sur le Glass Pane, et non le Content Pane : le redessin du Glass Pane étant fait là où est le bouton, ça l'efface, et rien n'est fait pour redessiner le bouton.
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.
Ok je croyais que le GlassPane était un panel avec certaines propriétés spéciales. Bon du coup j'ai juste enlevé le "glass" du tableau de composant et j'ai bien mon image en grand.
Alors là par contre j'ai essayé de mettre un getContentPane().repaint() mais ça ne marche toujours pas.Ensuite, je suppose que le bouton disparaît parce que l'animation fait un repaint() sur le Glass Pane, et non le Content Pane : le redessin du Glass Pane étant fait là où est le bouton, ça l'efface, et rien n'est fait pour redessiner le bouton.
EDIT : Meme en remplaçant getContentPane().repaint par b.repaint() cela ne fait rien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 glass.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if(!image.isAnimated()) image.startAnimation(10); getContentPane().repaint(); } });
REEDIT : Ok bon j'ai quasiment fini la chose (il fallait que je mette un image.setOpaque(false) pour voir le "dessous" pendant l'animation.
Il me reste un dernier détail. Lorsque l'animation est finie, je doit mettre le glass.setVisible(false) pour pouvoir cliquer sur les éléments du dessous
Mais si je met ça :
Le setVisible passe avant la fin du thread d'animation. Comment faire pour attendre la fin du thread ? J'ai essayé de mettre une boucle while(image.isAnimated()){ } entre les 2 mais bonjour les dégâts ^^
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 image = new ImageScroll(new File(IMAGE)); image.setOpaque(false); glass.add(image, BorderLayout.CENTER); glass.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if(!image.isAnimated()) image.startAnimation(10); glass.setVisible(false); } });
C'est normal que ton appel de glass.setVisible(false) soit appelé avant la fin du thread d'animation : c'est le principe, le thread d'animation s'exécutant en parallèle du thread courant (le thread SWING en fait), donc glass.setVisible(false) est exécuté en parallèle du thread d'animation.
Il y a plusieurs façons d'aborder une manière d'exécuter du code lorsque l'animation est terminée. Une solution pourrait être de mettre en place un système évènementiel, avec un évènement soulevé à la fin de l'animation. Peut être un peu lourd à implémenter dans ton cas, mais ce serait la solution la plus générique (C'est ce qui existe dans les Job Eclipse, par exemple, et c'est vraiment utile, mais ça n'existe pas en standard dans les threads java). Un autre manière serait de permettre de passer un Runnable en paramètre de la méthode startAnimation, et d'exécuter la méthode run() de ce runnable à la fin du thread (à la fin de la méthode run() du thread), en appelant startAnimation(10, new Runnable(){public void run() { glasspane.setVisible(false);}});. Un autre moyen serait un peu moins générique, mais serait assez simple, puisque j'imagine que le composant ImageScroll n'est utilisé que dans ce cas unique : tu peux faire simplement à la fin de la méthode run() du thread, ImageScroll.this.setVisible(false), puisque la classe de thread est une classe interne de ImageScroll et que ImageScroll est le seul composant dans le glasspane. Tu peux même récupérer le GlassPane, par la méthode getWindowAncestor() de SwingUtilities, et en appelant getClassPane(). Il y'en a d'autres (je pense par exemple à une solution à base de SwingWorker).
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.
Alors je vais répondre pour chaque proposition que tu m'as faites parce qu'il y en a beaucoup ^^:
- Pour le système événementiel, ce serais effectivement la meilleure chose à faire (du moins la plus logique) mais je me débrouille pour exploiter des événements déjà existants, je ne sais nullement en créer.
- Pour le Runnable en paramètre, je vais être clair, j'ai rien compris
EDIT : Si j'ai finalement compris, en gros on rajoute un thread pour rendre le glassPane invisible à la fin du thread qui effectue le mouvement. Bizarre comme logique du coup lol. Heureusement que je ne dois pas imbriquer 20 000 threads. Bon l'avantage je te l'accordes c'est qu'on garde l'animation "intacte" et on peut donc la réutiliser mais moi ici je vais l'utiliser qu'une fois donc les solutions suivantes seront meilleures.
- Pour le ImageScroll.this.setVisible(false) je l'avais déjà testé parce que ça me semblait facile, mais ça ne fonctionne pas, il me faut mettre tout le GlassPane en invisible.
- On en arrive donc à la 4ème solution qui me plait bien (ouf!!!). Mais je n'arrive pas à l'utiliser. J'ai mis ceci à la fin du run() : SwingUtilities.getWindowAncestor(ImageScroll.this).getGlassPane() mais le getWindowAncestor me renvoit la window et non la JFrame donc je ne peut pas utiliser le getGlassPane().
Ce n'est pas plus difficile de créer un système évenementiel que de créer une interface avec une méthode (par exemple IMonListener), d'avoir une variable listeners de type List<IMonListener, de faire 3 méthodes (une pour ajouter des IMonListener dans la listeners, une pour en enlever, et une pour parcourir la liste et appeler la méthode de IMonListener sur chaque listener qu'il y a dedans, et d'appeler cette dernière méthode à la fin du thread (il faudrait éventuellement ajouter des synchronized). Mais, bon, je l'ai dit, c'est un peu beaucoup pour un cas isolé comme le tiens.
Non, pas besoin de créer de nouveau thread. Il suffit d'appeler la méthode run() du runnable dans le thread courant, comme n'importe quelle méthode. Éventuellement, on peut s'assurer qu'elle soit bien exécutée sur l'EDT en faisant SwingUtilities.invokeLater(runnable), pour être plus clean. Mais c'est exactement pareil pour les 2 solutions suivantes... la seule différence, c'est que le code des méthodes suivantes n'est pas mis dans le code du thread d'animation, mais à l'extérieur, lorsqu'on la lance : ceci permettant à celui qui lance l'animation de choisir le code qu'il veut, donc que le thread d'animation n'est pas besoin de savoir comment est structuré la vue dans laquelle il s'éxécute.
Il faut caster effectivement la Window en JFrame (ou en RootPaneContainer) pour pouvoir appeler la méthode getGlassPane() (ce qui pourrait être évité avec la solution 2) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Window window = SwingUtilities.getWindowAncestor(ImageScroll.this); if ( window instanceof RootPaneContainer ) { Component glasspane = ((RootPaneContainer)window).getGlassPane(); glasspane.setVisible(false); }
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.
Merci bien, c'est fonctionnel !!!
Je testerais au passage l'événementiel.
Allez une dernière petite question et je ne t'embêtes plus ^^:
Pourquoi si je fais
ou
Code : Sélectionner tout - Visualiser dans une fenêtre à part (JFrame)SwingUtilities.getWindowAncestor(ImageScroll.this);
cela provoque une erreur de syntaxe alors que si on passe comme toi par une variable, on peut la caster ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part (RootPaneContainer)SwingUtilities.getWindowAncestor(ImageScroll.this);
Parce que normalement le compilateur connais le type de retour de getWindowAncestor() non ?
Je pense que le problème vient des parenthèses et pas de la variable intermédiaire.
Ecrire :
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part (JFrame)SwingUtilities.getWindowAncestor(ImageScroll.this).getGlassPane()
n'est évidemment pas la même chose.
Code : Sélectionner tout - Visualiser dans une fenêtre à part ((JFrame)SwingUtilities.getWindowAncestor(ImageScroll.this)).getGlassPane()
Dans le premier cas, on appel getGlassPane() sur l'instance résultat de l'appel de getWindowAncestor(), qui est du type Window (de classe JFrame peut-être, mais ça le compilateur ne peut pas le savoir, surtout qu'on ne peut en être sûr qu'à l'éxécution), et donc le compilateur n'accepte pas l'appel de la méthode getGlassPane() qui n'existe pas dans Window, et à la fin seulement on caste le résultat (enfin on le casterait si ça compilait).
Dans le second cas, on caste d'abord le résultat de getWindowAncestor(), ce qui donne une instance de JFrame typée en JFrame, sur laquelle donc le compilateur accepte bien qu'on appelle getGlassPane(). Par contre, on peut avoir une ClassCastExcepton si, en fait, ce n'est pas une instance de JFrame, mais un JDialog par exemple.
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.
Allez moi je vais me coucher, je commences à poser des questions totalement débiles.
Merci à toi
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