簡體   English   中英

嘗試在JProgressBar中使用線程

[英]Trying to use a thread with JProgressBar

因此,我試圖學習如何使用線程,所以我決定制作一個程序,添加一個線程,然后等待1/2秒。 而線程(我認為我做對了)刷新進度條的值。 因此,我不確定是否將程序弄錯了,或者是否卡在某個地方。 所以我在線程中放入了一個println ,這就是我得到的:

thred
0
1
2
3
4
5
6
7
8
9
10
11 (ect...)

這是我的框架代碼:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;

public class frame extends JFrame implements ActionListener{

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

    public static void main(String[] args) {
        frame f = new frame();
        f.setVisible(true);
        f.setSize(450,120);
    }

    /**
     * Create the frame.
     */

    public JProgressBar bar;

    public frame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 449, 120);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        bar = new JProgressBar();
        bar.setStringPainted(true);
        bar.setBounds(6, 50, 438, 32);
        contentPane.add(bar);

        JLabel lblNewLabel = new JLabel(
                "Percent of for loop completion");
        lblNewLabel.setBounds(6, 6, 279, 16);
        contentPane.add(lblNewLabel);

        JButton btnStart = new JButton("START");
        btnStart.setBounds(327, 1, 117, 29);
        btnStart.addActionListener(this);
        contentPane.add(btnStart);
    }

    public int i, progress;
    public void actionPerformed(ActionEvent e) {
        updater u = new updater();

        u.start();
        for( i =0; i < 100; i++){
            progress = i;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            System.out.println(i);
        }

    }

}

這就是我的線程類:

public class updater extends Thread {

    public void run() {
        System.out.println("thred");
        frame f = new frame();

        int p = f.progress;
        while (p != 100) {

            f.bar.setValue(p);
        }
    }
}

您正在阻止事件調度線程。 除其他事項外,這負責處理油漆更新。 當您阻止線程時,無法進行更新,這意味着您的程序似乎停滯不前...

public void actionPerformed(ActionEvent e) {
    updater u = new updater();
    u.start();
    // Now blocking, no more repaints or event notifications until you finish...
    for( i =0; i < 100; i++){
        progress = i;
        try {
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(i);
    }

}

您遇到的另一個問題是,Swing(大多數情況下)不是線程安全的事實。 也就是說,期望所有與UI的更新和交互將僅在EDT的上下文中發生。

盡管有多種解決方法,但最簡單的方法是使用SwingWorker ,它旨在允許您在后台線程中執行代碼並將更新安全地重新同步到UI。

看一眼...

對於一些例子。

您可能還想看看Swing中的並發以了解更多詳細信息

使用線程進行UI編程非常棘手,如果多個線程嘗試同時修改UI元素,則可能會遇到嚴重的問題。 在Swing應用程序中,對UI的所有更新都應在Swing / AWT事件線程上進行。 通常的方法是使用EventQueue#invokeLater安排一個Runnable在線程上執行。 在這種情況下,將包裝f.bar.setValue(p); Runnable並將其傳遞給invokeLater 這是有關事件線程基礎的有用教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM