- ベストアンサー
進捗バーが更新されない問題の修正方法
- プログレスバーの進捗状況が更新されない問題について、修正方法を説明します。
- タイマーを使用せずにプログレスバーの進捗を自動的に更新する方法を紹介します。
- サンプルコードを修正して、プログレスバーの進捗状況を正しく表示するようにします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
JavaのGUIはシングルスレッドなので、ほかの長時間タスクとパラレルに動作(画面更新)するためには、長時間タスクを別スレッドとして動かし、その中でGUIタスクはGUIのスレッド(EDT,イベントディスパッチスレッド)に登録してやる必要があります。JDK 1.6以降は、そのためにSwingWorkerクラスを使います。下記のコードは、SwingWorker以前の古典的なやり方です。 -------------------------------------------------- import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SampleProgressBar extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; JButton startButton; JButton stopButton; JProgressBar bar; JLabel label; int i; boolean go; public void actionPerformed(ActionEvent arg0) { String cmd = arg0.getActionCommand(); if (cmd.equals("start")){ go = true; startButton.setEnabled(false); stopButton.setEnabled(true); Thread t = new Thread(new Runnable(){ public void run(){ for (i = 0; i< 20000; i++ ){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ label.setText(i + " count"); bar.setValue(i); int per = (int)(bar.getPercentComplete() * 100); bar.setString(per + "% 完了"); } }); try { Thread.sleep(1); } catch(InterruptedException err) { err.printStackTrace(); } if (!go){ break; } } } }); t.start(); } else if (cmd.equals("stop")){ startButton.setEnabled(true); stopButton.setEnabled(false); go = false; } } public static void main(String[] args) { SampleProgressBar frame = new SampleProgressBar(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setTitle("Sample"); frame.setVisible(true); } public SampleProgressBar() { super(); initialize(); } private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); label = new JLabel("Not Start"); JPanel labelPanel = new JPanel(); labelPanel.add(label); startButton = new JButton("start"); startButton.addActionListener(this); startButton.setActionCommand("start"); stopButton = new JButton("stop"); stopButton.addActionListener(this); stopButton.setActionCommand("stop"); stopButton.setEnabled(false); JPanel buttonPanel = new JPanel(); buttonPanel.add(startButton); buttonPanel.add(stopButton); bar = new JProgressBar(0, 20000); bar.setStringPainted(true); bar.setString(""); bar.setValue(0); JPanel barPanel = new JPanel(); barPanel.add(bar); getContentPane().add(labelPanel, BorderLayout.PAGE_START); getContentPane().add(buttonPanel, BorderLayout.PAGE_END); getContentPane().add(barPanel, BorderLayout.CENTER); } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(new BorderLayout()); } return jContentPane; } } ------------------------------------------
その他の回答 (1)
- _ranco_
- ベストアンサー率58% (126/214)
まだこのスレッドは締め切られていないようなので、SwingWorkerを使う超簡単なやつをご紹介しておきましょう。まあ、元々、SwingWorkerを使うのはもったいないようなプログラムですが(笑)。 ---------------------------------------------------- import javax.swing.*; import java.beans.*; import java.awt.*; import java.awt.event.*; import java.util.logging.*; public class SampleProgressBar2 extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; JButton startButton; JButton stopButton; JProgressBar bar; JLabel label; int i; Counting counting; public void actionPerformed(ActionEvent arg0) { String cmd = arg0.getActionCommand(); if (cmd.equals("start")){ startButton.setEnabled(false); stopButton.setEnabled(true); counting = new Counting(); counting.addPropertyChangeListener(new PropertyChangeListener(){ public void propertyChange(PropertyChangeEvent e) { if ("c".equals(e.getPropertyName())) { i = (Integer)e.getNewValue(); label.setText(i + " count"); bar.setValue(i); // 以下はSwingWorkerのprogressプロパティをそのまま利用してもよい int per = (int)(bar.getPercentComplete() * 100); bar.setString(per + "% 完了"); } } }); counting.execute(); } else if (cmd.equals("stop")){ startButton.setEnabled(true); stopButton.setEnabled(false); counting.cancel(true); } } public static void main(String[] args) { SampleProgressBar2 frame = new SampleProgressBar2(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setTitle("Sample2"); frame.setVisible(true); } public SampleProgressBar2() { super(); initialize(); } private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); label = new JLabel("Not Start"); JPanel labelPanel = new JPanel(); labelPanel.add(label); startButton = new JButton("start"); startButton.addActionListener(this); startButton.setActionCommand("start"); stopButton = new JButton("stop"); stopButton.addActionListener(this); stopButton.setActionCommand("stop"); stopButton.setEnabled(false); JPanel buttonPanel = new JPanel(); buttonPanel.add(startButton); buttonPanel.add(stopButton); bar = new JProgressBar(0, 20000); bar.setStringPainted(true); bar.setString(""); bar.setValue(0); JPanel barPanel = new JPanel(); barPanel.add(bar); getContentPane().add(labelPanel, BorderLayout.PAGE_START); getContentPane().add(buttonPanel, BorderLayout.PAGE_END); getContentPane().add(barPanel, BorderLayout.CENTER); } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(new BorderLayout()); } return jContentPane; } } class Counting extends SwingWorker<Object, Integer>{ Logger logger; public Counting(){ logger = Logger.getAnonymousLogger(); } public Object doInBackground() { int c = 0; while (! isCancelled() && ++c <= 20000) { firePropertyChange("c", c - 1, c); try{ Thread.sleep(1); } catch (InterruptedException ie){ logger.info(ie.toString()); } } return null; } } ---------------------------------------
補足
ありがとうございます! Java による開発で進めてきまして 一応、サンプル版としては作業終えました。 このプログレスバーについては まだ組み込めてないので締め切ってないのです。 もしかしたら言語を変更するという話しもありまして。。。
補足
ありがとうございます。 SwingWorker なんてものがあるんですね。 サンプルなどをちょっと触ってみたので こちらを使用してみたいと思っています。 それ以前のやり方についても参考になりました。 ありがとうございました。