0

I have a main GUI interface that freezes when the app is doing some database checks with jdbc driver. My idea then was to start a thread that would create a new "loading" jpanel to keep user informed on status of the operations being done by the app. The problem is that this is not working. The loading jpanel is stuck the same.

Would you please be able to let me know the best way to do what I am trying to do or highlight what is wrong below?

Thanks a lot. Here are my classes:

Method on the main GUI that causes app to freeze:

private void snapshotOldVariables() {


    LoadingThread loadingThread = new LoadingThread();
    loadingThread.start();

    loadingThread.updateStatus("Creating snapshot of values...");

    // find selected inventory items on the main arraylist tableRows
    for (int i = 0; i < selectedItems.length; i++) {
        for (InventoryVO r : tableRows) {
            if (r.getMake().equals(selectedItems[i][0]) && r.getModel().equals(selectedItems[i][1]) && r.getSerial().equals(selectedItems[i][2])) {
                tableRowIndexes[i] = tableRows.indexOf(r);
            }
        }
    }

    for (int i = 0; i < selectedItems.length; i++) {
        productIds[i] = db.getAssetId(selectedItems[i][0], selectedItems[i][1]);
        oldLocationIds[i] = db.getLocationIdOfInventoryItem(productIds[i], selectedItems[i][2]);
        oldStatusIds[i] = db.getStatusId(tableRows.get(tableRowIndexes[i]).getStatus());
    }

    loadingThread.updateStatus("Complete");
    loadingThread.dispose();
}

Loading thread:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.app.main;

import com.app.panels.LoadingJPanel;
import java.awt.Dimension;
import javax.swing.JFrame;

/**
 *
 * @author myself
 */
public class LoadingThread extends Thread {

    JFrame loadingJFrame = null;
    LoadingJPanel loadingJPanel = null;

    @Override
    public void run() {

        loadingJFrame = new JFrame();
        loadingJPanel = new LoadingJPanel(loadingJFrame);

        Dimension d = new Dimension();
        d.setSize(500, 500);
        loadingJFrame.setResizable(false);
        loadingJFrame.setMinimumSize(d);
        loadingJFrame.setTitle("Loading...");
        loadingJFrame.setLocationRelativeTo(null);
        loadingJFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        loadingJFrame.add(loadingJPanel);
        loadingJFrame.setVisible(true);

    }

    public void updateStatus(String newStatus) {
        boolean tryUpdate = true;
        while (tryUpdate) {
            if (loadingJPanel != null) {
                loadingJPanel.updateStatus(newStatus);
                tryUpdate = false;
            }
        }
    }

    public void dispose() {
        boolean tryDispose = true;
        while (tryDispose) {
            if (loadingJFrame != null) {
                loadingJFrame.dispose();
                tryDispose = false;
            }
        }
    }

}

Loading JPanel:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.app.panels;

import javax.swing.JFrame;

/**
 *
 * @author myself
 */
public class LoadingJPanel extends javax.swing.JPanel {

    public String currentStatus = "";

    /**
     * Creates new form LoadingJPanel
     */
    public LoadingJPanel(JFrame loadingJFrame) {
        initComponents();
    }

    public void updateStatus (String newStatus) {
        currentStatus += " Done\n" + newStatus;
        jTextAreaLoading.setText(currentStatus);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextAreaLoading = new javax.swing.JTextArea();

        jLabel1.setText("Status");

        jTextAreaLoading.setEditable(false);
        jTextAreaLoading.setColumns(20);
        jTextAreaLoading.setRows(5);
        jScrollPane1.setViewportView(jTextAreaLoading);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>                        


    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextAreaLoading;
    // End of variables declaration                   
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user1060551
  • 421
  • 2
  • 11
  • 20
  • 4
    You're doing the exact inverse of what you should do. UI updates **must** be done from the event dispatch thread. What needs to be done in a background thread is the long, blocking database work. Please, read https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html – JB Nizet Nov 17 '19 at 20:22
  • 3
    You need to do Swing threading correctly -- long-running non-Swing code needs to be run in the background, but Swing code needs to run on the Swingevent thread, the EDT. You're not doing this. Google "concurrency in Swing" to see how to fix this. – Hovercraft Full Of Eels Nov 17 '19 at 20:22

0 Answers0