How to use : Java GUI SwingWorker and BackgroundWorker |
How to use : Java GUI SwingWorker and BackgroundWorker บทความนี้จะต้องบอกว่าเป็นขั้น Advanced มาก ๆ เพราะจะเป็นการเขียน Java GUI ขั้นสูง ในการใช้ SwingWorker ทำงานเป็น Background Process กับการแสดงสถานะการทำงานของ ProcessBar ให้สัมพันธ์กับการใช้งานจริง และจากบทความก่อนหน้านี้ได้อธิบายคร่าว ๆ แล้วว่า SwingWorker จะมี Method ชื่อว่า doInBackground() จะเป็น Method ไว้สำหรับการทำงานของ Process และเราจะใช้ Method นี้ในการตรวจสอบสถานะการทำงาน พร้อมทั้งการ Update สถานะของ ProgressBar
How to use : Java GUI SwingWorker and BackgroundWorker
How to use : Java GUI SwingWorker and BackgroundWorker
โดยในตัวอย่างนี้จะยกตัวอย่างการ Import ข้อมูล Text file จำนวน 1000 รายการลงใน Database และใช้ ProcessBar แสดงสถานะที่เกิดขึ้นจริงในระหว่างการทำงาน และจากโจทย์นี้จำนวน 1000 รายการ นั่นหมายความว่า
1000/100 = 10
หมายความว่า เมื่อข้อมูลเข้า 10 รายการ จะต้องไป Update สถานะ ProcessBar 1 ครั้ง (ProgressBar สถานะ 1-100%) โดยเราสามารถใช้คำสั่ง Update สถานะของ ProcessBar ได้ดังนี้
setProgress((int)((i*100)/1000)+1);
เมื่อทำงานครบ 1000 รายการ จำนวน ProcessBar จะได้ครบ 100% พอดี
Syntax การ Loop ค่า Array ในตัวอย่างนี้
protected Void doInBackground() throws Exception {
/*** Import ***/
for (int i = 0; i < myArrList.size(); i++) {
// SQL Insert
String sql = "INSERT INTO data "
+ "(DataLine) "
+ "VALUES ('" + myArrList.get(i) + "') ";
s.execute(sql);
setProgress((int)((i*100)/myArrList.size())+1);
}
return null;
}
จะสังเกตุว่าใน method ชื่อ doInBackground() ซึ่งเป็นส่วนของการทำงานจะมีการ setProgress() เพื่อไป Update สถานะของ ProgressBar ว่าทำงานได้กี่ % แล้ว โดยเราจะใช้
setProgress((int)((i*100)/myArrList.size())+1);
ประเด็นอยู่ที่ myArrList.size() คือจำนวนรายการที่จะต้อง Insert ซึ่งจะสัมพันธ์กับจำนวน Process กับ ProgressBar ที่เกิดขึ้นจริง ๆ
ในตัวอย่างนี้จะเลือกใช้ Database ของ MySQL แต่ในกรณีที่จะใช้ร่วมกับ Database อื่น ๆ ก็สามารถทำได้ง่าย ๆ เพียงแค่เปลี่ยน Connector และ Connection String เท่านั้น สามารถอ่านเพิ่มเติมได้ที่บทความนี้
Java Connect to MySQL Database (JDBC)
โครงสร้างของ MySQL และ Table
CREATE TABLE `data` (
`ID` int(4) unsigned zerofill NOT NULL auto_increment,
`DataLine` varchar(50) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
คำสั่งของ SQL ที่สามารถนำไปรันบน Query เพื่อสร้าง Table และ Rows ได้ทันที
ข้อมูล Text file ซึ่งมีอยู่ 1000 รายการ
ข้อมูล Text file ซึ่งมีอยู่ 1000 รายการ
Download ไฟลตัวอย่าง
Example การใช้งาน SwingWorker กับ ProcessBar ให้สัมพันธ์กับการทำงานของ Process
MyForm.java
package com.java.myapp;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.JTextField;
public class MyForm extends JFrame {
private JProgressBar progressBar;
private JButton btnStart;
private JTextField txtFile;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
MyForm form = new MyForm();
form.setVisible(true);
}
});
}
public MyForm() {
// Create Form Frame
super("ThaiCreate.Com Java GUI Tutorial");
setSize(525, 270);
setLocation(500, 280);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
// Label Title
final JLabel lblTitle = new JLabel("Import Data", JLabel.CENTER);
lblTitle.setBounds(61, 24, 370, 14);
getContentPane().add(lblTitle);
// ProgressBar
progressBar = new JProgressBar();
progressBar.setStringPainted(true);
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setBounds(162, 98, 190, 20);
getContentPane().add(progressBar);
// Button Start
btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnStart.setEnabled(false);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BackgroundWorker().execute();
}
});
}
});
btnStart.setBounds(209, 144, 100, 23);
getContentPane().add(btnStart);
// Label File Name
JLabel lblFileName = new JLabel("File Name");
lblFileName.setBounds(99, 70, 57, 14);
getContentPane().add(lblFileName);
// Text File
txtFile = new JTextField();
txtFile.setBounds(162, 67, 182, 20);
getContentPane().add(txtFile);
txtFile.setColumns(10);
// Button Choose
JButton btnChoose = new JButton("...");
btnChoose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fileopen = new JFileChooser();
int ret = fileopen.showDialog(null, "Choose file");
if (ret == JFileChooser.APPROVE_OPTION) {
// Read Text file
txtFile.setText(fileopen.getSelectedFile().toString());
}
}
});
btnChoose.setBounds(354, 66, 26, 23);
getContentPane().add(btnChoose);
}
public class BackgroundWorker extends SwingWorker<Void, Void> {
public BackgroundWorker() {
addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
progressBar.setValue(getProgress());
}
});
}
@Override
protected void done() {
JOptionPane.showMessageDialog(null,
"Import Data Successfully");
btnStart.setEnabled(true);
}
protected Void doInBackground() throws Exception {
// Read Text File
File file = new File(txtFile.getText());
ArrayList<String> myArrList = new ArrayList<String>();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
myArrList.add(line);
}
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Import to Database //
Connection connect = null;
Statement s = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection(""
+ "jdbc:mysql://localhost/mydatabase"
+ "?user=root&password=root");
s = connect.createStatement();
/*** Import ***/
for (int i = 0; i < myArrList.size(); i++) {
// SQL Insert
String sql = "INSERT INTO data "
+ "(DataLine) "
+ "VALUES ('" + myArrList.get(i) + "') ";
s.execute(sql);
setProgress((int)((i*100)/myArrList.size())+1);
Thread.sleep(10);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (s != null) {
s.close();
connect.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
}
}
Output
หน้าจอสำหรับ Import ข้อมูล ให้คลิกที่ Button เพื่อ Browse เลือกไฟล์
แสดง Dialog ให้เลือก Text file ที่มี 1,000 รายการ
หลังจากได้ Text File แล้วให้คลิกที่ Start
โปรแกรมกำลังทำงาน ซึ่งจะแสดงสถานะการทำงาน ตามจำนวนที่ถูก Insert ลงเข้าไปจริง ๆ
ครบ 100% นั้นหมายถึงรายการทั้งหมดถูก Import เรียบร้อยแล้ว
แสดงข้อความว่าทำการ Import เรียบร้อยแล้ว
ใน Database ข้อมูลถูกเพิ่ม 1,000 รายการ
ใน Database ข้อมูลถูกเพิ่ม 1,000 รายการ
เพิ่มเติม ในตัวอย่างนี้มีการใช้ Thread.sleep(10); เข้ามาหน่วงเวลา เพื่อให้เห็นภาพชัดเจน เพราะการทำงานจริง ๆ นั้นโปรแกรมจะทำงานเร็วมาก แต่ถ้าในกรณีที่เราใช้กับ Process อย่างอื่นที่มีทำงานช้าอยู่ในตัวแล้วก็ไม่จำเป็นจะต้องใช้ Thread.sleep(10); เข้ามาช่วย
อ่านเพิ่มเติม : How to use : Java GUI SwingWorker and JProgressBar
กรณีที่ใช้ร่วมกับ Database อื่น ๆ สามารถดูวิธีการใช้ Connector และ Connection String ได้ที่นี่
Property & Method (Others Related) |
|
ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท
|
|
|
By : |
ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ) |
|
Score Rating : |
|
|
|
Create/Update Date : |
2013-09-10 10:07:09 /
2017-03-27 21:57:28 |
|
Download : |
No files |
|
Sponsored Links / Related |
|
|
|
|
|
|
|