Pergunta

Estou fazendo um projeto e preciso de uma barra de progresso. Eu tenho a aula com o cronômetro e ela funciona bem quando incluo um principal; Mas quando tento chamá -lo no método de Magui, é tudo preto até que atinja 100% apareça.

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

Este é o código para a classe de temporizador ^

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

Esse é o programa inteiro, o Timer ActionListener é chamado de "Timer"

desde já, obrigado

Foi útil?

Solução

Bem -vindo ao maravilhoso mundo do tópico de despacho de eventos bloqueados (e violação do tópico inicial)

Basicamente, espera -se que o Swing seja um ambiente de rosca, todas as atualizações e modificações na interface do usuário devem ser executadas no contexto do encadeamento de despacho de eventos (também conhecido como EDT).

O EDT é responsável, entre outras coisas, processando solicitações de repetição. Se, por algum motivo, você bloqueia esse tópico (por exemplo, usando um loop de longa duração ou bloqueando o IO), isso impedirá que o EDT processe novas solicitações de tinta, fazendo com que pareça como se o seu programa tenha pendurado ... porque essencialmente ele tem.

A razão pela qual você pode ver a diferença entre correr Timer Diretamente e usá -lo na sua GUI é porque, quando o aplicativo é iniciado, ele estará em execução, o que é comumente conhecido como o thread "principal".

Quando você cria um recipiente de balanço de nível superior, o EDT é iniciado (que é um fio separado), o que significa que a interface do usuário aparecerá em seu próprio tópico, mas o aplicativo continuará sendo executado no tópico "principal", permitindo que o seu seu iterate Método para executar independentemente do EDT.

No entanto, quando você tenta executá -lo de dentro da sua GUI, tudo está em execução no contexto do EDT, fazendo com que ele seja bloqueado.

Comece dando uma olhada em

Para corrigir o problema, com base no seu código de exemplo, sugiro usar um SwingWorker. Isso permitirá que você execute sua "tarefa de longa execução" em um encadeamento de segundo plano, mas fornece vários métodos que permitem ressincronizar suas atualizações de volta ao EDT. Isso é muito importante, pois você nunca deve tentar atualizar a interface do usuário ou alterar seu estado de qualquer tópico que não seja o EDT.

Dar uma olhada em Tópicos de trabalhador e swingworker para mais detalhes

E se necessário, alguns exemplos ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top