2007年12月6日木曜日

Java:いまさらだがプログレスバー

12/13 JDialogをモーダルにしちゃダメですね.…修正.


Swingの始めの頃にツマズイて敬遠してたけどTimerオブジェクトの使い方がポイントだったんだですね.

public class Sample implements ActionListener {
public static void main(String[] args) {
new Sample();
}

private JFrame frame;

private JButton button;

private JDialog dialog;

private JProgressBar progressBar;

private Timer timer;

private Thread thread;

private Job job;

public Sample() {
if (frame == null) {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new FlowLayout());
button = new JButton("Button");
button.addActionListener(this);
panel.add(button);
frame.getContentPane().add(panel);
frame.pack();
}

if (dialog == null) {
dialog = new JDialog(frame, false);
JPanel panel = new JPanel();
progressBar = new JProgressBar(0, 100);
if (false) { // animation only
progressBar.setIndeterminate(true);
}
progressBar.setStringPainted(true);
panel.add(progressBar);
dialog.getContentPane().add(panel);
dialog.pack();
}

if (timer == null) {
timer = new Timer(100, this);
}

frame.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(button)) {
progressBar.setValue(0);
dialog.setVisible(true);

job = new Job();
thread = new Thread(job);

timer.start();
thread.start();
} else if (e.getSource().equals(timer)) {
if (thread.isAlive() == false) {
dialog.setVisible(false);
timer.stop();
job = null;
thread = null;
} else {
progressBar.setValue(job.getStep());
progressBar.setString(String.valueOf(job.getStep()) + "%");
}
}
}

class Job implements Runnable {
int step;

public int getStep() {
return step;
}

public void run() {
for (step = 0; step < 100; step++) {
for (int j = 0; j < 1000; j++) {
System.err.print(".");
}
System.err.println();
}
}
}
}


SwingではactionPerformed内で処理と描画を同時に考えてはダメだったんだよね.
今思えば当たり前.描画というのが命令というより要求であってそのタイミングがいつか?というのを理解しないとだめなんですね.

0 件のコメント: