close

預設之進度條或圈可能無法滿足各種版型,因此本次採用輪播圖片的方式,再加上實作Runnable介面以實現多線程(/執行緒)來不斷地執行該動畫,以達到進度圈之樣貌,並在此給予範例以供各位參考與學習。

 

1. RunnableThread的區別

2. Java中有二種方式可實現多線程,一為繼承Thread類別,另一則為實作Runnable介面。

        a.  繼承Thread類別

       Class只要extendsThread,並覆寫run()方法,即可實現多線程之操作,但因一個Class只能繼承一個父類別,因此大多是透過實作Runnable介面來完成的。

        b. 實作Runnable介面

       (1) 一個Class只要implementsRunnable,且覆寫run()方法,即可實現多線程之操作,但因Runnable定義的子類別中没有start()方法,因此利用public Thread(Runnable target)建構子,來接受Runnable的子類實例,並再透過Thread來啟動之。

                (2) Ex

CustomThreadct = new CustomThread(“自製線程內容”);

Thread thread = new Thread(ct);

thread.start();

          c. 差異之間的小結

        多線程大多皆以「實作Runnable介面」為主,因為其好處在於:避免侷限於只能繼承一個父類別之問題,其能一個類別實作好幾個介面。

 

  1. 範例:在此展示一個共有8張相似之圖示,並於每180毫秒就會重新變更該圖片之範例,其主要為達到下載中的進度圈之效果。
/**
 *
 * @author Elsa
 */
public class ProgressBarAnimation extends JFrame {
    Thread thread = new Thread(new ActionThread());     // 創建線程(thread)
    boolean flag = true;                    // 用於標示動畫是否為開始播放(/暫停/繼續)之狀態
    boolean stop = false;                   // 用於標示動畫是否為停止之狀態
    final JLabel labImge, labStatus;                // 用於顯示圖片之label、和顯示[下載中]之狀態文字
    JPanel panelLoadingContent;                     // 用於顯示裝載提示下載中之狀態文字與圖片
    JButton btnStart, btnStop;                      // 用於啟動或停止動畫執行之按鈕
    String picturePath;                             // 用於儲存圖片路徑之變數
    
    /*
     * 初始化各元件與設定
     */
    public ProgressBarAnimation() {
        // 1.初始化Frame之相關設定
        setSize(350, 350);
        setTitle("動畫進度圈之範例");
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        // 2.生成各元件
        panelLoadingContent = new javax.swing.JPanel();
        labImge = new JLabel();
        labStatus = new javax.swing.JLabel();
        btnStart = new javax.swing.JButton();
        btnStop = new javax.swing.JButton();

        // 3.初始化panelLoadingContent、labImge、labStatus之設定,並先隱藏該panel
        panelLoadingContent.setOpaque(false);
        panelLoadingContent.setBackground(new java.awt.Color(255, 255, 255));
        panelLoadingContent.setMaximumSize(new java.awt.Dimension(100, 100));
        panelLoadingContent.setMinimumSize(new java.awt.Dimension(100, 100));
        panelLoadingContent.setLayout(new java.awt.BorderLayout());
        labImge.setIcon(new javax.swing.ImageIcon(getClass().getResource("/test2/Res/progress_bar_circles_01.png")));
        panelLoadingContent.add(labImge, java.awt.BorderLayout.CENTER);
        labStatus.setText("下載中");
        labStatus.setForeground(new java.awt.Color(0, 102, 255));
        labStatus.setFont(new java.awt.Font("微軟正黑體", 1, 16));
        labStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        panelLoadingContent.add(labStatus, java.awt.BorderLayout.SOUTH);
        getContentPane().add(panelLoadingContent, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 100, -1, -1));
        panelLoadingContent.setVisible(false);

        // 4.設定[開始]和[停止]按鈕之ActionListener
        btnStart.setText("開  始");
        getContentPane().add(btnStart, new org.netbeans.lib.awtextra.AbsoluteConstraints(100, 220, -1, -1));
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent arg0) {
                // 若線程為空(即null),則重新創建線程物件
                if (thread == null)
                    thread = new Thread(new ActionThread());
                //  判斷該活動線程是否正在執行,若false,則執行下述之代碼,以啟動線程的執行
                if (!thread.isAlive()) {
                    panelLoadingContent.setVisible(true);
                    stop = false;
                    flag = true;
                    thread.start();
                }
            }
        });
        
        btnStop.setText("停  止");
        getContentPane().add(btnStop, new org.netbeans.lib.awtextra.AbsoluteConstraints(152, 220, -1, -1));
        btnStop.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent arg0) {
                panelLoadingContent.setVisible(false);
                stop = true;        // 設置為true,以停止播放動畫
            }
        });
    }

▲初始化各元件與設定之程式

 

/*
     * 用於實現動畫的線程 (其用於每180毫秒重新設定圖片,以達到動畫之效果)
     */
    private class ActionThread implements Runnable {
        private int index = 0;  // 用於控制圖片的編號

        public void run() {
            while (true) {
                // 如stop為true,則停止動畫之播放
                if (stop) {
                    thread = null;      // 銷毀線程
                    break;      // 跳出循環,結束線程的執行
                }
                // 如為播放狀態者(即flag=true),則開始設定圖片
                if (flag) {
                    String picture = "/test2/Res/progress_bar_circles_0";       // 設置圖片存放的位置路徑
                    index++;
                    if (index <= 8) {       // 動畫圖示共為8張,以讓其一直循環這8張圖
                        picturePath = picture + index + ".png";
                        if(index % 2 == 0)      // 取餘數,讓奇偶數之圖示時的狀態文字有不一樣的色調,以顯示微跳動之感
                            labStatus.setForeground(new java.awt.Color(0,153,255));
                        else
                            labStatus.setForeground(new java.awt.Color(0, 102, 255));
                    } else {
                        index = 1;
                        picturePath = picture + index + ".png";
                        labStatus.setForeground(new java.awt.Color(0, 102, 255));
                    }
                    // 設置顯示之圖片
                    labImge.setIcon(new javax.swing.ImageIcon(getClass().getResource(picturePath)));
                    try {
                        Thread.sleep(180);      // 讓線程休眠180毫秒,再設置下一張圖片
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }

用於實現動畫線程之程式

 

/*
     * 視窗關閉事件
     */
    public void processWindowEvent(WindowEvent e) {
        if (e.getID() == WindowEvent.WINDOW_CLOSING)
            System.exit(0);
    }

視窗關閉事件與主程式等程式

 

3. 執行結果

ProgressBarAnimationResult_1.png

尚未啟動之樣貌

 

ProgressBarAnimationResult_2.png

ProgressBarAnimationResult_3.png

ProgressBarAnimationResult_4.png

ProgressBarAnimationResult_5.png

執行中之樣貌

 

 

參考網址:

http://blog.csdn.net/wwww1988600/article/details/7309070

 

 

 

arrow
arrow

    Elsa 發表在 痞客邦 留言(0) 人氣()