1

使用 Better Swing 应用程序框架 (BSAF) 运行 Java 应用程序,如果我在程序启动后尝试打开与数据库的连接,它就会停止。如果我碰巧在启动前运行了连接,它就可以正常工作。就我而言,没有解决方法,因为我要求用户主动打开和关闭连接。

以下代码是发生的事情的示例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.EventObject;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.jdesktop.application.Action;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.Task;

public class BsafConnection extends SingleFrameApplication {

    private static final String DB_URL = ""; // A proper URL
    private static final String DRIVER = ""; // A proper driver
    private static Connection CONNECTION;

    public BsafConnection() {
        super();

        addExitListener(new ExitListener() {
            @Override
            public boolean canExit(EventObject event) {
                return true;
            }
            @Override
            public void willExit(EventObject event) {
                if (CONNECTION != null) {
                    try {
                        CONNECTION.close();
                        System.out.println("Connection closed");
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("Connection was not open");
                }
            }});
    }

    @Override
    protected void startup() {
    }

    @Override
    public void ready() {
        JPanel panel = new JPanel();
        panel.add(new JButton(getContext().getActionMap().get("connect")));
        panel.add(new JButton("Press here to check that the EDT is not blocked"));
        show(panel);
    }

    @Action
    public Task<?, ?> connect() {
        return new Task<Object, Object> (this) {
            @Override
            protected Object doInBackground() throws Exception {
                javax.swing.Action action = getContext().getActionMap().get("connect");
                action.putValue(javax.swing.Action.NAME, "Connecting...");
                openConnection(); // Placing the connection here makes the application stall

                action.putValue(javax.swing.Action.NAME, "Connected!");
                return null;
            }};
    }

    public static void openConnection() {
        try {
            Class.forName(DRIVER);

            CONNECTION = DriverManager.getConnection(DB_URL); // This instruction stalls when called after launch()
            System.out.println("Connection open");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String... args) {
//        openConnection(); // Here, the connection would work but is not the desired place 
        launch(BsafConnection.class, args);
    }

}

我正在使用 Windows 环境,如果这可能是某种问题的话。恐怕这可能与 BSAF 使用 EDT 运行应用程序的方式有关,或者与ClassLoader. 只是为了澄清:阻塞 EDT 不是问题,它工作正常,问题是指令DriverManager.getConnection(DB_URL);卡住并且没有抛出异常。

编辑:我刚刚发现,如果我碰巧在启动之前打开了一个连接,我以后可以正确打开它们。

编辑 2:添加了一个更具解释性的示例代码。

编辑 3:关于可能原因的澄清信息

4

1 回答 1

1

看起来您的连接正在阻塞事件调度线程。您应该在另一个线程中处理它,例如SwingWorker.

编辑:我不确定为什么Task/SwingWorker不起作用,但您可能会在BASF 论坛上查看该主题

于 2013-10-29T11:02:08.177 回答