Các thanh trượt và các thước đo tiến độ

1. Thanh trượt Slider

Tranh trượt Slider hay còn gọi là thước đo, gần giống như thanh cuộn ScrollBar. Tuy nhiên, ScrolỉBar được sử dụng để di chuyển cổng nhìn các vùng dữ’liệu, còn Slider đuợc sử dụng để xác định giá trị của dừ liệu ưong một lỷ lệ cho hước, vi dụ như thước kê của học sinh. ScrollBar cài đặt giao diện Adjustable, còn Slider không cài đặt giao diện đó và có thể xuất hiện như một giao diện sử dụng chung cho cả hai.

Cách chung nhẩt để tạo ra một Slider được thực hiện như sau:

JSlider slider = new JSlider(min, max, initialValue);

Tạo ra một thước đo nằm ngang có giá trị cực tiểu là min, cực đại là max và đầu đọc ở initialValue. Các giá trị của đầu đọc được dịch chuyển trong khoảng từ min tới max. Khi giá trị ờ đầu đọc thay đổi, một sự kiện change Event được gửi tới tất cả các đối tượng đang lắng rlghe để xừ lý cho phù hợp với sự thay đổi đó.

Trường hợp sử dụng toán từ tạo lập slider() mặc định JSlider slider = new JSlider() sẽ tạo ra một thước đo có giả trị cực tiểu là 0 và cực đại là 100, đầu đọc ở giữa (50)

Nếu muốn tạo ra thước đo nằm dọc,.ta sử dụng

JSlider slider = new JSlider (SwingConstraint s. VERTICAL, min, max, initialValue);

Để tạo được những thanh ừượt có các vạch đo, ví dụ các vạch nhò cách nhau 5 đcm vị, các vạch lớn cách nhau 20, ta phải đưa thêm các ràng buộc:

slider.setMajorTickSpacing (20) ; slider.setMinorTickSpacing(5);

Lưu ý, các vạch trên thước đo là các đon vị đo, không phải là pixel.

Ví dụ 4.10. Hãy tạo ra các loại thước đo:

+ Thước đo đon giản Plain: không có thang độ đo,

+ Thước đo Ticks: có thang độ đo và cho phép đo ở mọi cấp độ,

+ Thước đo Snap to ticks: đầu đọc luôn bám theo độ đo đã được vạch sẵn trên thước (làm tròn theo mép vạch gần nhất),

+ Thước đo Fi 1 led: độ đo được xác định bời đầu đọc được tô màu,

+ Thước đo đảo ngược Inverted: độ đo còn lại được tô màu,

+ Thước đo có đánh số Labels: ở những độ đo chỉ định như 0, 20, 40, 60, 80, 100 sẽ được đánh số tương ứng,

+ Thước đo có đánh số Custom labels: ờnhững độ đo chỉ định như 0, 20, 40, 60, 80, 100 sẽ được đánh nhãn tuỳ chinh, ví dụ là ‘A\ ‘B’, ‘C’, ‘D’, ‘E’, ‘F\

Khi các đầu đọc di chuyển thì giá trị tương ứng của mỗi đầu đọc được hiển thị ở ô bên

// SliderTest.java import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*;

public class SliderTest{

public static void main(String argsn){

JFrame fr = new SliderTestFrame(); fr.show();

}

}

//Tạo ra khung chưong trình gồm các loại thước đo và thanh trượt khác nhau

class SliderTestFrame extends JFrame

{

private GridBagConstraints constr; public SliderTestFrame(){ setTitle(“Slider Test”); setsize(400, 300);

addWindowListener(new windowAdapter(){

public void windowclosing(WindowEvent e){ System.exit (0);

}

}) ;

// Đặt layout cho khung chương trình là GridBagLayout và các ràng buộc

getContentPane().setLayout(new GrìdBagLayout());

constr = new GridBagConstraints{);

constr.weighty = 100;

constr.gridheíght = 1;

constr.gridwidth = 1;

constr.gridx = 0;

constr.gridy = 0;

// Tạo ra thanh trượt đơn giản Plain, không có vạch đo

JSlider slider = new JSlider(); addslider(slider, “Plain”);

//Tạo rathanh trượt Tick có vạch đo, và định vịđuợc mọi độ đò từ 0 đến 100

slider = new JSlider); slider.setPaintTicks(true); slider.setMajorTickSpacing(20); slider.setMinorTickSpacing(5); addslider(slider, “Ticks”);

// Tạo ra thanh trượt snap to ticks có vạch đo, nhưng đầu đọc luôn bám // theo vạch thước.

slider = new JSlider(); slider.setPaintTicks(true); slider.setSnapToTicks(true); slider.setMajorTickSpacing(20) ; slider.setMinorTickSpacing(5); addslider(slider, “Snap to ticks”);

//Tạo ra thước đo Fi 11 ed, khoảng cách đo được tô màu slider = new JSlider(); slider.setPaintTicks(true); slider.setMajorTickSpacing(20); slider.setMinorTickSpacing(5);

slider.putClientProperty (“JSlider. isFilled”, Boolean. TRUE) ; addslider(slider, “Filled”);

//Tạo ra thước đo Inverted, ngược lại với thước đo trên, khoảng cách còn lại // được tô màu

slider – new JSlider();

slider.setPaintTicks(true) ; slider.setMaj orTickSpacing(20) ; slider.setMinorTickSpacing(5);

slider.putclientProperty(“JSlider.isFilled”, Boolean.TRUE) ; slider.setInverted(true); addslider(slider, “Inverted”);

// Tạo ra thước đo Labe 1 s, thước được đánh số cách nhau 20 đơn vị

slider = new JSlider();

slider.setPaintTicks(true);

slider.setPaintLabels(true);

slider.setMajorTickSpacing(20);

slider.setMinorTickSpacing(5);

addslider(slider, “Labels”);

//Tạo ra thước đo Labels, đánh nhãn ‘A’, ‘B’,.‘F’ cách nhau 20 đơn vị

slider = new JSlider (); slider.setPaintLabels(true); slider.setPaintTicks(true); slider.setMajorTickSpacing(20); slider.setMinorTickSpacing(5);

Hashtable labelTable = new Hashtable (); labelTable.put(new Integer(0), new JLabel(“A”)); labelTable . put (new Integer (20), new JLabel (“B”)); labelTable.put(new Integer(40), new JLabel ( “C”)); labelTable.put(new Integer(60), new JLabel(“D”)); label Table . put (new Integer ( 80 ) , new ¿[Label ( “E” ) ) ; labelTable.put(new Integer(100), new JLabel ( “F”));

slider.setLabelTable (labelTable); addslider(slider, “Custom Labels”);

slider = new JSlider(); slider.setPaintTicks(true); slider.setPaintLabels(true); slider.setSnapToTicks(true);

slider.setMajorTickSpacìng(20) ; slider.setMinorTickSpacing(20) ;

}

public void addsiider(JSlider s, string descr){

// Tạo lập truờng text để hiển thị số đo được xác định bời đầu đọc thanh trượt final TextField textField = new TextField(4);

// Cập nhật lại số đo khi đầu đọc thanh trượt di chuyến và xử lý các sự kiện

s.addChangeListener(new ChangeListener(){

public void stateChanged(ChangeEvent event){ JSlider source = (JSlider)event.getSource (); textField.setText(“” + source.getValue());

}

}) ;

// Bổ sung 3 thành phần

constr.gridx = 0 ;

constr . anchor = GridBagConstraints WEST; constr.fill = GridBagConstraints.NONE; constr.weightx = 0;

// BỔ sung tên của thước đo

getContentPane().add(new JLabel(descr), constr);

// BỔ sung thước đo ở giữa

constr.griđx++;

constr.anchor = GridBagConstraints.CENTER; constr.fill = GridBagConstraints.HORIZONTAL; constr.weightx = 0;     I

getContentPane().add(s, constr);

// BỔ sung trường text hiển thị số đo constr.gridx++;

constr.anchor = GridBagConstraints.WEST; constr.fill = GridBagConstraints.NONE; constr.weightx = 200;

getContentPane().add(textField, constr);

// Tăng tọa độ y cho thước đo tiếp theo

  • JSlider()
  • JSlider(int direction)
  • JSlider(int min, int max)
  • JSlider(int min, int max, int init)
  • JSlider(int direction, int min, int max, int init)

Tạo ra thước đo theo hướng direction và các giá trị min, max,init tương ứng. Trong đó

+ direction có thể là SwingConstraints. HORIZONTAL thước nằm ngang hoặc SwingConstraints, VERTICAL để tạo ra thước nằm dọc. Mặc định là nam ngang.

+ min, max là các độ đo cực tiểu, cực đại. Mặc định là 0 và 100.

+ init là giá trị ban đầu của đầu đọc. Giá trị mặc định là 50.

  • void setPaintTicks(boolean b): nếu b là true thì thước hiển thị
  • void setMa j orTickSpacing (int units) : Đặt khoảng cáchcục đại giũa các vạch
  • void setMinorTickSpacing (int units): Đặt khoảng cách cực tiểu giữa các vạch
  • void setPaintLabels (boolean b): nếu b là true thì thước hiển thị nhăn
  • void setSnapToTicks (boolean b) : nếu b là true thi đầu đọc luôn bám theo vạch đo.

2. Thước tiến độ JProgressBar

Thước tiến độ JProgressBar là một thành phần đơn giản, nó chính là một hình chữ nhật được tô màu một phần để chì ra tiến độ thực hiện cùa một thao tác (công việc) nào đó. Mặc định, thanh tiến độ thể hiện số % hoàn thành công việc, ví dụ công việc cài đặt một phần mềm đã hoàn thành cho đến thời điểm đó.

Ta có thể thiết lập thước tiến độ giống như đối với thước đo. Ví dụ tạo ra thước tiến độ nằm ngang:

JProgressBar progressBar = new JProgressBar(0, 100); hay tạo ra thước tiến độ nằm dọc:

progressBar = new JProgressBar (SwingConstraints.VERTIVÄL, 0, 100);

Ta cũng có thể đặt các độ đo cực tiểu, cực đại thông qua phưcmg thức setMinimurn() và setMaximum().

Tuy nhiên, thước tiến độ khác với thước đo ờ chỗ người sử dụng không tự chỉnh sửa được độ đo tiến độ. Chương trình của ta phải gọi setValue() để thay đổi mức độ hoàn thành công việc.

Nếu ta gọi

progressBar.setStringPaint(true);

thì thước tiến độ sẽ tinh n% hoàn thành công việc và hiển thị dưới dạng xâu “n%”. Nếu muốn hiển thị những thông tin khác thì sử dụng phương thức setstríng(), ví dụ: if(progressBar.getValue() > 900)

progressBar.setstring(“Almost Done”);

Ví dụ 4.11. Xây dựng chương trinh có một thanh ghi tiến độ thề hiện sự tiêu tốn thời gian của mảy tinh như hình 4.15. Thước tiến độ có giá trị cực tiểu tà 0 kể từ lúc nhấn nút bắt đầu và giá trị cực đại là 1000 đơn vị thời gian cùa máy tính.

Việc thay đổi mức độ tiêu tốn thời gian ờ thước tiến độ được mô phỏng bời lớp SimulatedActivity. Lớp này cài đặt để thực hiện theo luồng sao cho giá trị của current tăng lên 10 lần trong một giây. Khi current đạt đến target hoặc luồng thực hiện bị ngắt thì nó kết thúc.

class SimulatedActivitỵ extends Thread! private int current; private int target;

//…

public void run(){

while(current < target && ! interrupted()) {

try {

sleep(100);

}catch(InterruptedException e){ return;

}

current++;

}

)

}

Khi ta nhấn nút start, một luồng mới bắt đầu thực hiện. Ta biết rằng javax. swing. Timer gọi phương thức act ionPerformed 0 để lắng nghe các sự kiện và tính thời gian hiện thời current như sau:

public void actionPerformed(ActionEvent evt){ int current = activity.getCurrent();

// Hiển thị ở thanh tiến độ

textArea.append(current + “\n”);

progressBar.setValue(current) ;

// Kiềm tra xem công việc đă kết thúc chưa if (current == activity. getTarget 0) { activityMonitor.stop(); startButton.setEnabled(false);

}

 // ProgressTest.java import java.awt.*; import java.awt.event.*; import javax.swing;

import javax.swing.event.*;                                                      ‘

public class ProgressTest{

public static void main(String args[]){

JFrame fr = new ProgressTestFrame(); fr.show();

}

}

// Khung chương trình thực hiện mô phòng thanh tiến độ tiêu tốn thời gian

class ProgressTestFrame extends JFrame

{

private Timer activityMonitor; private JButton startButton; private JProgressBar progressBar; private JTextArea textArea; private SimulatedActivity activity; public ProgressTestFrame(){

setTitle ( “Progress Bar Test”); setSize (300, 200);

addWindowListener(new WindowAdapter(){

public void windowclosing(WindowEvent e){ System.exit(0);

}

} ) ;

// Tạo ra vùng văn bàn để luu giữ kết quả

Container content = getContentPane(); textArea = new JTextArea();

// Thiết lập panel cùng với nút nhấn và thanh tiến độ

JPanel panel = new JPanel(); startButton = new JButton(“start”); progressBar = new JProgressBar() ; progressBar.setStringPainted(true); panel.add(StartButton) ; panel.add(progressBar) ;

content.add(new JScrollPane(textArea), “Center”); content.add(panel, “South”);

// Khởi động hoạt động khi nhấn nút start startButton.addActionListener( new ActionListener() {

public void actionPerformed (ActionEvent evt) { progressBar.setMaximum(1000); activity = new SimulatedActivity(1000);

activity.start (); activìtyMonitor.start (); startButton. setEnabled(false)

// Khởi động hoạt động cùa đồng hồ Timer

actìvitỵMonitor = new Timer(500, new ActionListener(){

public void actionPerformed(ActionEvent evt){
int current = activity.getCurrent0;

// Hiển thị tiến độ

textArea.append(current + “\n”); progressBar.setValue(current);

// Kiểm tra xem công việc đã kết thúc chưa

if(current == activity.getTarget() ) { activityMonitor.stop(); startButton.setEnabled(false);

}

}) ;

class SimulatedActivity extends Threadf private int current; private int target; public SimulatedActivity(int t){ current = 0; target = t;

}

public int getTarget(){ return target;

}

public int getCurrent() {

return current;

}

public void run{){

while(current < target && !interrupted()){ try{

sleep(100);

}catch(InterruptedException e){ return;

}

current++;

}

}

}

Javax.swing.JProgressBar

  • JProgressBar()
  • JProgressBar(int direction)
  • JProgressBar(int min, int max)
  • JProgressBar(int min, int max)
  • JProgressBar (int direction, int min, int max)

Tạo ra thước đo theo hướng direction và các giá trị min, max tương ứng. Trong đó

+ direction có thể là SwingConstraints . HORIZONTAL hoặc SwingConstraints .VERTICAL. Mặc định là nằm ngang.

+ min, max là các độ đo cực tiểu, cực đại. Mặc định là 0 và 100.

  • int getMinimum()
  • int getMaximum ( ) : Xác định các giá trị cực tiểu, cực đại
  • void setMinimum(int val)
  • void setMaximum (int val): Đặt các giá trị cực tiểu, cực đại
  • void setValue (int val) : Đã! lại giá trị hiện thời
  • int getVaỉue(int vaỉ): Đọc giá trị hiện thời
  • void setstring (String s): Dặt lại thông báo hiển thị
  • String getstring (): Đọc thông báo hiển thị.

Thước tiến độ là một thành phần đơn giản có thể đặt bên trong một cửa sổ, một khung chương trình. Ngược lại, ProgressMonitor là một hộp thoại trong đó chứa một thước tiến độ. Tất nhiên, hộp thoại thường có hai nút: OK và Cancel. Nếu ta nhấn nút Cancel thi công việc đang được theo dõi sẽ bị huỷ bỏ mặc dù chưa hoàn thành. Chi tiết hom ta có thể tham khảo ở tài liệu.