2012-12-10 46 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

相关问题