문제

프로젝트를 만들고 있으며 진행률 표시 줄이 필요합니다. 나는 타이머가있는 수업을 받았으며 메인을 포함 할 때 잘 실행됩니다. 그러나 내가 마소어 방법으로 부르려고 할 때, 그것이 100%에 부딪히기 전까지는 모두 검은 색입니다.

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

이것은 타이머 클래스의 코드 ^입니다

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

이것이 전체 프로그램입니다. 타이머 ActionListener는 "Timer"라고합니다.

미리 감사드립니다

도움이 되었습니까?

해결책

The Wonderful World of Blocked Event Dispatching Thread (및 초기 스레드 위반)에 오신 것을 환영합니다.

기본적으로 Swing은 단일 스레드 환경이며, UI에 대한 모든 업데이트 및 수정은 이벤트 파견 스레드 (일명 EDT)의 맥락에서 실행될 것으로 예상됩니다.

EDT는 무엇보다도 리 페인트 요청을 처리 할 책임이 있습니다. 어떤 이유로 든이 스레드를 차단하면 (예 : 장거리 루프 또는 IO 차단 사용) EDT가 새로운 페인트 요청을 처리하는 것을 방지하여 프로그램이 매달린 것처럼 보이게합니다. 가지다.

달리기 사이의 차이를 볼 수있는 이유 Timer GUI에서 직접 사용하면 응용 프로그램이 시작될 때 일반적으로 "기본"스레드로 알려진 내부에서 실행되기 때문입니다.

처음으로 최상위 스윙 컨테이너를 만들 때 EDT가 시작되었습니다 (별도의 스레드)는 UI가 자체 스레드에 표시되지만 응용 프로그램은 "기본"스레드에서 계속 실행되므로 허용합니다. iterate EDT와 독립적으로 실행하는 방법.

그러나 GUI 내에서 시도하고 실행하면 EDT의 맥락에서 모두 실행되어 차단됩니다.

살펴 보면서 시작하십시오

예제 코드를 기반으로 문제를 해결하려면 SwingWorker. 이렇게하면 배경 스레드에서 "긴 실행 작업"을 실행할 수 있지만 업데이트를 EDT로 다시 동기화 할 수있는 여러 가지 방법을 제공합니다. UI를 업데이트하거나 EDT 외에 다른 스레드에서 상태를 변경하지 않아야하기 때문에 이것은 매우 중요합니다.

보세요 작업자 스레드와 스윙 워크 자세한 사항은

그리고 필요한 경우 몇 가지 예 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top