Java 使用 SwingWorker - 按下按钮后 GUI 冻结(ProgressBar 也不起作用)
Java with SwingWorker - GUI freezes after button pressed (ProgressBar not working too)
我的程序的主要思想是从文件中解析 XML 数据并使用 JDBC 驱动程序将其插入到 MySQL 数据库中。文件包含 2000 个元素并且一切正常 - 文件被解析并将数据加载到数据库。问题是,当我按下按钮启动它时,所有 GUI 都冻结并且 JProgressBarr 无法按预期工作。我不知道为什么。我使用 SwingWorker 来做线程工作。这是我的代码:
package javamysqlinsert;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class JavaMySqlInsert extends JFrame implements ActionListener {
private final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private final String DB_URL = "jdbc:mysql://anton869.linuxpl.eu:3306/"
+ "anton869_cars";
private final String DB_USER = "user";
private final String DB_PASSWORD = "user";
private JTextField xmlPathField;
private JButton chooseFileButton, insertDataButton;
private JProgressBar insertProgressBar;
private String filePath;
class LoadXmlToDatabase extends SwingWorker<Void, Void> {
@Override
public Void doInBackground() {
JavaMySqlInsert.this.insertProgressBar.setIndeterminate(true);
loadAndParseXml();
return null;
}
@Override
public void done() {
JavaMySqlInsert.this.insertProgressBar.setIndeterminate(false);
JOptionPane.showMessageDialog(JavaMySqlInsert.this,
"Finished loading data to MySQL database",
"Loading success", JOptionPane.INFORMATION_MESSAGE);
}
private void loadAndParseXml() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(JavaMySqlInsert.this
.filePath));
doc.getDocumentElement().normalize();
System.out.println("Successfully loaded XML file");
fillItemList(doc);
} catch (IOException | ParserConfigurationException
| SAXException e) {
}
}
private void fillItemList(final Document doc) {
try {
System.out.println("Connecting to MySQL database...");
Class.forName(DEFAULT_DRIVER);
Connection conn = DriverManager.getConnection(DB_URL, DB_USER,
DB_PASSWORD);
System.out.println("Connected to MySQL database");
System.out.println("Starting parsing XML document and loading "
+ "it to MySQL database...");
NodeList nodesList = doc.getElementsByTagName("T");
final int nodeListLength = nodesList.getLength();
for (int i = 0; i < nodeListLength; i++) {
Node node = nodesList.item(i);
Element element = (Element) node;
HashMap<String, String> carMap = new HashMap<>();
if (node.getNodeType() == Node.ELEMENT_NODE) {
// <P_NAME>
carMap.put("p_name", element
.getElementsByTagName("P_NAME").item(0)
.getTextContent());
// <P_MFGR>
carMap.put("p_mfgr", element
.getElementsByTagName("P_MFGR").item(0)
.getTextContent());
// <P_BRAND>
carMap.put("p_brand", element
.getElementsByTagName("P_BRAND").item(0)
.getTextContent());
// <P_TYPE>
carMap.put("p_type", element
.getElementsByTagName("P_TYPE").item(0)
.getTextContent());
// <P_SIZE>
carMap.put("p_size", element
.getElementsByTagName("P_SIZE").item(0)
.getTextContent());
// <P_CONTAINER>
carMap.put("p_container", element
.getElementsByTagName("P_CONTAINER").item(0)
.getTextContent());
// <P_RETAILPRICE>
carMap.put("p_retailprice", element
.getElementsByTagName("P_RETAILPRICE").item(0)
.getTextContent());
// <P_COMMENT>
carMap.put("p_comment", element
.getElementsByTagName("P_COMMENT").item(0)
.getTextContent());
}
insertCarInfoRow(conn, carMap);
}
System.out.println("Data have been successfully parsed and "
+ "loaded to MySQL database. Inserted: "
+ nodeListLength + " rows");
} catch (SQLException | ClassNotFoundException e) {
}
}
private void insertCarInfoRow(final Connection conn,
final HashMap<String, String> carMap) {
final String insertQuery = "INSERT INTO part (p_name, p_mfgr, "
+ "p_brand, p_type, p_size, p_container, p_retailprice, "
+ "p_comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement ps = conn.prepareStatement(insertQuery)) {
ps.setString(1, carMap.get("p_name"));
ps.setString(2, carMap.get("p_mfgr"));
ps.setString(3, carMap.get("p_brand"));
ps.setString(4, carMap.get("p_type"));
ps.setInt(5, Integer.parseInt(carMap.get("p_size")));
ps.setString(6, carMap.get("p_container"));
ps.setFloat(7, Float.parseFloat(carMap.get("p_retailprice")));
ps.setString(8, carMap.get("p_comment"));
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
}
}
}
public JavaMySqlInsert() {
setBasicProperties();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(this.insertDataButton)) {
if (testInternetConnection("google.com")) {
new LoadXmlToDatabase().run();
} else JOptionPane.showMessageDialog(this,
"You have no Internet connection", "Network error",
JOptionPane.ERROR_MESSAGE);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JavaMySqlInsert jmsqli = new JavaMySqlInsert();
jmsqli.setLocationRelativeTo(null);
jmsqli.setVisible(true);
}
});
}
}
改变这个:
new LoadXmlToDatabase().run();
..到这个..
new LoadXmlToDatabase().execute();
我的程序的主要思想是从文件中解析 XML 数据并使用 JDBC 驱动程序将其插入到 MySQL 数据库中。文件包含 2000 个元素并且一切正常 - 文件被解析并将数据加载到数据库。问题是,当我按下按钮启动它时,所有 GUI 都冻结并且 JProgressBarr 无法按预期工作。我不知道为什么。我使用 SwingWorker 来做线程工作。这是我的代码:
package javamysqlinsert;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class JavaMySqlInsert extends JFrame implements ActionListener {
private final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
private final String DB_URL = "jdbc:mysql://anton869.linuxpl.eu:3306/"
+ "anton869_cars";
private final String DB_USER = "user";
private final String DB_PASSWORD = "user";
private JTextField xmlPathField;
private JButton chooseFileButton, insertDataButton;
private JProgressBar insertProgressBar;
private String filePath;
class LoadXmlToDatabase extends SwingWorker<Void, Void> {
@Override
public Void doInBackground() {
JavaMySqlInsert.this.insertProgressBar.setIndeterminate(true);
loadAndParseXml();
return null;
}
@Override
public void done() {
JavaMySqlInsert.this.insertProgressBar.setIndeterminate(false);
JOptionPane.showMessageDialog(JavaMySqlInsert.this,
"Finished loading data to MySQL database",
"Loading success", JOptionPane.INFORMATION_MESSAGE);
}
private void loadAndParseXml() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(JavaMySqlInsert.this
.filePath));
doc.getDocumentElement().normalize();
System.out.println("Successfully loaded XML file");
fillItemList(doc);
} catch (IOException | ParserConfigurationException
| SAXException e) {
}
}
private void fillItemList(final Document doc) {
try {
System.out.println("Connecting to MySQL database...");
Class.forName(DEFAULT_DRIVER);
Connection conn = DriverManager.getConnection(DB_URL, DB_USER,
DB_PASSWORD);
System.out.println("Connected to MySQL database");
System.out.println("Starting parsing XML document and loading "
+ "it to MySQL database...");
NodeList nodesList = doc.getElementsByTagName("T");
final int nodeListLength = nodesList.getLength();
for (int i = 0; i < nodeListLength; i++) {
Node node = nodesList.item(i);
Element element = (Element) node;
HashMap<String, String> carMap = new HashMap<>();
if (node.getNodeType() == Node.ELEMENT_NODE) {
// <P_NAME>
carMap.put("p_name", element
.getElementsByTagName("P_NAME").item(0)
.getTextContent());
// <P_MFGR>
carMap.put("p_mfgr", element
.getElementsByTagName("P_MFGR").item(0)
.getTextContent());
// <P_BRAND>
carMap.put("p_brand", element
.getElementsByTagName("P_BRAND").item(0)
.getTextContent());
// <P_TYPE>
carMap.put("p_type", element
.getElementsByTagName("P_TYPE").item(0)
.getTextContent());
// <P_SIZE>
carMap.put("p_size", element
.getElementsByTagName("P_SIZE").item(0)
.getTextContent());
// <P_CONTAINER>
carMap.put("p_container", element
.getElementsByTagName("P_CONTAINER").item(0)
.getTextContent());
// <P_RETAILPRICE>
carMap.put("p_retailprice", element
.getElementsByTagName("P_RETAILPRICE").item(0)
.getTextContent());
// <P_COMMENT>
carMap.put("p_comment", element
.getElementsByTagName("P_COMMENT").item(0)
.getTextContent());
}
insertCarInfoRow(conn, carMap);
}
System.out.println("Data have been successfully parsed and "
+ "loaded to MySQL database. Inserted: "
+ nodeListLength + " rows");
} catch (SQLException | ClassNotFoundException e) {
}
}
private void insertCarInfoRow(final Connection conn,
final HashMap<String, String> carMap) {
final String insertQuery = "INSERT INTO part (p_name, p_mfgr, "
+ "p_brand, p_type, p_size, p_container, p_retailprice, "
+ "p_comment) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement ps = conn.prepareStatement(insertQuery)) {
ps.setString(1, carMap.get("p_name"));
ps.setString(2, carMap.get("p_mfgr"));
ps.setString(3, carMap.get("p_brand"));
ps.setString(4, carMap.get("p_type"));
ps.setInt(5, Integer.parseInt(carMap.get("p_size")));
ps.setString(6, carMap.get("p_container"));
ps.setFloat(7, Float.parseFloat(carMap.get("p_retailprice")));
ps.setString(8, carMap.get("p_comment"));
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
}
}
}
public JavaMySqlInsert() {
setBasicProperties();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(this.insertDataButton)) {
if (testInternetConnection("google.com")) {
new LoadXmlToDatabase().run();
} else JOptionPane.showMessageDialog(this,
"You have no Internet connection", "Network error",
JOptionPane.ERROR_MESSAGE);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JavaMySqlInsert jmsqli = new JavaMySqlInsert();
jmsqli.setLocationRelativeTo(null);
jmsqli.setVisible(true);
}
});
}
}
改变这个:
new LoadXmlToDatabase().run();
..到这个..
new LoadXmlToDatabase().execute();