Я очень долго безуспешно пытался заставить работать следующий код. Я хотел бы открыть ServerSocket и запустить его на заднем плане моего графического интерфейса. У меня есть кнопка запуска, которая должна запускать сервер, и кнопка остановки, которая остановит сервер от дальнейшего прослушивания клиентов, которые хотят подключиться.
Это очень простой графический интерфейс с 2 кнопками и 2 текстовыми полями. Пользователь должен ввести имя пользователя и пароль, соответствующий базе данных. Если данные верны, Сервер должен запуститься. Однако это приводит к зависанию графического интерфейса пользователя, если сервер не работает в отдельном потоке. Я хочу использовать для этого SwingWorker. (Если нет лучшего способа)
Однако я немного нахожусь в глубине своих познаний по этому поводу. Любая помощь будет очень признательна. Спасибо!
public class Server extends JFrame implements ActionListener {
JLabel instructionsLabel;
JLabel passwordLabel;
JPasswordField passwordTF;
JButton shutdownButton;
JButton startupButton;
JLabel usernameLabel;
JTextField usernameTF;
public Server() {
super("Server");
initComponents();
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String f = "n";
ConnectionBean cb = new ConnectionBean();
char[] a = passwordTF.getPassword();
String b = new String(a);
String inputDetails = usernameTF.getText() + b;
Iterator it = cb.getDetails().iterator();
while (it.hasNext()) {
Object next = it.next();
if (inputDetails.equals(next)) {
f = "y";
if (source == startupButton) {
try {
sop.doInBackground();
} catch (Exception ex) {
}
JOptionPane.showMessageDialog(null,
"Congratulations! Server started.",
"Start-up Message",
JOptionPane.INFORMATION_MESSAGE);
} else if (source == shutdownButton) {
try {
sop.failIfInterrupted();
} catch (Exception ex) {
}
JOptionPane.showMessageDialog(null,
"Server shut-down successfully!",
"Shut-down Message",
JOptionPane.INFORMATION_MESSAGE);
}
}
}
if (f.equals("n")) {
JOptionPane.showMessageDialog(null, "Invalid username or password.", "Alert", JOptionPane.WARNING_MESSAGE);
}
passwordTF.setText("");
usernameTF.setText("");
cb.setCloseConnection(true);
}
// THIS IS WHERE I GET STUCK!
public class ServerOperation extends SwingWorker<Void, Void> {
ServerSocket ss;
Socket cs;
public ServerOperation(ServerSocket ss) {
this.ss = ss;
}
@Override
protected Void doInBackground() throws Exception {
return Void;
}
public void failIfInterrupted() throws InterruptedException {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
}
}
Код, который я использовал раньше для запуска сервера, был таким ...
ServerSocket ss;
Socket cs;
public void StartingSer() throws Exception {
ss = new ServerSocket(7777);
while (true) {
cs = ss.accept();
new ServerTread(cs).start();
}
}
но это приводит к зависанию графического интерфейса пользователя, поскольку он не является потокобезопасным.
Дело в том, что я не знаю, как это сделать. Давно пробовали безрезультатно. Я был бы очень признателен за помощь. Мне не удалось найти в Интернете никаких полезных статей по этой теме.
"но это приводит к зависанию графического интерфейса, поскольку он не является потокобезопасным"
Нет, это приводит к зависанию графического интерфейса пользователя, поскольку этот метод выполняется в потоке графического интерфейса. Вы должны использовать для этого отдельный поток.
Когда кнопка «Пуск» нажата, создайте поток, сохраните ссылку на него и запустите его. Когда кнопка Stop нажата, отправьте сигнал прерывания этому потоку. Вот и все. SwingWorker не требуется.
Да, я понял это. Теперь я понимаю, что он создает сервер в отдельном потоке.
Ну, у
doInBackground()
кода нет. Вы не застряли, вы просите нас написать все за вас. Требуется больше попыток реального кода.