У меня есть следующий код, чтобы получить 2 ввода от пользователя через поле JCombo, после чего я возвращаю значение s полученного ввода вызывающей функции, но проблема в том, что этот код отображает кадр для получения пользовательского ввода, но перед тем, как пользователь может нажать кнопку ' Ok ', он возвращает нулевое значение вызывающей функции. Я ищу, чтобы остановить код в этом методе, пока пользователь не нажмет кнопку "ОК". Пожалуйста, предложите что-нибудь.
package io;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Insets;
import java.io.FileNotFoundException;
public class SrcAndTargLangInput implements ActionListener {
public static JFrame frame;
public static JComboBox sourcLang;
public static JComboBox targLang;
public static JLabel setSrcLang;
public static JLabel setTargLang;
public static JButton ok;
static String[] lang=new String[2];
public SrcAndTargLangInput(){
ok = new JButton("Ok");
ok.setBounds(150,150,100,50);
frame = new JFrame();
frame.getContentPane().setLayout(null);
frame.getContentPane().add(ok);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Insets ins = frame.getInsets();
frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
setSrcLang=new JLabel("Source Language");
frame.getContentPane().add(setSrcLang);
setSrcLang.setBounds(50, 50, 100, 40);
setTargLang=new JLabel("Target Language");
frame.getContentPane().add(setTargLang);
setTargLang.setBounds(50, 100, 100, 40);
String[] srcLangList={"English","Spanish","French"};
sourcLang = new JComboBox(srcLangList);
frame.getContentPane().add(sourcLang);
sourcLang.setBounds(250,50,100,40);
String[] targLangList={"English","Spanish","French"};
targLang = new JComboBox(targLangList);
frame.getContentPane().add(targLang);
targLang.setBounds(250,100,100,40);
frame.setVisible(true);
ok.addActionListener(this);
}
public static String[] langInfo(){
SrcAndTargLangInput ob = new SrcAndTargLangInput();
return lang;
}
public void actionPerformed(ActionEvent e){
lang[0]=(sourcLang.getSelectedItem().toString());
lang[1]=(targLang.getSelectedItem().toString());
frame.setVisible(false);
}
}
Вызывающая функция:
String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();
System.out.println(lg[0]);
System.out.println(lg[1]);
На основе этих строк:
String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();
Проблема в том, ваш SrcAndTargLangInput
класс использует JFrame
, чтобы попросить пользователя для входа. Сказав это, JFrame
не является модальным и, следовательно, не блокирует текущий поток, ожидающий ввода, как вы пожелаете. Вы должны использовать модальный JDialog
или JOptionPane
(который отображает модальный диалог), чтобы ждать, пока пользователи подтвердят свой ввод.
Взгляните на эти темы:
Как уже многие разработчики уже сказали, Swing предназначен для использования с менеджерами setBounds()
и вам следует избегать таких методов, как setBounds()
, setLocation()
или setSize()
. Вы можете также взглянуть на эти темы:
Обратите внимание, что текст текстового поля не изменяется, пока вы не подтвердите свой ввод.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Demo {
private void createAndShowGui() {
final JTextField textField = new JTextField(10);
textField.setEditable(false);
JButton button = new JButton("Show dialog");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox languagesComboBox = new JComboBox(new Object[]{"English","Spanish","French"});
JPanel dialogPanel = new JPanel();
dialogPanel.add(new JLabel("Please select an option:"));
dialogPanel.add(languagesComboBox);
int option = JOptionPane.showConfirmDialog(null, dialogPanel, "Select an input"
, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if(option == JOptionPane.OK_OPTION) {
String selectedInput = (String)languagesComboBox.getSelectedItem();
textField.setText(selectedInput);
}
}
});
JPanel content = new JPanel();
content.add(new JLabel("User input:"));
content.add(textField);
content.add(button);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGui();
}
});
}
}
В вашем коде вы можете добавить логическую переменную со значением по умолчанию как false.
В методе actionPerformed установите значение true. Обновите метод logInfo, чтобы сделать поток спящим до тех пор, пока не будет выполнено никаких действий. Посмотрите на код ниже.
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Insets;
import java.io.FileNotFoundException;
public class SrcAndTargLangInput implements ActionListener {
public static JFrame frame;
public static JComboBox sourcLang;
public static JComboBox targLang;
public static JLabel setSrcLang;
public static JLabel setTargLang;
public static JButton ok;
static String[] lang=new String[2];
boolean actionPerformed = false;
public SrcAndTargLangInput(){
ok = new JButton("Ok");
ok.setBounds(150,150,100,50);
frame = new JFrame();
frame.getContentPane().setLayout(null);
frame.getContentPane().add(ok);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Insets ins = frame.getInsets();
frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
setSrcLang=new JLabel("Source Language");
frame.getContentPane().add(setSrcLang);
setSrcLang.setBounds(50, 50, 100, 40);
setTargLang=new JLabel("Target Language");
frame.getContentPane().add(setTargLang);
setTargLang.setBounds(50, 100, 100, 40);
String[] srcLangList={"English","Spanish","French"};
sourcLang = new JComboBox(srcLangList);
frame.getContentPane().add(sourcLang);
sourcLang.setBounds(250,50,100,40);
String[] targLangList={"English","Spanish","French"};
targLang = new JComboBox(targLangList);
frame.getContentPane().add(targLang);
targLang.setBounds(250,100,100,40);
frame.setVisible(true);
ok.addActionListener(this);
}
public static String[] langInfo() throws InterruptedException{
SrcAndTargLangInput ob = new SrcAndTargLangInput();
while(!ob.actionPerformed) {
Thread.sleep(1000);
}
return lang;
}
public void actionPerformed(ActionEvent e){
lang[0]=(sourcLang.getSelectedItem().toString());
lang[1]=(targLang.getSelectedItem().toString());
actionPerformed = true;
frame.setVisible(false);
Thread.currentThread().interrupt();
}
}
null layout
вместо рекомендовать Layout Manager . Второй избегать использования Thread.sleep()
вместо того, чтобы использовать Timers
. И дополнительно, для ActionListeners
не использовать таймеры , пока что - то происходит, вместо этого, использовать событие. Это касается OP: как добавить ActionListener
в JButton
io.SrcAndTargLangInput.langInfo();
?