Wątek utworzony z aplikacji swing zawiesza ją

0

Witam,

aktualnie próbuję napisać komunikator tekstowy w stylu chatu. problem jest w tym, że nowy wątek który ma nasłuchiwać odpowiedzi serwera i wysyłać wiadomości zawiesza całą aplikację.

Z góry dzięki za odpowiedź.

Plik: KomunikatorFrame.java

package glowny;

import java.awt.BorderLayout;

public class KomunikatorFrame extends JFrame {

	private static final long serialVersionUID = 7055360075085702038L;
	private JPanel contentPane;
	private JTextField textField;
	private static final String HOST = "192.168.100.15";
	private static final int PORT = 8189;
	private JTextPane wiadomosci;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					KomunikatorFrame frame = new KomunikatorFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public KomunikatorFrame() {
		inicjalizujMenu();
	}
	
	public void updateText(String line) {
		wiadomosci.setText(line);
	}
	
	private void polaczZKanalem(int i) {
		WatekKlienta watekKlienta = new WatekKlienta(HOST, PORT);
		watekKlienta.setListener(this);
		Thread thread = new Thread(watekKlienta);
		thread.run();
	}

	private void inicjalizujMenu() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 640, 480);
		
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu mnNewMenu = new JMenu("File");
		menuBar.add(mnNewMenu);
		
		JMenu mnNewMenu_1 = new JMenu("Connect");
		mnNewMenu.add(mnNewMenu_1);
		
		JMenuItem mntmKanal = new JMenuItem("Kanal_01");
		mntmKanal.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				polaczZKanalem(1);
			}
		});

		mnNewMenu_1.add(mntmKanal);
		
		JMenuItem mntmExit = new JMenuItem("Exit");
		mntmExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

		mnNewMenu.add(mntmExit);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));
		
		JPanel panel = new JPanel();
		contentPane.add(panel, BorderLayout.SOUTH);
		panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		textField = new JTextField();
		panel.add(textField);
		textField.setColumns(40);
		
		JButton wyslij = new JButton("Wyslij");
		panel.add(wyslij);
		
		JSplitPane splitPane = new JSplitPane();
		splitPane.setDividerLocation(480);
		splitPane.setDividerSize(5);
		contentPane.add(splitPane, BorderLayout.CENTER);
		
		wiadomosci = new JTextPane();
		wiadomosci.setEditable(false);
		splitPane.setLeftComponent(wiadomosci);
		
		JTextPane osoby = new JTextPane();
		osoby.setEditable(false);
		splitPane.setRightComponent(osoby);
	}

}

Plik: WatekKlienta.java

package glowny;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class WatekKlienta implements Runnable {
	
	private KomunikatorFrame komunikatorFrame;
	private Scanner in;
	private PrintWriter writer;
	private String host;
	private int port;
	private boolean exit;
	
	WatekKlienta(String host, int port) {
		this.host = host;
		this.port = port;
		exit = false;
	}
	
	public void setListener(KomunikatorFrame komunikatorFrame) {
		this.komunikatorFrame = komunikatorFrame;
	}

	@Override
	public void run() {
			
			while (!exit) {

			}

	}
	
}

PS: W pętli while próbowałem nasłuchiwać, usypiać wątek ale powodowało to tylko zmianę użycia procesora z 25% do 1% itd. Całe menu stworzone w swingu i tak było zawieszone.

0

Nie stworzyłeś żadnego Socketa to jak się chcesz połączyć? Co z czym?

0

Socket tworzyłem w wątku, aktualnie chodzi mi o to że ten wątek(pętla while) nawet bez kodu w środku zawiesza działanie całej aplikacji. (menu swing nie odpowiada)

	public void run() {
		try {
			Socket socket = new Socket(host, port);
			in = new Scanner(socket.getInputStream());
			writer = new PrintWriter(socket.getOutputStream());
			String line = in.nextLine();
			komunikatorFrame.updateText(line);
			
			while (!exit) {
				line = in.nextLine();
				komunikatorFrame.updateText(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
0

Z czym się tutaj łączysz? Tworzysz socket ale wcześniej przydałby się jakiś server. Zmień sobie ip na localhosta najlepiej.

0

Serwer mam ale pomińmy kwestie łączenia się z nim, to wszystko działa, usunąłem ten kod w pierwszym poście, chodzi o sam fakt, że nowy wątek w którym jest pętla while powoduje zawieszenie się programu zamiast wykonywanie równolegle kodu KomunikatorFrame i WatekKlienta

Nawet gdy wykasuje wszystko z while(true) swing jest zawieszony. pozostaje tylko ubicie programu z menadżera.

Reszta kod serwera:

package glowny;

//import java.util.Scanner;

public class StartProgramu {

	public static void main(String[] args) {
		//Scanner sc = new Scanner(System.in);
		//System.out.println(sc.next());
		Serwer serwer = new Serwer();
		serwer.run();
	}

}
package glowny;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Serwer implements Runnable {

	boolean exit;
	ArrayList<WatekSerwera> listaKanal1 = new ArrayList<WatekSerwera>();
	
	Serwer() {
		exit = false;
	}

	@Override
	public void run() {
		try {
			int i = 1;
			ServerSocket s = new ServerSocket(8189);

			while (!exit) {
				Socket incoming = s.accept();
				System.out.println("Polaczono: " + i);
				WatekSerwera watekSerwera = new WatekSerwera(incoming, i);
				watekSerwera.setListener(this);
				listaKanal1.add(watekSerwera);
				Thread thread = new Thread(watekSerwera);
				thread.run();
				i++;
			}
			s.close();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void update(String line, int i) {
		for(WatekSerwera ws : listaKanal1) {
			ws.update(line);
		}
	}
}
package glowny;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class WatekSerwera implements Runnable {

	private Socket incoming;
	private Serwer serwer;
	private boolean exit;
	private int i;
	private Scanner in;
	private PrintWriter out;

	WatekSerwera(Socket s, int i) {
		incoming = s;
		exit = false;
		this.i = i;
	}
	
	public void setListener(Serwer serwer) {
		this.serwer = serwer;
	}
	
	public void update(String line) {
		out.write(line);
		out.flush();
	}

	@Override
	public void run() {
		try {
			InputStream inStream = incoming.getInputStream();
			OutputStream outStream = incoming.getOutputStream();

			in = new Scanner(inStream);
			out = new PrintWriter(outStream);

			out.println("Serwer: Witam na kanale");
			out.flush();
			
			while (!exit) {
				String line = in.nextLine();
				serwer.update(line, i);
				System.out.println("Klient: " + line);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

Tak jakby program zamiast tworzyć nowy wątek po prostu wchodził w pętle while w metodzie run i już stamtąd nie wychodził...

0

Ok znalazłem błąd. Moja głupota - wpisałem Thread.run zamiast Thread.start...

1 użytkowników online, w tym zalogowanych: 0, gości: 1