Home > Enterprise >  Unable to terminate a thread
Unable to terminate a thread

Time:03-27

I am trying to present a splash screen during application initialization in a new thread so that processing can continue in the main thread. The screen is presented but the thread does not stop when told to terminate by the main thread. I have tried using a volatile boolean flag and the interrupt() method, neither of which stops the thread.

Here's what I have so far:

Main thread

        startScreen = new StartScreen("Loading Resume Builder");
        Thread splashThread = new Thread(startScreen);
        
        splashThread.start();
        
        loadDB();
        splashThread.interrupt();

new thread

public class StartScreen extends JFrame
        implements Runnable {
    
    private static volatile boolean exit;

    /**
     * Creates new form StartScreen
     *
     * @param status
     * @throws java.io.IOException
     */
    public StartScreen(String status) throws IOException {
        initComponents();
        setupFrame(status);
    }

    /**
     * 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() {

        imageLabel = new javax.swing.JLabel();
        statusLabel = new javax.swing.JLabel();

        setAlwaysOnTop(true);
        setMaximumSize(new java.awt.Dimension(400, 300));
        setMinimumSize(new java.awt.Dimension(400, 300));
        setPreferredSize(new java.awt.Dimension(640, 371));

        statusLabel.setName(""); // NOI18N
        statusLabel.setOpaque(true);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusLabel)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addComponent(imageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(imageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 369, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(statusLabel)
                .addGap(16, 16, 16))
        );

        imageLabel.getAccessibleContext().setAccessibleName("");
    }// </editor-fold>                        

    private void setupFrame(String status) throws IOException {
        setUndecorated(true);
        setLocationRelativeTo(null);
        
        ImageIcon imageIcon = new ImageIcon("E:\\Users\\flash\\Documents\\"
                  "NetBeansProjects\\ResumeBuilder\\"
                  "career-g5c3a164de_640.jpg");
        imageLabel.setIcon(imageIcon);
        imageLabel.setOpaque(false);
        imageLabel.setSize(new Dimension(395, 250));
        
        this.getContentPane().add(imageLabel);
        
        setStatus(status);
        statusLabel.setLocation(new Point(10, 275));
        this.add(statusLabel);
        
        setVisible(true);
    }
    
    public void setStatus(String status) {
        statusLabel.setText(status);
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel imageLabel;
    private javax.swing.JLabel statusLabel;
    // End of variables declaration                   

    @Override
    public synchronized void run() {
        if (!Thread.currentThread().isInterrupted()) {
            
        } else {
            setVisible(false);
            repaint();
        }
    }
    
    public static void close() {
        exit = true;
    }
}

CodePudding user response:

You might consider saving yourself writing code for splash screen by using the default Java splash screen parameter. Just add -splash:/somepathto/splash.jpg to your java command line and the splash screen will be presented at JVM startup.

Your application can cancel the default splash screen at an appropriate moment by inserting a call to:

/**
 * Closes splash screen if JVM startup parameter used:
 *    JAVA.EXE -splash:"/somepath/splash.jpg" ...
 */
public static void closeSplash() {
    SplashScreen ss = SplashScreen.getSplashScreen();
    if (ss != null) {
        ss.close();
    }
}

If you don't cancel the splashscreen, it will linger in the background until JVM exits.

CodePudding user response:

The post by DuncG is the solution I went with. It's clean and easy to implement.

  • Related