2013-10-29 117 views
1

使用Better Swing應用程序框架(BSAF)運行Java應用程序,如果我曾嘗試在程序啓動時嘗試打開與數據庫的連接,則會停滯。如果我碰巧在啓動之前運行連接,它會正常工作。在我的情況下,沒有解決方法,因爲我需要用戶主動打開和關閉連接。BSAF檔位打開數據庫連接

下面的代碼是發生了什麼

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運行應用程序的方式有關。 只是爲了澄清:阻止美國東部時間並不是一個問題,它的工作正常,事情是指令DriverManager.getConnection(DB_URL);卡住並引發異常。

編輯:我剛剛發現,如果我在啓動之前打開連接,我可以在以後正確打開它們。

編輯2:增加了一個更具解釋性的示例代碼。

編輯3:澄清有關可能的原因

回答

1

它看起來像你的連接阻塞事件調度線程信息。你應該在另一個線程中處理它,如SwingWorker

編輯:我不確定爲什麼Task/SwingWorker不起作用,但你可以在topic上查看BASFforum

+0

嘗試過了,它不工作:使用'SwingUtilities.invokeLater(...)'或者使用框架的'Task',這是一個內部的'SwingWorker'。這個例子很簡單,這就是爲什麼它阻止了EDT(在真正的實現中沒有被阻塞,因爲它在'Task'內處理),但真正的問題沒有被阻塞,這是連接永遠不會發生。 –

+0

對不起,我不明白「連接永遠不會發生。」你的意思是'openConnection()'永遠不會被調用,或者它阻止了EDT? –

+0

兩者都不是:問題是指令'DriverManager.getConnection(DB_URL)'在應用程序啓動後總是被阻止。我將重寫這個例子來澄清問題。 –

相關問題