java – 在GUI中处理未处理的异常

我主要为技术精通的人写一个小工具,例如程序员,工程师等等.由于这些工具通常会随着时间的推移而改进,因此我知道将会有未处理的异常,用户不会介意.我希望用户能够向我发送回溯,以便我可以检查发生了什么,并可能改进应用程序.

我通常做wxPython编程,但我最近做了一些Java.我已经把TaskDialog类挂接到Thread.UncaughtExceptionHandler(),我对结果很满意.特别是它可以捕获和处理任何线程的异常:

我在wxPython中做了类似的工作很长一段时间.然而:

>我不得不写一个装饰器,以便能够从另一个线程打印异常.
>即使在功能上,结果也相当丑陋.

这里是Java和wxPython的代码,所以你可以看到我做了什么:

Java的:

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JButton;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import com.ezware.dialog.task.TaskDialogs;

public class SwingExceptionTest {

    private JFrame frame;

    public static void main(String[] args) {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (ClassNotFoundException e) {
        }
        catch (InstantiationException e) {
        }
        catch (illegalaccessexception e) {
        }
        catch (UnsupportedLookAndFeelException e) {
        }

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            public void uncaughtException(Thread t,Throwable e) {
                TaskDialogs.showException(e);
            }
        });

        EventQueue.invokelater(new Runnable() {
            public void run() {
                try {
                    SwingExceptionTest window = new SwingExceptiontest();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printstacktrace();
                }
            }
        });
    }

    public SwingExceptiontest() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100,100,600,400);
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0,0};
        gridBagLayout.rowHeights = new int[]{0,0};
        gridBagLayout.columnWeights = new double[]{0.0,Double.MIN_VALUE};
        gridBagLayout.rowWeights = new double[]{0.0,Double.MIN_VALUE};
        frame.getContentPane().setLayout(gridBagLayout);

        JButton btnNewButton = new JButton("Throw!");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                onButton();
            }
        });
        GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
        gbc_btnNewButton.gridx = 0;
        gbc_btnNewButton.gridy = 0;
        frame.getContentPane().add(btnNewButton,gbc_btnNewButton);
    }

    protected void onButton(){
        Thread worker = new Thread() {
            public void run() { 
                throw new RuntimeException("Exception!");
            }
        };
        worker.start();
    }

}

wxPython的:

import StringIO
import sys
import traceback
import wx
from wx.lib.delayedresult import startWorker


def thread_guard(f):
    def thread_guard_wrapper(*args,**kwargs) :
        try:
            r = f(*args,**kwargs)
            return r
        except Exception:
            exc = sys.exc_info()
            output = StringIO.StringIO()
            traceback.print_exception(exc[0],exc[1],exc[2],file=output)
            raise Exception("<THREAD GUARD>\n\n" + output.getvalue())
    return thread_guard_wrapper

@thread_guard
def thread_func():
    return 1 / 0

def thread_done(result):
    r = result.get()
    print r


class MainWindow(wx.Frame):
    def __init__(self,*args,**kwargs):
        wx.Frame.__init__(self,**kwargs)

        self.panel = wx.Panel(self)
        self.button = wx.Button(self.panel,label="Throw!")
        self.button.Bind(wx.EVT_BUTTON,self.OnButton)

        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.button)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()

    def OnButton(self,e):
        startWorker(thread_done,thread_func)

app = wx.App(True)
win = MainWindow(None,size=(600,400))
app.MainLoop()

现在的问题:

我可以轻松地做一些类似于wxPython中的Java解决方案的东西吗?或者也许,在Java或wxPython中有更好的方法吗?

解决方法

在Python中,您可以将sys.execpthook设置为要为未捕获异常调用函数.那么你不需要装饰器,你可以在钩子函数中集中处理异常.

而不只是打印异常追溯文本,并让它显示在股票stdout窗口中,您可以使用它更智能,例如使用对话框显示文本,并具有允许用户错误信息发送回的控件开发人员,忽略未来的错误,重新启动应用程序,或任何您想要的.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...