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

AWT/Swing Java Discussion :

Faire bouger une piece sur un jeu d'echecs


Sujet :

AWT/Swing Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut Faire bouger une piece sur un jeu d'echecs
    Bonjour à tous.

    Voilà mon problème: j'essaie de coder une interface graphique pour un jeu d'échecs. Je souhaite faire en sorte que lorsqu'une IA jouera, l'utilisateur voir la pièce du coup choisi bouger.
    Pour ce faire, je fais bouger les coordonnées de la pièce et la dessine dans un JPanel qui contient l'échiquier. Je rafraichis l'écran régulièrement pour obtenir le mouvement de la pièce.

    La pièce bouge très bien, sans accroc, mais d'autres composants que l'échiquier (par exemple une liste de notation des coups joués) sont impactés et font apparaître des choses pour le moins inattendues et surtout "erronées".

    Pour rafraichir l'écran régulièrement j'utilise un timer qui va appeler régulièrement la méthode paintImmediately() sur le JPanel affichant l'échiquier.

    Je me doute que je n'ai pas du faire les choses dans les règles de l'art mais je ne trouve pas de solution.
    Toute aide sera la bienvenue.
    Merci para avance.


    Nom : Impression ecran.png
Affichages : 484
Taille : 306,1 Ko

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 112
    Par défaut
    Je ne sais pas si c'est une erreur dans ton code. Mais ça me fait penser a un truc que j'ai rencontré sous windows 11 avec un ecran 4k.

    Essaye, si tu peux reproduire facilement le bug et constater si ca marche ou pas de desactiver d3d au lancement du programme avec le paramètre :

    Par contre je vois java 8 pour le projet, faudrait peut être se mettre a jour (sans méchancetée
    (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

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Bonjour Wax78.

    Merci pour ta réponse.

    J'ai tenté de passer à la JVM le paramètre que tu m'as donné. Mais rien n'y fait, j'ai toujours des anomalies ...

    Pour ce qui est de la reproduction du bug, je n'y suis pas arrivé: je ne sais pas dans quelles situations il apparaît. C'est un peu pour ça que je me tourne vers vous: voir avec des gens qui ont un peu plus de bouteille.

    Pour ma version de Java, c'est vrai que je suis un peu à la traine, mais ça n'est pas une priorité (je doute que mon bug vienne de là , mais je peux me tromper...).

    Je précise que les composants (au sens swing) où apparaisse les anomalies ne sont pas à chaque fois les mêmes, ça peut varier.

    Si besoin n'hésitez pas à me demander d'éventuelles précisions !

    Merci encore.


    EDIT: voilà j'ai mis à jour la JVM dans mon Eclipse... Bug toujours présent.

    RE-EDIT: je ne demande pas forcément une solution à mon problème, mais au moins des pistes à explorer.... car là je ne sais même pas dans quelle direction chercher...
    Comme je l'ai déjà dit, toute aide sera la bienvenue.

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Bonjour.

    Je reviens vers vous pour apporter une précision qui peut avoir son importance: lorsqu'une anomalie survient, si je minimise ma fenêtre et que je la rouvre, l'anomalie a disparu, l'affichage est normal.

    Voilà...

  5. #5
    Membre éprouvé Avatar de kick54
    Homme Profil pro
    Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Inscrit en
    Mai 2016
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2016
    Messages : 120
    Par défaut
    Citation Envoyé par amauryxiv Voir le message
    Bonjour.

    Je reviens vers vous pour apporter une précision qui peut avoir son importance: lorsqu'une anomalie survient, si je minimise ma fenêtre et que je la rouvre, l'anomalie a disparu, l'affichage est normal.

    Voilà...
    Bonjour amauryxiv,

    pas facile sans le code ...

    cependant, dans l'action de l'évènement qui déclenche le défaut, essaie d'ajouter en dernière instruction
    Cordialement

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Bonjour kick54.

    Merci pour la réponse.

    En fait je m'en suis sorti en faisant en sorte que le rafraichissement se déroule dans event-dispatch-thread (avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeAndWait()
    ), et depuis le problème a disparu.
    A l'occasion je testerai ta méthode et si ça marche j'opterai pour elle...

  7. #7
    Membre éprouvé Avatar de kick54
    Homme Profil pro
    Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Inscrit en
    Mai 2016
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2016
    Messages : 120
    Par défaut
    Citation Envoyé par amauryxiv Voir le message
    Bonjour kick54.

    Merci pour la réponse.

    En fait je m'en suis sorti en faisant en sorte que le rafraichissement se déroule dans event-dispatch-thread (avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SwingUtilities.invokeAndWait()
    ), et depuis le problème a disparu.
    A l'occasion je testerai ta méthode et si ça marche j'opterai pour elle...
    Bonjour
    ah oui, c'est bien utile
    Pour les programmes swing, j'utilise toujours le même Main() ci-dessous, où la Classe FenetrePrincipale hérite de 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
     
    public class Main {
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws IOException {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    FenetrePrincipale fenetre = new FenetrePrincipale();
                }
            });
        }
     
    }
    Bonne journée

  8. #8
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Bonjour kick54 (et les autres).

    J'ai pu essayer l'appel à updateUI() : ça a l'air de très bien marcher !

    Deux questions:
    - pourquoi l'appel à paintImmediately() ne fonctionne pas; quel va être la différence avec updateUI() ?
    - pourquoi l'utilisation de invokeAndWait() dans le code que tu as envoyé ?

    Merci pour ton aide.

  9. #9
    Membre éprouvé Avatar de kick54
    Homme Profil pro
    Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Inscrit en
    Mai 2016
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2016
    Messages : 120
    Par défaut
    Citation Envoyé par amauryxiv Voir le message
    Bonjour kick54 (et les autres).

    J'ai pu essayer l'appel à updateUI() : ça a l'air de très bien marcher !

    Deux questions:
    - pourquoi l'appel à paintImmediately() ne fonctionne pas; quel va être la différence avec updateUI() ?
    - pourquoi l'utilisation de invokeAndWaitinvokeLater() dans le code que tu as envoyé ?

    Merci pour ton aide.
    Bonjour

    invokeLater() garantit que les composants Swing sont créés et exécutés sur le thread de répartition d'événements. C'est indispensable quand tu as des animations. Ces dernière doivent obligatoirement utiliser la classe javax.swing.Timer (synchronisation avec le thread swing) sous peine de bug d'affichage.

    updateUI() : honnêtement je ne connais pas le lien entre elle et les méthodes paintXXX(). Je n'ai jamais pris le temps de fouiller plus avant (il faudra suivre dans le code source). Je l'utilise un peu comme un couteau suisse quand rien d'autre ne passe, en mode "Bourrin" quoi.
    Mon hypothèse : updateUI provoque la mise à jour du look & feel et donc met à jour la présentation de toute l'arborescence des composants graphiques.

    Ci-dessous deux exemples mettant en oeuvre le javax.swing.Timer.
    La Main() est celle donnée précédemment.

    • Avec un JTextField :



    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
     
    package IHM;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
     
    /**
     *
     * L'interface est construite directement dans FenetrePrincipale
     * le programme affiche l'heure système dans un JTextField.
     * <br>
     * Après avoir paramétré la JFrame, un JPanel et un JFexteField,
     * on instancie un écouteur dévènement (ActionListener)
     * dont on surcharge (@override) l'action associée 
     * lorsque survient un évènement.
     * L'action associée met à jour le contenu du JTextField avec l'heure système.
     * <br>
     * Ensuite on instancie un Timer Swing :
     * <ul>
     * <li>le premier paramètre du constructeur est la periode en milliseconde,</li> 
     * <li>le second paramêtre du constructeur est l'écouteur associé au Timer.</li>
     * </ul>
     * Toute les 1000 ms, le Timer émet un evenement (un ActionEvent)
     * qui déclenche l'action associée à l'écouteur d'évènement, 
     * ce qui met à jour le contenue du JTextField
     * 
     */
    public class FenetrePrincipale extends JFrame{
     
        public FenetrePrincipale(){
            // Paramétrage de la JFrame
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setTitle("Horloge");
            this.setMinimumSize(new Dimension(600,170));
            this.setLocation(100, 100);
            this.setResizable(false);
            this.setVisible(true);
     
            // Instanciation et paramétrage du JTextField
            JTextField jtfAfficheur = new JTextField();
            jtfAfficheur.setEditable(false);
            jtfAfficheur.setFont(new Font(Font.MONOSPACED, Font.BOLD | Font.ITALIC, 96));
            jtfAfficheur.setBackground(Color.black);
            jtfAfficheur.setForeground(Color.green);
            jtfAfficheur.setColumns(10);
            jtfAfficheur.setHorizontalAlignment(JTextField.CENTER);
     
            //instanciation et paramétrage du JPanel
            JPanel panClock = new JPanel();
            panClock.setLayout(new FlowLayout());
     
            // Ajout du JTextField dans le Jpanel
            panClock.add(jtfAfficheur);
     
            // Ajout du JPanel dans la JFrame
            this.add(panClock);
     
            // "Compactage" de la JFrame
            this.pack();
     
     
            // instanciation de l'écouteur d'évènement
            ActionListener ecouteur = new ActionListener() {
     
                @Override
                public void actionPerformed(ActionEvent e) {
                    SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
                    jtfAfficheur.setText(df.format(Calendar.getInstance().getTime()));
                }            
            };
     
            // instanciation du Timer Swing
            javax.swing.Timer t = new javax.swing.Timer(1000, ecouteur); 
     
            // SetinitialDelay fixe le délai avant l'envoi du premier évènement, ici 100 milliseconde
            t.setInitialDelay(100);
     
            // Lance le Timer qui émettra un évènement toute les 1000 milliseconde
            t.start();
        }
    }

    • Avec PanneauHorloge, une héritière de JPanel et sa méthode paint()


    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
     
     
    package IHM;
     
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import javax.swing.JPanel;
     
    /**
     *
     */
    public class PanneauHorloge extends JPanel {
        private String heure = "";
        private Font fonte ;
        public PanneauHorloge() {
            super();
            fonte = new Font(Font.MONOSPACED, Font.BOLD | Font.ITALIC, 96) ;
        }
     
        @Override
        public void paint(Graphics g){
     
            int x = 48 ;
            int y = 96 ;
     
            g.setColor(Color.black);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setFont(fonte);
            g.setColor(Color.RED);
            g.drawString(heure, x, y);
        }
     
        public void setHeure(String heure) {
            this.heure = heure;
            repaint() ;
        }
     
     
    }
     
     
     
    package IHM;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
     
    /**
     *
     * L'interface est construite avec un PanneauHorloge, 
     * une dérivée de JPanel
     * 
     */
    public class FenetrePrincipale extends JFrame{
     
        public FenetrePrincipale(){
            // Paramétrage de la JFrame
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setTitle("Horloge");
            this.setMinimumSize(new Dimension(600,170));
            this.setLocation(100, 100);
            this.setResizable(false);
            this.setVisible(true);
     
            //instanciation et paramétrage du JPanel
            PanneauHorloge panHorloge = new PanneauHorloge();
     
            // Ajout du JPanel dans la JFrame
            this.add(panHorloge);
     
            // "Compactage" de la JFrame
            this.pack();
     
     
            // instanciation de l'écouteur d'évènement
            ActionListener ecouteur = new ActionListener() {
     
                @Override
                public void actionPerformed(ActionEvent e) {
                    SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
                    panHorloge.setHeure(df.format(Calendar.getInstance().getTime()));
                }            
            };
     
            // instanciation du Timer Swing
            javax.swing.Timer t = new javax.swing.Timer(1000, ecouteur); 
     
            // SetinitialDelay fixe le délai avant l'envoi du premier évènement, ici 100 milliseconde
            t.setInitialDelay(100);
     
            // Lance le Timer qui émettra un évènement toute les 1000 milliseconde
            t.start();
        }
    }

  10. #10
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Citation Envoyé par kick54 Voir le message
    Bonjour

    invokeLater() garantit que les composants Swing sont créés et exécutés sur le thread de répartition d'événements. C'est indispensable quand tu as des animations. Ces dernière doivent obligatoirement utiliser la classe javax.swing.Timer (synchronisation avec le thread swing) sous peine de bug d'affichage.
    Je ne trouve trace nulle-part de la classe javax.swing.Timer ...

    Pour j'ai peut-être parlé un peu vite... Car oui mon bug a disparu mais... un autre est apparu !
    Pour l'instant je vais donc reprendre mon qui marche plutôt bien.
    Au passage, il s'agit bien d'un et non d'un ; pour nos lecteurs, ne pas confondre les deux !

Discussions similaires

  1. [Lazarus] Faire glisser une pièce sur un échiquier en l'attrapant
    Par Roland Chastain dans le forum Lazarus
    Réponses: 12
    Dernier message: 04/06/2016, 06h41
  2. bouger une forme sur borland C++builder4
    Par super_dek dans le forum C++Builder
    Réponses: 3
    Dernier message: 03/01/2007, 12h37
  3. Réponses: 4
    Dernier message: 10/11/2006, 10h55
  4. Faire boucler une Macro sur elle même..
    Par volganne dans le forum Access
    Réponses: 5
    Dernier message: 02/06/2006, 11h13
  5. Faire bouger une baballe
    Par mael94420 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 07/01/2006, 10h33

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