Question

Je fais un projet et j'ai besoin d'une barre de progression. J'ai le cours avec la minuterie et ça fonctionne bien lorsque j'inclus un principal; Mais quand j'essaie de l'appeler dans la méthode Mainingui, tout est noir jusqu'à ce qu'il atteigne 100% alors.

package microproject.resources;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Timer extends JFrame {

    JProgressBar current;
    JTextArea out;
    JButton find;
    Thread runner;
    int num = 0;
    int length = 0;

    public Timer() {
        setTitle("Progress");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        length = Integer.parseInt(JOptionPane.showInputDialog(null, "How many seconds:"));

        JPanel p = new JPanel(new GridLayout(1,1));
        p.setPreferredSize(new Dimension(300,65));
        current = new JProgressBar(0, length);
        current.setPreferredSize(new Dimension(250,50));
        current.setValue(0);
        current.setStringPainted(true);
        p.add(current);
        setVisible(true);
        setContentPane(p);
        pack();
        setVisible(true);
        iterate();
    }

    public void iterate() {
        while(num < length +1) {
            current.setValue(num);
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {}
            num += 1;
        }

    }

    public static void main(String[] args) {
        Timer f = new Timer();
    }
}

Ceci est le code de la classe de minuterie ^

package microproject.resources;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class GUIMain extends JFrame {

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

    public static void GuiFrame(){
        JFrame frame = new JFrame("Casino Royal3");
        frame.setSize(811,577);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

        frame.setLayout(new GridLayout(2,1));
        frame.setResizable(false);
        JPanel PNorth = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        JPanel PSouth = new JPanel(new BorderLayout());


        //Creating Image for Casino Button
        ImageIcon img1 = new ImageIcon("src\\Casino.jpg");
        final JButton btn1 = new JButton(img1);
        btn1.setPreferredSize(new Dimension(550,274));
        btn1.setMargin(new Insets(0,0,0,0));
        PNorth.add(btn1, BorderLayout.EAST);
        btn1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btn1.setIcon(new ImageIcon("src\\Casino2.jpg"));
            }
        });

        //Creating Image for Sheridan Label
        ImageIcon img2 = new ImageIcon("src\\SHERIDAN_LOGO.jpg");
        JButton btn2 = new JButton(img2);
        btn2.setMargin(new Insets(0,0,0,0));
        PNorth.add(btn2);
        btn2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ImageIcon instruc = new ImageIcon("src\\Instructions.jpg");
                JLabel instructions = new JLabel(instruc);
                JOptionPane.showConfirmDialog(null, instructions, "instructions", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE);
            }
        });

        JPanel timmus = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        timmus.setPreferredSize(new Dimension(166, 273));
        timmus.setBackground(Color.BLUE);

        ImageIcon time = new ImageIcon("src\\Timer.jpg");
        JButton timer = new JButton(time);
        timer.setMargin(new Insets(0,0,0,0));
        timer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Timer f = new Timer();
            }
        });
        timmus.add(timer);

        ImageIcon mus = new ImageIcon("src\\music.jpg");
        JButton music = new JButton(mus);
        music.setMargin(new Insets(0,0,0,0));
        timmus.add(music);

        JPanel games = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        games.setPreferredSize(new Dimension(500,279));
        games.setBackground(Color.BLUE);

        ImageIcon calculator = new ImageIcon("src\\Calculator.jpg");
        JButton calc = new JButton(calculator);
        calc.setMargin(new Insets(0,0,0,0));
        calc.setPreferredSize(new Dimension(166,273));
        games.add(calc);
        calc.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Calculator c1 = new Calculator();
            }
        });

        ImageIcon g1 = new ImageIcon("src\\250Hangman.jpg");
        JButton game1 = new JButton(g1);
        //game1.setBackground(Color.WHITE);
        game1.setMargin(new Insets(0,0,0,0));
        game1.setPreferredSize(new Dimension(166,273));
        games.add(game1);
        game1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Hangman h1 = new Hangman();
            }
        });


        ImageIcon g2 = new ImageIcon("src\\Minesweeper.jpg");
        JButton game2 = new JButton(g2);
    //    game2.setBackground(Color.WHITE);
        game2.setMargin(new Insets(0,0,0,0));    
        game2.setPreferredSize(new Dimension(166,273));
        games.add(game2);

        PSouth.add(timmus, BorderLayout.CENTER);
        PSouth.add(games, BorderLayout.EAST);

        frame.add(PNorth, BorderLayout.NORTH);
        frame.add(PSouth, BorderLayout.SOUTH);

        frame.setVisible(true);
        frame.pack();
    }
}

C'est tout le programme, le Timer ActionListener s'appelle "Timer"

Merci d'avance

Était-ce utile?

La solution

Bienvenue dans le monde merveilleux du fil de répartition des événements bloqués (et violation du fil initial)

Fondamentalement, Swing est un environnement fileté unique, toutes les mises à jour et modifications de l'interface utilisateur devraient être exécutées dans le contexte du thread de répartition des événements (AKA EDT).

L'EDT est responsable, entre autres, des demandes de repeindre. Si, pour une raison quelconque, vous bloquez ce fil (par exemple, en utilisant une longue boucle de course ou en bloquant IO), cela empêchera l'EDT de traiter les nouvelles demandes de peinture, ce qui donne l'impression que votre programme avait suspendu ... parce que essentiellement il a.

La raison pour laquelle vous pourriez voir une différence entre courir Timer Directement et l'utiliser dans votre interface graphique est parce que lorsque l'application est démarrée, elle s'exécutera à l'intérieur, ce que l'on appelle communément le thread "principal".

Lorsque vous créez un conteneur de swing de haut niveau, l'EDT est démarré (qui est un thread séparé), ce qui signifie que l'interface utilisateur apparaîtra dans son propre fil, mais l'application continuera à fonctionner dans le thread "principal", permettant à votre iterate Méthode pour s'exécuter indépendamment de l'EDT.

Cependant, lorsque vous essayez de l'exécuter à partir de votre interface graphique, tout fonctionne dans le contexte de l'EDT, ce qui le fait bloquer.

Commencez par jeter un coup d'œil

Pour résoudre le problème, en fonction de votre exemple de code, je suggère d'utiliser un SwingWorker. Cela vous permettra d'exécuter votre "longue tâche en cours d'exécution" dans un thread d'arrière-plan, mais fournit un certain nombre de méthodes qui vous permettent de reprendre vos mises à jour à l'EDT. Ceci est très important, car vous ne devez jamais tenter de mettre à jour l'interface utilisateur ou de modifier son état à partir d'un fil autre que l'EDT.

Jeter un coup d'œil à Fil de travail et swingworker pour plus de détails

Et si nécessaire, quelques exemples ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top