Skip to content

Instantly share code, notes, and snippets.

@frostiq
Last active August 29, 2015 13:56
Show Gist options
  • Save frostiq/9271154 to your computer and use it in GitHub Desktop.
Save frostiq/9271154 to your computer and use it in GitHub Desktop.
NetChat
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();
}
}
import javax.swing.*;
public class Catcher {
static void catchException(Exception e){
JOptionPane.showMessageDialog(null, e.toString(), "Error", JOptionPane.ERROR_MESSAGE);
//e.printStackTrace();
}
}
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();
}
}
Manifest-Version: 1.0
Main-Class: MainWindow
import java.awt.event.*;
public class NetActionButtonListener implements ActionListener{
MainWindow wnd;
public NetActionButtonListener(MainWindow wnd) {
this.wnd = wnd;
}
@Override
public void actionPerformed(ActionEvent e) {
if(!wnd.isRunning)
wnd.cmd.execute();
else
wnd.cmd.cancel();
}
}
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);
}
}
}
}
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("");
}
}
}
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");
}
}
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");
}
}
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