捕获位于不同类中的 SwingWorker 抛出的异常 [英] Catch Exception thrown by a SwingWorker located in a different class

查看:24
本文介绍了捕获位于不同类中的 SwingWorker 抛出的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主类 Gui 来处理我的 GUI 并调用一些放在它们自己的类中的 SwingWorkers(调用 DB 和其他数据源)TablesDataManager.我的问题是,当其中一个摇摆工人在其 done90 方法中(即在 EDT 上)抛出异常时,我希望能够在主类中以某种方式捕获它并采取相应措施(调用 showErrorAndExit 在下面是我的 SSCCE).

I have a main class Gui that handles my GUI and calls a few SwingWorkers (calls to DB and other data sources) that have been put in their own class TablesDataManager. My issue is that when one of those swingworkers throws an exception within its done90 method (i.e. on the EDT), I want to be able to catch it somehow in the main class and act accordingly (call showErrorAndExit in my SSCCE below).

欢迎提出任何想法.

Gui.java

import java.awt.event.WindowEvent;
import javax.swing.*;

public class Gui extends JFrame {

    private final JLabel waitLabel = new JLabel();
    private final JPanel panel = new JPanel();
    private final TablesDataManager tblData = new TablesDataManager();

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                createAndShowGui();
            }
        });
    }

    private static void createAndShowGui() {
        Gui frame = new Gui("My Great GUI");
        frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public Gui(String title) {
        super(title);
        panel.add(waitLabel);
        setContentPane(panel);
        try {
            initData();
        } catch (Exception e) {
            showErrorAndExit(e);
        }
    }

    //I WANT TO CALL THIS METHOD IF done() THROWS AN EXCEPTION
    private void showErrorAndExit(Exception e) {
        JOptionPane.showMessageDialog(this,
                "An unexpected error occured while initialising the tables. The application will close.\n"
                + (e.getMessage() == null ? "" : e.getMessage()),
                "Unrecoverable error",
                JOptionPane.ERROR_MESSAGE);
        this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }

    private void initData() {
        waitLabel.setText("Loading Data");
        tblData.initData(new Runnable() {

            public void run() {
                initTables();
            }
        });
    }

    private void initTables() {
        waitLabel.setText("Loading Tables");
        tblData.initTables(new Runnable() {

            public void run() {
                finishComponentsSetup();
            }
        });
    }

    private void finishComponentsSetup() {
        waitLabel.setText("We are done");
    }
}

TablesDataManager.java

TablesDataManager.java

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;

class TablesDataManager {

    private final InitData initData = new InitData();
    private final InitTables initTables = new InitTables();

    void initData(final Runnable runAfterInit) {
        launchWorker(initData, runAfterInit);
    }

    void initTables(final Runnable runAfterInit) {
        launchWorker(initTables, runAfterInit);
    }

    private void launchWorker(final SimpleSwingWorker worker, final Runnable runAfterWorkerDone) {
        worker.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals("progress")) {
                    if (worker.getProgress() == 100) { //update finished
                        runAfterWorkerDone.run();
                    }
                }
            }
        });
        worker.execute();
    }

    private class InitData extends SimpleSwingWorker {

        @Override
        protected Void doInBackground() throws Exception {
            //do something in the background
            //unfortunately there is a connection problem
            throw new IOException("Can't connect to database...");
        }
    }

    private class InitTables extends SimpleSwingWorker {

        @Override
        protected Void doInBackground() throws Exception {
            //do something else in the background
            return null;
        }
    }


    private abstract class SimpleSwingWorker extends SwingWorker<Void, Void>  {

        @Override
        protected abstract Void doInBackground() throws Exception;

        @Override
        public void done() {
            try {
                get();
                setProgress(100);
            } catch (ExecutionException | InterruptedException e) {
                System.out.println("Got that?");
                //WHAT DO I DO WITH IT???
                throw new RuntimeException(e);
            }
        }
    }
}

推荐答案

在您的 GUI 中保留对您的工作人员的引用,并在您的工作中添加一个 try catch.在 catch 中,将异常分配给一个变量并为其添加一个 getter.在您的 GUI 中,当您的工作人员完成后,只需检查工作人员中是否有异常.

Keep a reference to your workers in your GUI and in your workes add a try catch. In the catch assign the exception to a variable and add a getter to it. IN your GUI, when your worker is done, just check if there is an exception in the worker or not.

这篇关于捕获位于不同类中的 SwingWorker 抛出的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆