2012-12-10 47 views
1

在DbInterface類中,函數openDB()打開與服務器上Oracle數據庫的連接。出於安全原因,用戶必須在程序繼續進行連接之前在JFrame文本區輸入密碼。現在這個Jframe有一個動作偵聽器,它等待用戶輸入密碼並調用OpenDBContinue()方法。Java:如何使用線程等待來自用戶的IO,然後繼續

現在的問題是:openDB()不等待Jframe IO完成並假設數據庫已打開,將控制權返回給調用類(調用openDB()的任何人),然後繼續並開始查詢數據庫顯然失敗!

現在我該如何讓openframe()在Jframe IO上等待完成?這是給你一個想法的代碼。

public void openDB(int inFileInx,String inRemoteDBURLFull) throws FileNotFoundException 
{ 
    if(this.password!=null) 
     try 
     { openDBcontinue(inFileInx,inRemoteDBURLFull); 
     } 
     catch(Exception exp) 
      { DpmLogger.dtlException("SPDBInterfaceException:OpenDB", exp); 
      } 
    else { 
      passwd =  new JFrame(); 
      passwd.setLocation(SpdMain.bTabbedPanel.getWidth()/2,SpdMain.bTabbedPanel.getHeight()/2); 
      passwd.setTitle("Enter Passwd for user "+username); 
      JPasswordField p =new JPasswordField(10); 
      p.addActionListener(this); 
      p.setActionCommand(inFileInx+","+inRemoteDBURLFull); 
      passwd.add(p); 
      passwd.setPreferredSize(new Dimension(300,50)); 
      passwd.pack(); 
      passwd.setVisible(true); 
      pass=new Thread(new Runnable() 
      { 
       public void run() { 
        DpmLogger.dtlTraceOut("The password thread has completed and has got password from the user",DpmLogger.TRACE_RARE,myId); 
       } 

      }); 

      try { 
        pass.join(); 
       } catch (InterruptedException e) 
        { 
         DpmLogger.dtlTraceOut("Password thread unable to join",DpmLogger.TRACE_RARE,myId); 
        } 

       DpmLogger.dtlTraceOut("Password thread now joined",DpmLogger.TRACE_RARE,myId); 
     } 

} 


public void actionPerformed(ActionEvent e) 
{ JTextField p=(JTextField)e.getSource(); 
    if(password==null) 
    password=p.getText(); 
    passwd.setVisible(false); 

    String[] inVars=e.getActionCommand().split(","); 
    try 
    { openDBcontinue(Integer.parseInt(inVars[0]),inVars[1]); 
      pass.start(); 
    } 
    catch(Exception exp) 
    { DpmLogger.dtlException("SPDBInterfaceException:OpenDB", exp); 
    } 
} 

正如你所看到的,我試圖讓方法在join()的'pass'線程上等待。動作偵聽器在IO完成時啓動傳遞線程。但它不起作用。 OpenDB()無需等待'pass'即可運行。這是因爲該方法不在線程內?我是否必須使此DBInterface類擴展Thread類?我很困惑!

+1

退房How to Make Dialogs什麼是錯了['JDialog'](http://docs.oracle.com/javase/tutorial/uiswing/components/dialog html的)? – MadProgrammer

+0

所有事件都在一個單獨的線程(事件調度程序線程)中進行處理。我想你正在應用'pass.join()'在錯誤的線程中(這使**當前**線程等待通過完成),而你想在JFrame IO上等待完成。如果有任何耗時的處理,你應該考慮'SwingWorker',例如,以便你的UI不會凍結 –

+0

哦,對不起,我使用JPasswordField(你可以在代碼中看到它)。我一定忘記提及,但那不是我的問題 – Sid

回答

3

出於安全原因,用戶在一個JFrame textarea的輸入自己的密碼

爲:

  1. 便利(以及可能的解決方案)交換JFrame一個模式對話框或JOptionPane 。例如。如在this answer中看到的那樣。
  2. 安全使用JPassWordField而不是the tutorial中看到的'textarea'。
    enter image description here
+0

+1擊敗我 – MadProgrammer

+0

我使用JPasswordField。仔細查看代碼。不管怎麼說,還是要謝謝你! – Sid

+0

*「正確地查看代碼。」*拼寫正確的類名。如果需要複製/粘貼它們。 'textarea'不是'JPasswordField'。 –

3

你可以使用一個JDialog,但這需要你管理的緊密操作(添加有關使用狀態按鈕和食堂),或者你可以簡單地使用JOptionPane

或者(當設置爲模態)將導致事件派發線程暫停執行,直到它們關閉。

enter image description here

public class TestDialog01 { 

    public static void main(String[] args) { 
     new TestDialog01(); 
    } 

    public TestDialog01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       PasswordPane pane = new PasswordPane(); 
       int result = JOptionPane.showConfirmDialog(null, pane, "Password", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); 
       if (result == JOptionPane.OK_OPTION) { 
        // get the result... 
       } 

      } 
     }); 
    } 

    public class PasswordPane extends JPanel { 

     private JTextField userName; 
     private JPasswordField password; 

     public PasswordPane() { 
      userName = new JTextField(12); 
      password = new JPasswordField(12); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.insets = new Insets(2, 2, 2, 2); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      add(new JLabel("User Name:"), gbc); 
      gbc.gridx++; 
      add(userName, gbc); 

      gbc.gridy++; 
      gbc.gridx = 0; 
      add(new JLabel("Password:"), gbc); 
      gbc.gridx++; 
      add(password, gbc); 
     } 

     public String getUserName() { 

      return userName.getText(); 

     } 

     public char[] getPassword() { 

      return password.getPassword(); 

     } 
    } 
} 

更多信息

+0

很好的解釋。 +1 –

+0

因此,您不是在Event Dispatching Thread中調用OpenDB。 – MadProgrammer

+0

不工作。 OpenDB()總是返回不等待JOptionPane返回OK_OPTION。這是發生了什麼: openDBcalled 的JOptionPane將顯示對話框 openDBreturns 回調用openDB 的JOptionPane後filemgr:密碼被記錄爲測試 – Sid

相關問題