Java Swing GUI зависает
10393 просмотра
5 ответа
Я пишу клиентское / серверное приложение Java с использованием сокетов, и вот проблема:
У меня есть кнопка, чтобы начать прослушивание указанного порта:
кнопка actionPerformed метод
private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) {
int port = Integer.parseInt(portTextfield.getText(), 10);
try {
socket.listen(port);
} catch (IOException ex) {
}
}
Вот метод socket.listen
public static void listen() throws IOException {
ServerSocket ss = new ServerSocket(port);
while (true)
new socket(ss.accept());
}
класс «socket» расширяет «Thread».
Таким образом, после того, как ss.accept () возвращает значение, он создает новый экземпляр сокета в отдельном потоке.
После нажатия кнопки графический интерфейс останавливается, потому что внутри метода socket.listen существует бесконечный цикл. Как я могу избежать этого?
Автор: Nick Sanders Источник Размещён: 13.11.2019 11:38Ответы (5)
5 плюса
У вас есть две ловушки в вашем дизайне:
ss.accept()
это блокирующий вызов, поэтому ваш пользовательский интерфейс будет зависать, пока не будет входящее соединение- Никогда не запускайте
while(true)
циклы в EDT.
Вместо этого сделайте следующее:
- При нажатии кнопки создайте поток, который начнет прослушивать входящие соединения.
- Если у вас есть входящее соединение, создайте другой поток, который будет принимать входящее клиентское соединение и обрабатывать его.
5 плюса
пока ваш
new socket(ss.accept());
возвращается немедленно, вам нужно только изменить
while (true)
это помещает EDT (Thread Dispatch Thread) в бесконечный цикл, и ваш GUI перестает отвечать на запросы. Итак, удалите эту строку.
Если вы не можете использовать класс SwingWorker ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List ), создайте вложенный класс, который Extents SwingWorker. Просто вызовите swingWoker.execute (); (после того, как вы создали его объект) в вашем методе listenButtonActionPerformed (java.awt.event.ActionEvent evt) .
См. Учебное пособие: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html.
Никогда не создавайте новую тему и не запускайте ее из Swing EDT
Автор: vedant Размещён: 25.06.2012 08:413 плюса
Вам нужно будет использовать многопоточность. Если бы я находился там, где вы, я бы разделил код GUI и код сервера, а когда кнопка нажата, я просто запускаю код сервера как новый поток.
Ваш код замораживает графический интерфейс в основном потому, что все события выполняются в потоке диспетчера событий (EDT), который является потоком, который заботится обо всех ваших графических интерфейсах и соответствующих событиях. Если вы заблокируете его, остановите или создадите циклы, это повлияет на его производительность.
Автор: npinti Размещён: 25.06.2012 08:033 плюса
Проверьте это: http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html
1) Если вы пишете приложение GUI, возможно, в Swing никогда не вызывайте метод блокировки в потоке диспетчера событий или в обработчике событий. например, если вы читаете файл или открываете сетевое соединение при нажатии кнопки, не делайте этого в методе actionPerformed (), вместо этого просто создайте другой рабочий поток для выполнения этой работы и вернитесь из actionPerformed (). это будет поддерживать отзывчивость вашего графического интерфейса, но опять-таки это зависит от дизайна, если операция - это то, что требует от пользователя ожидания, а не использования invokeAndWait () для синхронного обновления.
Использование нескольких потоков: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html
Автор: CosminO Размещён: 25.06.2012 08:082 плюса
Попробуйте это...
1. During getting the initial connection delay can occur, so first create and empty
socket,then try to connect to the server.
`Socket s = new Socket();`
`s.connect(new InetSocketAddress("ip_addr",port_nos),1000);`
2. And Secondly always keep the Non-UI work out of Your UI thread..
Вот мой пример взаимодействия сервера с клиентом.
Код на стороне клиента:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket();
s.connect(new InetSocketAddress("127.0.0.1", 4444),1000);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Код серверной части:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
@Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
Автор: Kumar Vivek Mitra
Размещён: 25.06.2012 03:08
Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- swing Java Swing: отображение изображений внутри Jar
- swing Как реализовать перетаскиваемые вкладки с помощью Java Swing?
- swing Можно ли отобразить компоненты Swing в JSP?
- swing Как добавить ActionListener в JButton в Java
- sockets java.net.SocketException: сброс соединения
- sockets TcpClient.Connected возвращает true, но клиент не подключен, что я могу использовать вместо этого?
- sockets В чем разница между портом и сокетом?
- user-interface Что такое MVP и MVC и в чем разница?
- user-interface Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- user-interface Прототипирование GUI с клиентом
- user-interface Как заставить кнопку выглядеть так, как будто она нажата?
- concurrency Что такое состояние гонки?
- concurrency Что такое тупик?
- concurrency Что такое мьютекс?
- concurrency Безопасно ли получать значения из java.util.HashMap из нескольких потоков (без изменений)?