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

Agents de placement/Fenêtres Java Discussion :

Défilement image JFrame


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut Défilement image JFrame
    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 ?

  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,

    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.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    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

  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
    Citation Envoyé par Halo2550 Voir le message
    Moi qui m'attendais à une solution assez simple.
    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.

    Citation Envoyé par Halo2550 Voir le message
    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
    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.

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    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).

  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 Halo2550 Voir le message
    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).
    Si le formulaire occupe tout l'espace de la JFrame dans laquelle il est affiché, je m'orienterais vers une solution avec le GlassPane de la fenêtre. Sinon, vers une solution avec la classe JLayer (qui peut également fonctionner dans le premier cas).
    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
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    Je tentes le coup avec le GlassPane mais j'ai quelques soucis :

    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();
    	}
    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.

    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.

  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,

    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.

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    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.
    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.

    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.
    Alors là par contre j'ai essayé de mettre un getContentPane().repaint() mais ça ne marche toujours pas.

    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();
    	}
    });
    EDIT : Meme en remplaçant getContentPane().repaint par b.repaint() cela ne fait rien.

    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 :

    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);
    	}
    });
    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 ^^

  10. #10
    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
    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.

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    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().

  12. #12
    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 Halo2550 Voir le message
    - 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.
    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.

    Citation Envoyé par Halo2550 Voir le message
    - 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.
    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.

    Citation Envoyé par Halo2550 Voir le message
    - 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().
    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.

  13. #13
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (JFrame)SwingUtilities.getWindowAncestor(ImageScroll.this);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (RootPaneContainer)SwingUtilities.getWindowAncestor(ImageScroll.this);
    cela provoque une erreur de syntaxe alors que si on passe comme toi par une variable, on peut la caster ?

    Parce que normalement le compilateur connais le type de retour de getWindowAncestor() non ?

  14. #14
    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
    Je pense que le problème vient des parenthèses et pas de la variable intermédiaire.

    Ecrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (JFrame)SwingUtilities.getWindowAncestor(ImageScroll.this).getGlassPane()
    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.

    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.

  15. #15
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 95
    Points : 60
    Points
    60
    Par défaut
    Allez moi je vais me coucher, je commences à poser des questions totalement débiles.

    Merci à toi

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

Discussions similaires

  1. problème défilement images en ActionScriptII
    Par cds82 dans le forum Flash
    Réponses: 2
    Dernier message: 10/11/2006, 13h55
  2. Script défilement images
    Par glloq8 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 24/10/2005, 15h53
  3. [FLASH MX] Problème pour défilement images
    Par Buzhug dans le forum Flash
    Réponses: 10
    Dernier message: 22/10/2004, 21h09

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