Java线程崩溃,但Swing仍在工作
对于XLSX文件中的某些单元格,rt.GetFontatinex(i)部分只是崩溃,控件只是退出函数,甚至调用函数。不过,外旋式车窗仍开着。我不知道为什么毫无例外的控制会失控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 ==
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。因此,您需要查看