All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.util.WatchedProcess Maven / Gradle / Ivy

There is a newer version: 7.6.6
Show newest version
package edu.cmu.tetradapp.util;

import edu.cmu.tetrad.util.TetradLogger;
import edu.cmu.tetradapp.Tetrad;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

/**
 * Runs a long process, watching it with a thread and popping up a Stop button that the user can click to stop the
 * process.
 * 

* Replacement for the old WatchedProcess, which called the deprecated Thread.stop() method. This method is deprecated * because it can leave the program in an inconsistent state. This class uses Thread.interrupt() instead, which is the * recommended way to stop a thread. *

* Example usage: *

 * class MyWatchedProcess extends WatchedProcess {
 *
 *     @Override
 *     public void watch() throws InterruptedException {
 *         // Long process...
 *     }
 * };
 *
 * new MyWatchedProcess();
 * 
* * @author josephramsey * @author ChatGPT */ public abstract class WatchedProcess { private final JFrame frame; private Thread longRunningThread; private JDialog dialog; /** * Constructor. */ public WatchedProcess() { // Get the Tetrad frame. frame = Tetrad.frame; if (frame == null) { throw new RuntimeException("Tetrad frame is null. Cannot create WatchedProcess."); } startLongRunningThread(); } private void positionDialogAboveFrameCenter(JFrame frame, JDialog dialog) { // Calculate the new position for the dialog Point newDialogPosition = new Point( frame.getX() + frame.getWidth() / 2 - dialog.getWidth() / 2, // Centered horizontally frame.getY() + frame.getHeight() / 2 - dialog.getHeight() / 2 // Centered vertically ); // Set the dialog's new position dialog.setLocation(newDialogPosition); } /** * This is the method that will be called in a separate thread. It should be a long-running process that can be * interrupted by the user. * * @throws InterruptedException if the process is interrupted while running. */ public abstract void watch() throws InterruptedException; private void startLongRunningThread() { longRunningThread = new Thread(() -> { try { watch(); } catch (InterruptedException e) { TetradLogger.getInstance().forceLogMessage("Thread was interrupted while watching. Stopping..."); } catch (Exception e) { TetradLogger.getInstance().forceLogMessage("Exception while watching: " + e.getMessage()); } if (dialog != null) { SwingUtilities.invokeLater(() -> dialog.dispose()); } }); showStopDialog(); longRunningThread.start(); } private void showStopDialog() { dialog = new JDialog(frame, "Stop Process", Dialog.ModalityType.APPLICATION_MODAL); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setUndecorated(true); dialog.setSize(200, 50); dialog.setResizable(false); dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); frame.addComponentListener(new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { if (dialog != null) { positionDialogAboveFrameCenter(frame, dialog); } } }); JButton stopButton = new JButton("Processing (click to stop)..."); stopButton.addActionListener(e -> { if (longRunningThread != null) { SwingUtilities.invokeLater(() -> longRunningThread.interrupt()); } if (dialog != null) { SwingUtilities.invokeLater(() -> dialog.dispose()); } }); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.BLACK, Color.BLACK)); panel.add(stopButton); dialog.getContentPane().add(panel); positionDialogAboveFrameCenter(frame, dialog); SwingUtilities.invokeLater(() -> dialog.setVisible(true)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy