1

XLSX ファイル rt.getFontAtIndex(i) の一部のセルでは、部分がクラッシュし、制御が関数を終了し、関数を呼び出すことさえあります。Out Swing ウィンドウはまだ開いています。例外がなければコントロールがコードの外に出る理由はわかりません。

    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;
    }
4

2 に答える 2

2

XSSFRichTextString.getFontAtIndex() のドキュメントによると、XSSFFont を返すか、フォントが適用されていない場合やインデックスが範囲外の場合は null が返されます。そのため、(System.out.print 呼び出しを含めて) 使用する前に、戻り値が null かどうかを確認する必要があります。そうしないと、NullPointerException が発生し、制御がコード ブロックから離れてしまいます。

また、Error をキャッチしても役に立たないことに注意してください。NPE は RuntimeException であり、Error のサブクラスではないため、try/catch ブロックでキャッチされません。いくつかの例外 (しゃれは意図していません) を除いて、チェックされていない例外をキャッチしようとするのではなく、適切なチェックをコードに入れる必要があります (返された参照が null でないことを確認する、配列の長さに対してインデックスをチェックするなど)。

于 2013-09-10T20:16:32.860 に答える
1

「バックグラウンド スレッドがクラッシュしているにもかかわらず、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();
         }
      });
   }
}
于 2013-09-10T20:14:51.867 に答える