1

在 DbInterface 类中,函数 openDB() 打开与服务器上的 Oracle DB 的连接。出于安全原因,用户必须在 JFrame 文本区域中输入密码,然后程序才能继续连接。现在这个 Jframe 有一个动作监听器,它等待用户输入密码并调用 OpenDBContinue() 方法。

现在的问题是:openDB() 不会等待 Jframe IO 完成并假设 DB 已打开,将控制权返回给调用类(调用 openDB() 的人),然后他们继续开始查询显然失败的 DB!

现在如何让 openDB() 等待 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() 的“通过”线程上等待。当 IO 完成时,动作监听器启动 pass 线程。但它不起作用。OpenDB() 无需等待“通过”运行即可返回。这是因为该方法不在线程内吗?我必须让这个 DBInterface 类扩展 Thread 类吗?我很困惑!

4

2 回答 2

3

出于安全原因,用户必须在 JFrame 文本区域中输入密码

为了:

  1. 方便(和可能的解决方案)交换JFrame模态对话框或JOptionPane. EG 如this answer所示。
  2. 安全性使用 a而不是教程JPassWordField中看到的“textarea” 。
    在此处输入图像描述
于 2012-12-10T04:37:48.040 回答
3

You could use a JDialog, but that would require you to manage the close operations (add buttons and mess about with states), or you could simply use a JOptionPane

Either (when set to modal) will cause the Event Dispatching Thread to pause execution at that point until they are closed.

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();

        }
    }
}

Check out How to Make Dialogs for more info

于 2012-12-10T04:45:14.987 回答