Java:如何让线程等待来自用户的IO,然后继续
在DbInterface类中,函数openDB()打开与服务器上Oracle DB的连接。出于安全原因,用户必须在JFrame文本区域中输入密码,然后程序才能继续连接。现在,这个Jframe有一个操作侦听器,它等待用户输入密码并调用OpenDBContinue()方法 现在的问题是:openDB()不等待Jframe IO完成,假设DB已经打开,则将控制权返回给调用类(调用openDB()的人),然后他们继续并开始查询DB,这显然失败了 现在如何让openDB()等待Jframe IO完成?这是给你一个想法的代码Java:如何让线程等待来自用户的IO,然后继续,java,multithreading,swing,io,Java,Multithreading,Swing,Io,在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()使该方法在“pass”线程上等待。操作侦听器在IO完成时启动传递线程。但它不起作用。OpenDB()返回,无需等待“pass”运行。这是因为该方法不在线程内吗?我必须让这个DBInterface类扩展线程类吗?我糊涂了
出于安全原因,用户必须在JFrame文本区域中输入密码
用于:
JFrame
交换为模式对话框或JOptionPane
。例如,如中所示。JPassWordField
代替中的“textarea”JFrame
交换为模式对话框或JOptionPane
。例如,如中所示。JPassWordField
代替中的“textarea”您可以使用
JDialog
,但这需要您管理关闭操作(添加按钮并处理状态),或者您可以简单地使用JOptionPane
其中一个(设置为modal时)将导致事件调度线程在该点暂停执行,直到它们关闭
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();
}
}
}
查看更多信息您可以使用
JDialog
,但这需要您管理关闭操作(添加按钮并处理状态),或者您可以简单地使用作业窗格
其中一个(设置为modal时)将导致事件调度线程在该点暂停执行,直到它们关闭
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();
}
}
}
查看更多信息a有什么问题?所有事件都在swing中的单独线程(事件调度程序线程)中处理。我认为您在错误的线程中应用了
pass.join()
(这使得当前线程等待pass完成),而您希望等待JFrame IO完成。如果有任何耗时的事情要处理,你应该考虑<代码> SvigWorks,这样你的UI就不会被冻结了,抱歉我使用了JPasswordField(你可以在代码中看到它)。我一定忘了提到这一点,但这不是我的问题。a怎么了?所有事件都在swing中的一个单独线程(事件调度程序线程)中处理。我认为您在错误的线程中应用了pass.join()
(这使得当前线程等待pass完成),而您希望等待JFrame IO完成。如果有任何耗时的事情要处理,你应该考虑<代码> SvigWorks,这样你的UI就不会被冻结了,抱歉我使用了JPasswordField(你可以在代码中看到它)。我一定忘了提这一点,但这不是我的问题,我用的是JPasswordField。请仔细查看代码。无论如何谢谢你!正确地拼写类名。如果需要,复制/粘贴它们。“textarea”不是JPasswordField
。我使用JPasswordField。请仔细查看代码。无论如何谢谢你!正确地拼写类名。如果需要,复制/粘贴它们。“textarea”不是JPasswordField
。因此,您没有从事件调度线程中调用OpenDB。仍然无法工作。OpenDB()总是返回,而不是等待JOptionPane返回OK_选项。发生的情况如下:调用openDB joptionPane后,openDBcalled joptionPane将显示openDBreturns to filemgr对话框:密码记录为testjoptionPane
必须在EDT内可见,才能阻止线程。你有一些示例代码吗?那么,你不是从事件调度线程中调用OpenDB。仍然不能工作。OpenDB()总是返回,而不是等待JOptionPane返回OK_选项。发生的情况如下:调用openDB joptionPane后,openDBcalled joptionPane将显示openDBreturns to filemgr对话框:密码记录为testjoptionPane
必须在EDT内可见,才能阻止线程。你有一些示例代码吗?