简体   繁体   中英

Java with SwingWorker - GUI freezes after button pressed (ProgressBar not working too)

The main idea of my program is to parse XML data from file and insert it into MySQL database using JDBC driver. File conatins 2000 elements and everything works perfectly - file is parsed and data loaded to database. The problem is that when I press button to start it all GUI freeze and the JProgressBarr does not work as it intended. I have no idea why. I used SwingWorker to do thread work. Here is my code:

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);  
            }

        });
    }

}

Change this:

new LoadXmlToDatabase().run();

..to this..

new LoadXmlToDatabase().execute();

GUI freezes in java mostly due to thread problems and in this case i guess its because when the button is clicked or pressed.So try to provide a thread seperate for the button.Try this solution.

public void actionPerformed(ActionEvent e) {

//declare the variables you have (if any)

Thread t = new Thread() {

               @Override

             public void run() {  
                 //write you code here

                }

            };

        t.start();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM