Java线程崩溃,但Swing仍在工作

Java线程崩溃,但Swing仍在工作,java,swing,apache-poi,Java,Swing,Apache Poi,对于XLSX文件中的某些单元格,rt.GetFontatinex(i)部分只是崩溃,控件只是退出函数,甚至调用函数。不过,外旋式车窗仍开着。我不知道为什么毫无例外的控制会失控 public static String addLinkTagInRichTextForUnderscores(XSSFRichTextString rt) { System.out.print("Was here 1\n"); if(rt.length()==0 || rt ==

对于XLSX文件中的某些单元格,rt.GetFontatinex(i)部分只是崩溃,控件只是退出函数,甚至调用函数。不过,外旋式车窗仍开着。我不知道为什么毫无例外的控制会失控

    public static String addLinkTagInRichTextForUnderscores(XSSFRichTextString rt) {
        System.out.print("Was here 1\n");
        if(rt.length()==0 || rt == null) {
            return " ";
        }
        String outString = rt.toString();
        //String finalString = "";
        List<Integer> startIndexListOfUL = new ArrayList<Integer>();

        boolean continuing = false;
        System.out.println(outString +" A "+ rt.length() +"\n\n");

        for(int i=1;i<rt.length();i++) {
            System.out.print("Was here at font "+ i);
            XSSFFont font = null;
            try{
            //font = rt.getFontAtIndex(i);
            } catch(Error e){
                e.fillInStackTrace();
            }
            System.out.print("Was here too" + rt.getFontAtIndex(i));
            if(font!= null) {
                if(XSSFFont.U_SINGLE == font.getUnderline()) {

                    if(!continuing){
                        startIndexListOfUL.add(new Integer(i));
                        continuing = true;
                    }

                }else{
                    continuing = false;
                }
            } else {
                //System.out.println("No font " + i);
            }
        }

        System.out.println(startIndexListOfUL);

        if(startIndexListOfUL.size()==0) {
            //finalString = outString;
            return " ";
        } else {
            int spacing = 0;
            for(int i = 0; i<startIndexListOfUL.size(); i++) {
                outString =     insertStringAt(outString,startIndexListOfUL.get(i) + spacing,"<link>");
                spacing = spacing + 6;
            }
        }

        //just remove redundant <link> tags
        outString = outString.replaceAll("(<link>[\\s]?<link>)", "<link>");
        //System.out.println("Final >>>> " + outString);
        return outString;
    }
公共静态字符串addLinkTaginRichTextFor下划线(XSSFRichTextString rt){
System.out.print(“Was here 1\n”);
如果(rt.length()==0 | | rt==null){
返回“”;
}
String outString=rt.toString();
//字符串finalString=“”;
List startIndexListOfUL=new ArrayList();
布尔连续=假;
System.out.println(outString+“A”+rt.length()+“\n\n”);
对于(int i=1;i如果您的问题是“为什么我的Swing GUI应用程序没有在后台线程崩溃的情况下崩溃?”,那么答案是Swing GUI与其他Java程序没有什么不同。如果您在任何程序中崩溃线程,1)异常不会导致JVM崩溃,并且2)异常信息不会渗透到调用代码中,调用代码将非常高兴地不知道发生了什么

解决方案是在发生这种情况时通知Swing GUI。例如,如果您使用SwingWorker创建后台线程,其
get()
方法将传递SwingWorker的doInBackground方法中可能发生的任何异常。例如:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import javax.swing.*;

public class SwingTest {
   private JPanel mainPanel = new JPanel();
   private JTextField numberField = new JTextField("5x", 5);

   @SuppressWarnings("serial")
   public SwingTest() {
      MyFailAction myFailAction = new MyFailAction();
      numberField.setAction(myFailAction);
      mainPanel.add(new JLabel("String to parse into an int:"));
      mainPanel.add(numberField);
      mainPanel.add(new JButton(myFailAction));
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }

   private class MyFailAction extends AbstractAction {

      public MyFailAction() {
         super("Push to Fail");
         putValue(MNEMONIC_KEY, KeyEvent.VK_P);
      }

      @Override
      public void actionPerformed(ActionEvent arg0) {
         String text = numberField.getText();
         final MySwingWorker mySw = new MySwingWorker(text);
         mySw.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
               if (evt.getPropertyName().equals("state")) {
                  if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
                     try {
                        // **** here I call get() on my SwingWorker ****
                        int value = mySw.get();
                        JOptionPane.showMessageDialog(mainPanel, "value is "
                              + value);
                     } catch (InterruptedException | ExecutionException e) {
                        if (e.getCause() instanceof NumberFormatException) {
                           String message = "A NumberFormatException has occurred when trying to parse \""
                                 + numberField.getText() + "\" to an int\n" +
                                 "Reseting field to \"0\"";
                           JOptionPane.showMessageDialog(mainPanel, message,
                                 "NumberFormatException",
                                 JOptionPane.ERROR_MESSAGE);
                        }

                        StringBuilder sb = new StringBuilder();
                        sb.append(e.getMessage() + "\n");
                        for (StackTraceElement ele : e.getStackTrace()) {
                           sb.append(ele.toString() + "\n");
                        }
                        sb.append("\n");
                        sb.append("*****   Cause:   *****\n");
                        sb.append(e.getCause().getLocalizedMessage());
                        for (StackTraceElement ele : e.getCause()
                              .getStackTrace()) {
                           sb.append(ele.toString() + "\n");
                        }
                        JTextArea textArea = new JTextArea(sb.toString());
                        JScrollPane message = new JScrollPane(textArea);
                        JOptionPane.showMessageDialog(mainPanel, message,
                              "Error Specifics", JOptionPane.ERROR_MESSAGE);
                        numberField.setText("0");
                     }
                  }
               }
            }
         });
         mySw.execute();
      }
   }

   private class MySwingWorker extends SwingWorker<Integer, Void> {
      private static final long SLEEP_DELAY = 1000;
      private String text;

      public MySwingWorker(String text) {
         this.text = text;
      }

      @Override
      protected Integer doInBackground() throws Exception {
         Thread.sleep(SLEEP_DELAY);
         int value = Integer.parseInt(text);
         return value;
      }
   }

   private static void createAndShowGui() {
      SwingTest swingTest = new SwingTest();

      JFrame frame = new JFrame("SwingTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(swingTest.getMainPanel());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.util.concurrent.ExecutionException;
导入javax.swing.*;
公开课摇摆测试{
private JPanel mainPanel=new JPanel();
私有JTextField numberField=新JTextField(“5x”,5);
@抑制警告(“串行”)
公共SwingTest(){
MyFailAction MyFailAction=新建MyFailAction();
numberField.setAction(myFailAction);
添加(新的JLabel(“要解析为int的字符串:”);
主面板。添加(数字字段);
添加(新的JButton(myFailAction));
}
公共JComponent getMainPanel(){
返回主面板;
}
私有类MyFailAction扩展了AbstractAction{
公共行动{
超级(“推送失败”);
putValue(助记符键,KeyEvent.VK\u P);
}
@凌驾
已执行的公共无效操作(操作事件arg0){
String text=numberField.getText();
最终MySwingWorker mySw=新的MySwingWorker(文本);
mySw.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
if(evt.getPropertyName().equals(“状态”)){
if(evt.getNewValue().equals(SwingWorker.StateValue.DONE)){
试一试{
//****我在这里对我的SwingWorker调用get()****
int value=mySw.get();
JOptionPane.showMessageDialog(主面板,“值为”
+价值);
}捕获(中断异常|执行异常e){
if(如getCause()实例的NumberFormatException){
String message=“尝试分析时发生NumberFormatException\”
+numberField.getText()+“\”为整数\n+
将字段重置为“0”;
JOptionPane.showMessageDialog(主面板,消息,
“NumberFormatException”,
JOptionPane.ERROR\u消息);
}
StringBuilder sb=新的StringBuilder();
sb.append(如getMessage()+“\n”);
对于(StackTraceElement元素:e.getStackTrace()){
sb.append(ele.toString()+“\n”);
}
某人附加(“\n”);
某人追加(“****原因:******\n”);
sb.append(例如getCause().getLocalizedMessage());
对于(StackTraceElement元素:e.getCause()
.getStackTrace()){
sb.append(ele.toString()+“\n”);
}
JTextArea textArea=新的JTextArea(sb.toString());
JScrollPane message=新的JScrollPane(textArea);
JOptionPane.showMessageDialog(主面板,消息,
“错误说明”,作业窗格。错误消息);
numberField.setText(“0”);
}
}
}
}
});
mySw.execute();
}
}
私有类MyWingWorker扩展SwingWorker{
专用静态最终长睡眠延迟=1000;
私有字符串文本;
公共MySwingWorker(字符串文本){
this.text=文本;
}
@凌驾
受保护的整数doInBackground()引发异常{
线程睡眠(睡眠延迟);
int value=Integer.parseInt(文本);
返回值;
}
}
私有静态void createAndShowGui(){
SwingTest SwingTest=新的SwingTest();
JFrame=新JFrame(“SwingTest”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(swingTest.getMainPanel());
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}

XSSFRichTextString.getFontatinex()的文档说明,如果未应用字体或索引超出范围,它将返回XSSFFont,或者返回null。因此,您需要查看