class SimulatedTarget implements Runnable {
private volatile int current = 0;
private final int amount;
SimulatedTarget(int amount) { this.amount = amount; }
public int getAmount() { return amount; }
public int getCurrent() { return current; }
public void run() {
while (current < amount) { Thread.sleep(50); current++; }
}
}
// UI 組裝
JProgressBar bar = new JProgressBar(JProgressBar.VERTICAL);
bar.setMinimum(0);
bar.setMaximum(target.getAmount());
new Thread(target).start();
new Timer(300, e -> bar.setValue(target.getCurrent())).start();
ProgressMonitor monitor = new ProgressMonitor(null, "等待任務完成", "已完成:", 0, target.getAmount());
new Timer(300, e -> {
monitor.setProgress(target.getCurrent());
if (monitor.isCanceled()) { timer.stop(); targetThread.interrupt(); System.exit(0); }
}).start();
共用 `BoundedRangeModel`,支援:
ChangeListener listener = e -> showVal.setText("值:" + ((JSlider)e.getSource()).getValue());
// 普通
addSlider(new JSlider(), "普通");
// 保留區 extent=30
JSlider s = new JSlider(); s.setExtent(30); addSlider(s, "保留區30");
// 主次刻度 + 範圍
s = new JSlider(30,200); s.setPaintTicks(true); s.setMajorTickSpacing(20); s.setMinorTickSpacing(5); addSlider(s, "有刻度");
// 吸附刻度
s = new JSlider(); s.setSnapToTicks(true); s.setPaintTicks(true); s.setMajorTickSpacing(20); s.setMinorTickSpacing(5); addSlider(s, "吸附刻度");
// 無軌道
s = new JSlider(); s.setPaintTrack(false); s.setPaintTicks(true); ... addSlider(s, "無軌道");
// 反向
s = new JSlider(); s.setInverted(true); s.setPaintTicks(true); ... addSlider(s, "反向");
// 數值標籤
s = new JSlider(); s.setPaintLabels(true); s.setPaintTicks(true); ... addSlider(s, "數值標籤");
// 自定文字標籤
s = new JSlider(); s.setPaintLabels(true); s.setLabelTable(Map.of(0,new JLabel("A"),20,new JLabel("B"),...)); addSlider(s, "文字標籤");
// 自定圖標標籤
s = new JSlider(); s.setPaintLabels(true); s.setLabelTable(Map.of(0,new JLabel(new ImageIcon("0.gif")),...)); addSlider(s, "圖標標籤");
| 場景 | 推薦組件 |
|---|---|
| 後台任務進度回報 | JProgressBar / ProgressMonitor |
| 用戶手動選擇數值範圍 | JSlider |
| 精確微調數值/日期/列表 | JSpinner |