Clignotement dans JFrame Java


Bonjour les gars, je fais un thread pour mettre à jour une balle sur JFrame donc je repeint l'écran... et puis peindre la balle mettre à jour sa position .. et puis dessiner de nouveau l'écran ... tirer la balle et le même cycle ... voici le code

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
   Thread t = new Thread()
   {
     public void run()
     {
         while(true)
         {
             repaint();
             b2.update(ob,2);
             b2.paint(ob.getGraphics());

             b2.setT(b2.getT() + 1);
             try {
                 Thread.sleep(50);
             } catch (InterruptedException ex) {
                 System.out.println("Error in Sleeping");
             }

         }
     }
   };

   t.start();
}

Mais le problème est que je ne vois pas la balle... la peinture de l'écran remplace toujours la balle et la balle est comme sous le Jframe ..

Author: mKorbel, 2012-12-08

3 answers

Si vous souhaitez avoir des animations dans Swing, la classe recommandée à utiliser est la javax.swing.Timer. Cette classe vous permet d'effectuer des opérations sur le thread de répartition des événements à intervalles réguliers.

 6
Author: Robin, 2017-05-23 10:29:39

Quelques Règles Générales

  • Swing n'est pas thread safe, vous ne devriez jamais mettre à jour les composants de l'interface utilisateur que dans le contexte du Thread de répartition des événements.
  • Vous ne contrôlez pas le processus de peinture, le repaint manager le fait. Vous pouvez demander des mises à jour en appelant repaint, mais vous ne devez jamais appeler update et paint directement lorsque vous essayez de mettre à jour l'affichage.
  • Le contexte Graphics utilisé par le sous-système paint est une ressource partagée garanti pour être le même entre les cycles de peinture, vous ne devriez jamais maintenir une référence à elle. Vous ne devez pas non plus vous fier aux résultats de JComponent#getGraphics cette méthode est capable de renvoyer null.

Un Exemple De Solution

Vous avez un certain nombre d'options, en fonction de ce que vous voulez finalement réaliser.

Vous pouvez utiliser un SwingWorker, mais étant donné que tout ce que vous allez faire est d'entrer dans une boucle infinie et qu'il serait plus facile d'utiliser {[7] } alors utilisez réellement le publish méthode, cette approche serait en fait plus de travail.

Vous pouvez également utiliser un Thread, mais vous vous retrouverez avec les mêmes problèmes que l'utilisation d'un SwingWorker

La solution simpliset, pour ce que vous êtes présenté, est en fait un javax.swing.Timer

public class Blinky {

    public static void main(String[] args) {
        new Blinky();
    }

    public Blinky() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BlinkyPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    protected class BlinkyPane extends JPanel {

        private JLabel blinkyLabel;
        private boolean blink = false;

        public BlinkyPane() {
            setLayout(new GridBagLayout());
            blinkyLabel = new JLabel("I'm blinking here");
            blinkyLabel.setBackground(Color.RED);
            add(blinkyLabel);

            Timer timer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    blink = !blink;
                    if (blink) {
                        blinkyLabel.setForeground(Color.YELLOW);
                    } else {
                        blinkyLabel.setForeground(Color.BLACK);
                    }
                    blinkyLabel.setOpaque(blink);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 100);
        }

    }

}

Vous pouvez jeter un oeil à Swing Timeret Concurrence dans Swing pour plus d'informations

 2
Author: MadProgrammer, 2012-12-08 22:00:21

Si vous accédez à des composants GUI en dehors de l'EDT (Event Dispatch Thread), vous pouvez rencontrer des problèmes étranges, contrairement à si vous effectuez des tâches de longue durée dans l'EDT, vous aurez également des problèmes.

Vérifier ce post pour plus d'infos sur GUI Threading in Java

 0
Author: Extreme Coders, 2017-05-23 12:10:50