-1

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

        });
    }

}
anton86993
  • 638
  • 1
  • 9
  • 26
  • 2
    Do not post so much code. Post an [MCVE] : post the bare minimum to show your issue. If there are more than one problem it would be better to deal with one at a time. (Writing a minimal case is a good debugging technique. In doing so you are likely to solve your problem.) – c0der Oct 30 '16 at 05:12
  • 1
    Please read [MCVE] carefully. The code posted is not one, It is not M (for example if retrieval from database is not the issue, remove it) , it is not C (for example you should not expect a person willing to help to guess what 30+ imports are missing), and it is not V because it can not be compiled and run as is. – c0der Oct 30 '16 at 05:24
  • `for (int i = 0; i < nodeListLength; i++) {` Does the UI still freeze if this loop is removed? When making an MCVE as described by @c0der, **all** unnecessary code should be removed. Only the stuff needed to put the problem on-screen, plus the actual problem code, should be included. – Andrew Thompson Oct 30 '16 at 05:24
  • @c0der *"guess what 30+ imports are missing"* This (excluding imports) is a personal dislike of mine. Including imports allows us to see, at a glance, if third party APIs are used, and makes it explicit what classes and packages are involved. Some argue that the people viewing the code use IDEs to insert imports, but that doesn't account for class names that might be duplicated in 3rd party APIs (or the core Java API, for that matter). – Andrew Thompson Oct 30 '16 at 05:28
  • I've added imports. I'm not a regular visitor here that's why I'm sorry if I don't do some things right. I've tried to cut unnecessary code and leave those which are connected to the problem. – anton86993 Oct 30 '16 at 05:36
  • 1
    @AndrewThompson I think that, (quoting from SO help: http://stackoverflow.com/help/how-to-ask) "Pretend you're talking to a busy colleague" is a good advice. I found that making the effort to remove all redundant code and add what's needed helps anyone to focus on the problem. As I wrote above it a good debugging tool (in addition to showing respect to other people's time) – c0der Oct 30 '16 at 05:37

1 Answers1

4

Change this:

new LoadXmlToDatabase().run();

..to this..

new LoadXmlToDatabase().execute();
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
johnII
  • 1,423
  • 1
  • 14
  • 20