我知道我知道,在這個無處不在的地方已經有100萬個問題和答案。關於它的非常詳細的文章,幾種類型的例子。我花了幾個小時閱讀了這篇文章,但那不是訣竅。我問這個問題的原因是因爲我仍然不明白我需要做什麼,顯然是因爲我的代碼還沒有工作。我得到Swing如何與EDT協同工作的想法,如果我要使用ServerSocket的accept()方法,那麼我需要爲Swing啓動一個新線程(我認爲?)。當我運行我的代碼時,窗口剛剛打開並凍結。 我的問題是有人看我的代碼,告訴我我做錯了什麼,並解釋給我,就像我只有一半的大腦? (因爲這是我的感覺就像:P)Java - 線程,Swing和ServerSocket
這裏有一些地方我讀過不已:
- This question from SO.
- This site.
- And of course the Oracle's explanation of swing and threads.
- 而一個其他幾個隨機站點。
Main.class
package com.sever.core;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.SwingUtilities;
public class Main {
private SocketManager network;
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
Window window = new Window();
window.setVisible(true);
}
});
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
Main main = new Main();
main.run();
}
});
}
public void run(){
network = new SocketManager(25595);
while(true){
try {
network.setSocket(network.getServerSocket().accept());
AddUser(network.getSocket());
Thread x = new Thread(network);
x.start();
} catch (Exception e) {
System.out.println("Failed to connect.");
}
}
}
public void AddUser(Socket s){
try {
Scanner input = new Scanner(s.getInputStream());
network.addUser(input.nextLine());
} catch (Exception e) {
}
}
}
Window.class
package com.sever.core;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
private Thread thread;
private JPanel window = new JPanel();
private JTextArea consle = new JTextArea("Server started....");
private JTextField input = new JTextField();
private JScrollPane consleinput = new JScrollPane(consle);
public Window(){
this.setName("NAMEHERE - Server Software");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
window.setBackground(Color.DARK_GRAY);
window.setLayout(new BoxLayout(window, BoxLayout.Y_AXIS));
consleSetup();
addComponets();
}
private void addComponets(){
add(window);
window.add(consleinput);
window.add(input);
}
private void consleSetup(){
consle.setEditable(false);
consle.setLineWrap(true);
consle.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
consleinput.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
input.setMaximumSize(new Dimension(Integer.MAX_VALUE,input.getPreferredSize().height));
}
private void addListeners(){
input.addActionListener(new ActLis());
input.setActionCommand("input");
}
}
SocketManager.class
package com.sever.core;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class SocketManager implements Runnable{
private Socket sock;
private ServerSocket sersoc;
private PrintWriter output;
private BufferedReader input;
private Thread thread;
public ArrayList<Socket> currentConnections = new ArrayList<Socket>();
public ArrayList<String> currentUsers = new ArrayList<String>();
public SocketManager(String ip, int port){
try{
sock = new Socket(ip,port);
PrintWriter output = new PrintWriter(sock.getOutputStream());
BufferedReader input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
System.out.println("Server: socket started.");
}catch(Exception e){
System.out.println("Server: Socket failed to connect.\n");
}
}
public SocketManager(int port){
try {
sersoc = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Server: Socket failed to connect.\n");
}
}
public SocketManager(Socket socket){
this.sock = socket;
try{
output = new PrintWriter(sock.getOutputStream());
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
}catch(Exception e){
}
}
public synchronized void checkConnetion(){
if(!sock.isConnected()){
for(int x = 0; x <= currentConnections.size(); x++){
if(currentConnections.get(x) == sock){
currentConnections.remove(x);
System.out.println("Server: Disconnecting from: " + currentConnections.get(x) + "\n");
}
}
}
}
public synchronized Socket getSocket(){
return sock;
}
public synchronized ServerSocket getServerSocket(){
return sersoc;
}
public synchronized void setSocket(Socket s){
System.out.println("Setting socket to: " + s.getInetAddress());
sock = s;
}
public synchronized void addSocket(Socket s){
currentConnections.add(s);
}
public synchronized void addUser(String u){
currentUsers.add(u);
}
public synchronized ArrayList<Socket> getConnections(){
return currentConnections;
}
public synchronized ArrayList<String> getUsers(){
return currentUsers;
}
public synchronized void send(String data){
try{
output.println(data);
}catch(Exception e){
}
}
public synchronized void close(){
try{
sock.close();
}catch(Exception e){
}
output = null;
input = null;
System.gc();
}
public synchronized boolean isConnected(){
return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}
@Override
public void run() {
System.out.println("Is runing.");
while(true){
try {
checkConnetion();
if(input.readLine().isEmpty()){
return;
}
output.println("Server: Recived your message.");
} catch (Exception e) {
} finally{
try {
sock.close();
} catch (Exception e) {
}
}
}
}
}
ActLis.class
package com.sever.core;
import java.awt.event.*;
import javax.swing.*;
public class ActLis implements ActionListener{
private JTextField actionField;
public ActLis(){
}
public ActLis(JTextField t){
actionField = t;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String cmd = e.getActionCommand();
if(cmd == "input"){
}
}
}
- 編輯 - 新Main.class用的SwingWorker
package com.sever.core;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Main {
private SocketManager network;
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
Window window = new Window();
window.setVisible(true);
}
});
SwingWorker server = new SwingWorker(){
@Override
protected Object doInBackground() throws Exception {
Main main = new Main();
main.run();
return null;
}
};
server.run();
}
public void run(){
network = new SocketManager(25595);
while(true){
try {
network.setSocket(network.getServerSocket().accept());
AddUser(network.getSocket());
Thread x = new Thread(network);
x.start();
} catch (Exception e) {
System.out.println("Failed to connect.");
}
}
}
public void AddUser(Socket s){
try {
Scanner input = new Scanner(s.getInputStream());
network.addUser(input.nextLine());
} catch (Exception e) {
}
}
}
由於您使用了invokeLater,因此您的套接字在EDT上運行。你應該使用SwingWorker來執行Main.run()。 –
@GuillaumePolet好的,謝謝。我讀過那篇文章,但是當我這樣做時,我不確定那是否是我想要的。我會試一試並回報。 – cgasser