Last active
August 29, 2015 13:56
-
-
Save frostiq/9271154 to your computer and use it in GitHub Desktop.
NetChat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.swing.*; | |
import java.awt.*; | |
import java.awt.event.*; | |
import java.net.*; | |
public class MainWindow extends JFrame{ | |
JTextArea chatArea = new JTextArea(); | |
JButton netAction = new JButton(); | |
JTextField IPfield = new JTextField(); | |
JRadioButton clientMode = new JRadioButton("Client mode"); | |
JRadioButton serverMode = new JRadioButton("Server mode"); | |
ButtonGroup clientOrServer = new ButtonGroup(); | |
JPanel radioPanel = new JPanel(new GridLayout(2,1,0,5)); | |
JTextArea log = new JTextArea(); | |
JSplitPane splitPane = new JSplitPane(); | |
JPanel menuPanel = new JPanel(new GridLayout(1,0,10,5)); | |
JPanel chatPanel = new JPanel(new BorderLayout()); | |
JTextField sendField = new JTextField(); | |
Socket socket; | |
ClientDispatcher listener; | |
Server server; | |
boolean isRunning = false; | |
Command cmd; | |
MainWindow(){ | |
super("Net Chat"); | |
getContentPane().setLayout(new BorderLayout()); | |
getContentPane().add(splitPane, BorderLayout.CENTER); | |
getContentPane().add(menuPanel, BorderLayout.NORTH); | |
splitPane.setLeftComponent(chatPanel); | |
chatPanel.add(new JScrollPane(chatArea), BorderLayout.CENTER); | |
chatPanel.add(sendField, BorderLayout.SOUTH); | |
splitPane.setRightComponent(new JScrollPane(log)); | |
log.setEditable(false); | |
chatArea.setEditable(false); | |
addComponentListener(new ComponentAdapter() { | |
@Override | |
public void componentResized(ComponentEvent e) { | |
splitPane.setDividerLocation(0.5); | |
} | |
}); | |
radioPanel.setBorder(BorderFactory.createEtchedBorder()); | |
clientOrServer.add(clientMode); | |
clientOrServer.add(serverMode); | |
clientMode.addItemListener(new RadioListener(this)); | |
serverMode.addItemListener(new RadioListener(this)); | |
serverMode.setSelected(true); | |
radioPanel.add(clientMode); | |
radioPanel.add(serverMode); | |
menuPanel.add(radioPanel); | |
menuPanel.add(IPfield); | |
menuPanel.add(netAction); | |
netAction.addActionListener(new NetActionButtonListener(this)); | |
sendField.addKeyListener(new SendFieldListener(this)); | |
IPfield.addKeyListener(new KeyAdapter() { | |
@Override | |
public void keyPressed(KeyEvent e) { | |
if(e.getKeyCode() == KeyEvent.VK_ENTER) | |
netAction.doClick(); | |
} | |
}); | |
try{ | |
for (InetAddress i: InetAddress.getAllByName(InetAddress.getLocalHost().getHostName())) | |
if(i instanceof Inet4Address) | |
log.append(i.toString() + "\n"); | |
} | |
catch (Exception e){Catcher.catchException(e);} | |
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | |
setSize(700, 400); | |
setVisible(true); | |
} | |
void initClient(){ | |
netAction.setText("Connect to Server"); | |
IPfield.setText(""); | |
IPfield.setEnabled(true); | |
} | |
void initServer(){ | |
netAction.setText("Start Server"); | |
IPfield.setText(""); | |
IPfield.setEnabled(false); | |
} | |
synchronized void printToChat(String s){ | |
chatArea.append(s); | |
} | |
synchronized void printToLog(String s){ | |
log.append(s); | |
} | |
public static void main (String[] args){ | |
new MainWindow(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.swing.*; | |
public class Catcher { | |
static void catchException(Exception e){ | |
JOptionPane.showMessageDialog(null, e.toString(), "Error", JOptionPane.ERROR_MESSAGE); | |
//e.printStackTrace(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.net.InetAddress; | |
import java.net.UnknownHostException; | |
abstract public class Command { | |
abstract void execute(); | |
void cancel(){} | |
protected MainWindow wnd; | |
protected Command(MainWindow wnd) { | |
this.wnd = wnd; | |
} | |
} | |
class ConnectToServerCommand extends Command{ | |
ConnectToServerCommand(MainWindow wnd) { | |
super(wnd); | |
} | |
@Override | |
void execute() { | |
wnd.socket = SocketParser.parse(wnd.IPfield.getText()); | |
if(wnd.socket.isConnected()){ | |
wnd.log.append("Connected successfully to " + wnd.socket.getInetAddress() + "\n"); | |
wnd.isRunning = true; | |
wnd.netAction.setText("Disconnect"); | |
wnd.listener = new ClientDispatcher(wnd.socket, wnd); | |
wnd.listener.start(); | |
} | |
else | |
wnd.log.append("Connection failed!\n"); | |
} | |
@Override | |
void cancel() { | |
if(wnd.socket!=null){ | |
wnd.listener.interrupt(); | |
wnd.isRunning = false; | |
wnd.initClient(); | |
} | |
} | |
} | |
class StartServerCommand extends ConnectToServerCommand{ | |
StartServerCommand(MainWindow wnd) { | |
super(wnd); | |
} | |
@Override | |
void execute() { | |
wnd.server = new Server(wnd); | |
try { | |
wnd.IPfield.setText(InetAddress.getLocalHost().getHostAddress()+":"+wnd.server.s.getLocalPort()); | |
} catch (UnknownHostException e) { | |
Catcher.catchException(e); | |
} | |
wnd.server.start(); | |
super.execute(); | |
} | |
@Override | |
void cancel() { | |
if(wnd.server!=null) | |
wnd.server.interrupt(); | |
super.cancel(); | |
wnd.initServer(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Manifest-Version: 1.0 | |
Main-Class: MainWindow | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.event.*; | |
public class RadioListener implements ItemListener { | |
protected MainWindow wnd; | |
public RadioListener(MainWindow wnd) { | |
this.wnd = wnd; | |
} | |
@Override | |
public void itemStateChanged(ItemEvent e) { | |
if (e.getStateChange() == ItemEvent.SELECTED){ | |
if (wnd.cmd != null) | |
wnd.cmd.cancel(); | |
if(e.getSource() == wnd.clientMode){ | |
wnd.initClient(); | |
wnd.cmd = new ConnectToServerCommand(wnd); | |
} | |
else { | |
wnd.initServer(); | |
wnd.cmd = new StartServerCommand(wnd); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.event.KeyAdapter; | |
import java.awt.event.KeyEvent; | |
public class SendFieldListener extends KeyAdapter { | |
MainWindow wnd; | |
public SendFieldListener(MainWindow wnd) { | |
this.wnd = wnd; | |
} | |
@Override | |
public void keyPressed(KeyEvent e) { | |
if(e.getKeyCode() == KeyEvent.VK_ENTER){ | |
wnd.listener.sendMessage(wnd.sendField.getText()); | |
wnd.sendField.setText(""); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.net.ServerSocket; | |
import java.net.Socket; | |
import java.util.ArrayList; | |
public class Server extends Thread{ | |
ServerSocket s; | |
MainWindow wnd; | |
ArrayList<ServerDispatcher> sockets = new ArrayList<ServerDispatcher>(); | |
public Server(MainWindow wnd) { | |
try { | |
this.s = new ServerSocket(0); | |
this.wnd = wnd; | |
this.setName(this.getClass().getName()); | |
} | |
catch (Exception e){ | |
Catcher.catchException(e); | |
} | |
} | |
@Override | |
public void run() { | |
try { | |
while (!isInterrupted()){ | |
Socket socket = s.accept(); | |
wnd.printToLog(socket.getInetAddress().getHostAddress()+ " connected\n"); | |
ServerDispatcher sock = new ServerDispatcher(socket, this); | |
sock.start(); | |
sockets.add(sock); | |
} | |
} catch (IOException e) { | |
interrupt(); | |
} | |
} | |
@Override | |
public void interrupt() { | |
if(!isInterrupted()){ | |
super.interrupt(); | |
int n = sockets.size(); | |
for(int i=n-1; i>=0; --i) | |
sockets.get(i).interrupt(); | |
try { | |
s.setReuseAddress(true); | |
s.close(); | |
} catch (IOException e) { | |
Catcher.catchException(e); | |
} | |
} | |
} | |
synchronized public void disconnectSocket(ServerDispatcher sock){ | |
sockets.remove(sock); | |
wnd.printToLog(sock.socket.getInetAddress().getHostAddress()+ " disconnected\n"); | |
} | |
synchronized void retranslate(String m){ | |
for (ServerDispatcher listener :sockets) | |
listener.sendMessage(m+"\n"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
import java.net.Socket; | |
abstract class AbstractDispatcher extends Thread{ | |
Socket socket; | |
BufferedReader reader; | |
PrintStream printer; | |
protected AbstractDispatcher(Socket socket) { | |
this.socket = socket; | |
this.setName(this.getClass().getName()); | |
try { | |
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); | |
this.printer = new PrintStream(socket.getOutputStream()); | |
} catch (IOException e) { | |
Catcher.catchException(e); | |
} | |
} | |
public void disconnect(){ | |
try { | |
if(!socket.isClosed()) | |
socket.close(); | |
} catch (IOException e) { | |
Catcher.catchException(e); | |
} | |
} | |
public void interrupt() { | |
if(!isInterrupted()){ | |
super.interrupt(); | |
disconnect(); | |
} | |
} | |
public void sendMessage(String m){ | |
printer.println(m); | |
} | |
} | |
class ServerDispatcher extends AbstractDispatcher{ | |
Server server; | |
public ServerDispatcher(Socket socket, Server server) { | |
super(socket); | |
this.server = server; | |
} | |
@Override | |
public void run() { | |
try { | |
String str; | |
while ((str = reader.readLine()) != null) | |
server.retranslate("from "+socket.getInetAddress().getHostAddress()+":\n"+str); | |
} | |
catch (IOException e) { | |
interrupt(); | |
} | |
} | |
@Override | |
public void disconnect(){ | |
super.disconnect(); | |
server.disconnectSocket(this); | |
} | |
} | |
class ClientDispatcher extends AbstractDispatcher{ | |
MainWindow wnd; | |
public ClientDispatcher(Socket socket, MainWindow wnd) { | |
super(socket); | |
this.wnd = wnd; | |
} | |
@Override | |
public void run() { | |
try { | |
String str; | |
while ((str = reader.readLine()) != null) | |
wnd.printToChat(str.concat("\n")); | |
} catch (IOException e) { | |
interrupt(); | |
} | |
} | |
@Override | |
public void disconnect(){ | |
super.disconnect(); | |
wnd.printToLog("Disconnected from " +socket.getInetAddress().getHostAddress()+ "\n"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.net.*; | |
import java.util.InputMismatchException; | |
import java.util.regex.*; | |
public class SocketParser { | |
public static Socket parse(String text){ | |
String[] arr= text.split(":"); | |
try{ | |
return new Socket(InetAddress.getByName(arr[0]), new Integer(arr[1])); | |
} | |
catch (IOException e){ | |
Catcher.catchException(e); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment