Frage

Ich mache ein Projekt und brauche eine Fortschrittsleiste. Ich habe die Klasse mit dem Timer und es läuft gut, wenn ich ein Hauptförderer einbeziehe. Aber wenn ich versuche, es in der Maingui -Methode zu nennen, ist es nur schwarz, bis es zu 100% trifft und dann erscheint.

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

Dies ist der Code für die Timer -Klasse ^ ^

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

Das ist das gesamte Programm, das Timer ActionListener heißt "Timer"

Danke im Voraus

War es hilfreich?

Lösung

Willkommen in der wundervollen Welt des blockierten Ereignis -Versands (und Verstoß gegen den ersten Thread)

Grundsätzlich ist Swing eine einzelne Thread -Umgebung, alle Updates und Modifikationen an der Benutzeroberfläche werden voraussichtlich im Kontext des Ereignis -Versand -Threads (auch bekannt als EDT) ausgeführt.

Die EDT ist unter anderem für die Bearbeitung von Repaint -Anfragen verantwortlich. Wenn Sie diesen Thread aus irgendeinem Grund blockieren (beispielsweise mit einer lang laufenden Schleife oder einem Blockierungs -IO), verhindert er, dass die EDT neue Farbanforderungen verarbeitet, so hat.

Der Grund, warum Sie einen Unterschied zwischen dem Laufen sehen könnten Timer Direkt und die Verwendung in Ihrer GUI, weil die Bewerbung begonnen wird, wird sie im Inneren ausgeführt, was allgemein bekannt ist, der "Haupt" -Thread.

Wenn Sie zum ersten Mal einen Swing -Container der obersten Ebene erstellen, wird der EDT gestartet (was ein separater Thread ist), was bedeutet, dass die Benutzeroberfläche in seinem eigenen Thread angezeigt wird. Die Anwendung wird jedoch weiterhin im "Haupt" -Thread ausgeführt, wobei Ihr Ihre Erläuterungen ermöglicht, sodass Sie Ihrem Thread ermöglichen. iterate Methode, um unabhängig vom EDT zu laufen.

Wenn Sie jedoch versuchen, es aus Ihrer GUI auszuführen, läuft alles im Kontext des EDT, was dazu führt, dass es blockiert wird.

Schauen Sie sich zunächst an

Um das Problem basierend auf Ihrem Beispielcode zu beheben, würde ich vorschlagen, a zu verwenden SwingWorker. Auf diese Weise können Sie Ihre "Langzeitaufgabe" in einem Hintergrund -Thread ausführen, bietet jedoch eine Reihe von Methoden, mit denen Sie Ihre Updates wieder an die EDT synchronisieren können. Dies ist sehr wichtig, da Sie niemals versuchen sollten, die Benutzeroberfläche zu aktualisieren oder ihren Status von einem anderen Thread zu ändern, der EDT.

Sich ansehen Arbeiterfäden und Swingworker für mehr Details

Und bei Bedarf einige Beispiele ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top