简体   繁体   English

取消文件打开对话框后的InterruptedException - 1.6.0_26

[英]InterruptedException after cancel file open dialog - 1.6.0_26

The output from the code that follows is: 以下代码的输出是:

java.vendor     Sun Microsystems Inc.
java.version    1.6.0_26
java.runtime.version    1.6.0_26-b03
sun.arch.data.model     32
os.name     Windows XP
os.version  5.1
os.arch     x86
Input selection cancelled by user.
Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    at sun.java2d.Disposer.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

The following code shows the exception on my machine. 以下代码显示了我的计算机上的异常。

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

public class GUI extends JPanel implements ActionListener {

    private final String newline = System.getProperty("line.separator");
    JButton openButton;
    JTextArea log;
    JFileChooser fc;

    public GUI() {
        super(new BorderLayout());

        log = new JTextArea(20,40);
        log.setMargin(new Insets(5,5,5,5));
        log.setEditable(false);

        fc = new JFileChooser();

        openButton = new JButton("Open");
        openButton.addActionListener(this);

        JPanel buttonPanel = new JPanel(); //use FlowLayout
        buttonPanel.add(openButton);

        add(buttonPanel, BorderLayout.NORTH);
        add(new JScrollPane(log));

        showProp("java.vendor");
        showProp("java.version");
        showProp("java.runtime.version");
        showProp("sun.arch.data.model");
        showProp("os.name");
        showProp("os.version");
        showProp("os.arch");
    }

    public void showProp(String name) {
        output(name + " \t" + System.getProperty(name));
    }

    public void output(String msg) {
        log.append(msg + newline);
        log.setCaretPosition(log.getDocument().getLength());
        System.out.println(msg);
    }

    public void actionPerformed(ActionEvent e) {
        //Handle open button action.
        int returnVal = fc.showOpenDialog(GUI.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            //This is where a real application would open the file.
            output(
                "Input File Selected: " +
                fc.getSelectedFile().getName() +
                ".");

        } else {
            output("Input selection cancelled by user.");
        }
        log.setCaretPosition(log.getDocument().getLength());
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("IDE Output Converter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Add content to the window.
        frame.add(new GUI());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

When I run the program the main window opens fine and the program works fine. 当我运行程序时,主窗口打开正常,程序工作正常。

However, if you: 但是,如果你:

  • open the the JFileChooser using the 'Open File' button 使用“打开文件”按钮打开JFileChooser
  • press cancel and then 按取消然后再按
  • exit the program 退出程序

An InterruptedException is thrown. 抛出InterruptedException Or if you choose a file and 'Open' it then exit the program the same error is thrown. 或者,如果您选择一个文件并“打开”它然后退出程序,则会抛出相同的错误。 On this blog the same thing is explained with example code, his solution is to call new JFileChooser(); 在这个博客上 ,同样的事情用示例代码解释,他的解决方案是调用new JFileChooser(); as soon as possible, which I have done to no effect. 尽快,我已经做了什么没有效果。

Is this a bug in 1.6.0_26? 这是1.6.0_26中的错误吗? If so, is there a work-around for that version? 如果是这样,该版本是否有解决方法?

Is it the code? 这是代码吗? If so, how to fix it? 如果是这样,如何解决? (Looking less likely, with 2 other null results - one of which is now deleted.) (看起来不太可能,另外两个空结果 - 其中一个现在被删除了。)

I would say this is a small bug in sun.awt.Disposer . 我会说这是sun.awt.Disposer一个小错误。

That class creates the "Java2D Disposer" daemon thread which handles disposing AWT resources of garbage collected objects (mainly AWT windows). 该类创建“Java2D Disposer”守护程序线程,该线程处理处理垃圾收集对象(主要是AWT窗口)的AWT资源。 Most of the time that thread waits on its reference queue for a new disposable object to be garbage collected. 大多数情况下,线程在其引用队列上等待新的一次性对象被垃圾收集。 When the thread is interrupted it explicitly prints that exception. 当线程被中断时,它会显式地打印该异常。

When the JVM is terminated it interrupts all threads. 当JVM终止时,它会中断所有线程。 Under some circumstances - which are apparently influenced by the usage of JFileChooser and the subsystems initialized by it - some threads still get a chance to run after this interruption. 在某些情况下 - 显然受到JFileChooser的使用和由其初始化的子系统的影响 - 一些线程仍然有机会在此中断后运行。 And in this case an InterruptedException is thrown in the "Java2D Disposer" thread because it was waiting on a lock. 在这种情况下,在“Java2D Disposer”线程中抛出InterruptedException ,因为它正在等待锁定。 It would be better if it ignored that exception during shutdown. 如果在关机期间忽略该异常会更好。

As a workaround, replace 作为解决方法,替换

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

with

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosed(WindowEvent e) {
        PrintStream nullStream = new PrintStream(new OutputStream() {
            public void write(int b) throws IOException {
            }

            public void write(byte b[]) throws IOException {
            }

            public void write(byte b[], int off, int len) throws IOException {
            }
        });
        System.setErr(nullStream);
        System.setOut(nullStream);
        System.exit(0);
    }
});

I had a similar issue. 我有一个类似的问题。 I fixed it following the advice from this thread 我按照这个帖子的建议修复了它

My output for a slightly altered version of your source (now included as an edit to the question itself) is.. 我的输出略有改动的源代码版本(现在作为对问题本身的编辑包含在内)是..

java.vendor     Sun Microsystems Inc.
java.version    1.6.0_29
java.runtime.version    1.6.0_29-b11
sun.arch.data.model     32
os.name         Windows 7
os.version      6.1
os.arch         x86
Input File Selected: install.ini.
Input selection cancelled by user.
Press any key to continue . . .

From your question it seems the important line is: 从您的问题来看,似乎重要的是:

Input selection cancelled by user.

But after that I see no InterruptedException in the output. 但之后我在输出中看不到InterruptedException

The difference I saw between the code in the blog post is the scope of the JFileChooser. 我在博客文章中的代码之间看到的差异是JFileChooser的范围 In the blog post the object is a local variable within the onClickedButton function. 在博客文章中,对象是onClickedButton函数中的局部变量 In your example the object is defined at the class level . 在您的示例中,对象是在类级别定义的。 I assume being a local variable gives the Disposer thread more time to clear the JFileChooser object. 我假设作为局部变量为Disposer线程提供了更多时间来清除JFileChooser对象。

When I made the the file chooser object a local variable in the actionPerformed method block in your example, the exception did not occur. 当我在示例中的actionPerformed方法块中将文件选择器对象设置为局部变量时,未发生异常。 I did test it around ten times, Both running the application through eclipse and through the command line. 我测试了大约十次,都通过eclipse和命令行运行应用程序。 The exception did not occur. 没有发生例外。

If the exception still occurs, you can initializing a file chooser object in the constructor of GUI but not assigning it to anything . 如果异常仍然发生,您可以在GUI的构造函数中初始化文件选择器对象,但不能将其分配给任何内容 I assume here it acts as an early initialization and disposal of a heavy weight swing object. 我在这里假设它充当了重型摆动物体的早期初始化和处理。

Hope this helps. 希望这可以帮助。

Try to add a System.gc() call when done with JFileChooser. 尝试使用JFileChooser时添加System.gc()调用。 I had some problems with file locks that this call fixed. 这个调用修复了文件锁的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM