1

DbInterfaceクラスでは、関数openDB()がサーバー上のOracleDBへの接続を開きます。セキュリティ上の理由から、プログラムが接続を続行する前に、ユーザーは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()を使用してメソッドを「pass」スレッドで待機させようとしています。アクションリスナーは、IOが終了するとパススレッドを開始します。しかし、それは機能しません。OpenDB()は、「pass」の実行を待たずに戻ります。これは、メソッドがスレッド内にないためですか?このDBInterfaceクラスにThreadクラスを拡張させる必要がありますか?私は混乱しています!

4

2 に答える 2

3

を使用できますがJDialog、閉じる操作を管理する必要があります (ボタンを追加して状態をいじる)、または単にJOptionPane

いずれか (モーダルに設定されている場合) は、イベント ディスパッチ スレッドが閉じられるまで、その時点で実行を一時停止します。

ここに画像の説明を入力

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

        }
    }
}

詳細については、ダイアログの作成方法を参照してください。

于 2012-12-10T04:45:14.987 に答える
3

セキュリティ上の理由から、ユーザーはパスワードを JFrame テキストエリアに入力する必要があります

為に:

  1. 利便性 (および考えられる解決策)JFrameをモーダル ダイアログまたは に置き換えJOptionPaneます。この回答に見られるEG 。
  2. チュートリアルで見られるように、セキュリティJPassWordFieldは「textarea」の代わりにa を使用します。
    ここに画像の説明を入力
于 2012-12-10T04:37:48.040 に答える