/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package privatechat;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.MenuEvent;
/**
*
* @author willem
* This private chat application shows your IP and waits,
* through a socket connect loop, for the peer chatter to contact you.
* When given the correct peer IP and by pushing "connect" the wait-loop
* breaks off and a new socket connection starts to connect with the peer chatter.
* After the proper handshake the receiver/ info text-area invites you
* to send a greeting (or prints an error when the connections did not work out)
* and the chat may begin (or not)!
*
*/
public class Main extends JFrame { // the main class sets the GUI and the listeners
private Color bluecolor, blackcolor, redcolor;
private Font theFont;
private int port;
private JTextField ipIn, ipOut;
private JButton send, connect, save;
private JComboBox scriptBox;
private JTextArea textIn, textOut;
private JLabel ipInLabel, ipOutLabel, scriptLabel, incomeChat, outcomeChat;
private JCheckBoxMenuItem checkbmenu1;
private ActionListener menuListener;
private ActionListener panelListener;
private SocketConnection sc1, sc2;
private enum SocketState {LISTENING, ME_CONNECTING}
private SocketState state;
private String handshake, ip;
private boolean listen;
private static int threadcount = 0;
public Main() {
bluecolor = Color.BLUE;
redcolor = Color.RED;
blackcolor = Color.BLACK;
theFont = new Font("SansSerif", Font.PLAIN, 14);
port = 1501;;
handshake = "willemprivatechat";
menuListener = new MenuListener();
panelListener = new panelListener();
addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent evt) {
}
});
Container contentPane = getContentPane();
contentPane.add(CreateGuiPanel());
setJMenuBar(createMenubars());
getIp();
sc1 = new SocketConnection(port);
// testconnect();
}
public static void main(String[] args) {
JFrame frame = new Main();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("PRIVATE CHAT");
frame.setBounds(300, 300, 700, 600);
frame.setResizable(false);
frame.setVisible(true);
}
public void testconnect() {
try {
Socket socket = new Socket("95.19.97.17", 1501); // 62.37.67.235
} catch (UnknownHostException ex) {
textIn.append(" error in host connection \n" + ex);
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
textIn.append(" i/o error of connection \n" + ex);
}
}
public JPanel CreateGuiPanel() { // all the GUI for the chat panel
// three buttons: connect, send, and save the text
send = new JButton("send");
send.setActionCommand("SEND");
send.addActionListener(panelListener);
connect = new JButton("connect");
connect.setActionCommand("CONNECT");
connect.addActionListener(panelListener);
save = new JButton("save all the chat text");
save.setActionCommand("SAVE");
save.addActionListener(panelListener);
//the text labels for the components
ipInLabel = new JLabel ("My IP address ");
ipOutLabel = new JLabel("Peer's IP address");
scriptLabel = new JLabel("Enscript the chat");
// two IP textfields
ipIn = new JTextField(12);
ipIn.setText("");
ipIn.requestFocusInWindow();
ipIn.setMaximumSize(ipIn.getPreferredSize());
ipInLabel.setLabelFor(ipIn);
ipIn.setEditable(false);
ipOut = new JTextField(12);
ipOut.setText("127.0.0.1");
ipOut.requestFocusInWindow();
ipOut.setMaximumSize(ipIn.getPreferredSize());
ipOutLabel.setLabelFor(ipOut);
ipOut.setEditable(true);
// two chat text field/ area
textIn = new JTextArea(20,55);
textIn.setLineWrap(true);
textIn.setWrapStyleWord(true);
// textIn.setPreferredSize(new Dimension(30,10));
textIn.setText("The Private Chat Application\n"
+ "is waiting to get connected.\n"
+ "when you know your peer's IP\n"
+ "write it into the box and push\n"
+ "connect and have fun.\n \n");
textIn.setFont(new Font("Serif", Font.ITALIC, 16));
textIn.setEditable(true);
textOut = new JTextArea(4,50);
textOut.setLineWrap(true);
textOut.setWrapStyleWord(true);
// textOut.setPreferredSize(new Dimension(200,30));
textOut.setFont(new Font("Serif", Font.ITALIC, 16));
textOut.setEditable(true);
JScrollPane scrollPanel1 = new JScrollPane(textIn);
JScrollPane scrollPanel2 = new JScrollPane(textOut);
//the enscript combo box
String[] scriptitems = {"No Script"};
scriptBox = new JComboBox(scriptitems);
scriptBox.setSelectedIndex(0);
scriptBox.addActionListener(menuListener);
scriptBox.setActionCommand("COMBO");
//the panel setups and named borders
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel southPanel = new JPanel(new GridLayout(2, 1));
JPanel centerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,3,3));
JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel northbuttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel southbuttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JPanel fieldPanel = new JPanel(new GridLayout(2, 1));
JPanel ipInPanel = new JPanel(new GridLayout(1, 2));
JPanel ipOutPanel = new JPanel(new GridLayout(1, 2));
JPanel buttonCombo = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JPanel textPanel = new JPanel(new GridLayout(2, 1));
// the south panel
ipInPanel.add(ipInLabel);
ipInPanel.add(ipIn);
ipOutPanel.add(ipOutLabel);
ipOutPanel.add(ipOut);
fieldPanel.add(ipInPanel);
fieldPanel.add(ipOutPanel);
southPanel.add(fieldPanel);
buttonCombo.add(connect);
buttonCombo.add(scriptBox);
northPanel.add(fieldPanel);
northPanel.add(buttonCombo);
//the center panel
centerPanel.setBackground(Color.WHITE);
centerPanel.add(scrollPanel1);
//the north panel
JPanel textoutPanel = new JPanel(new FlowLayout());
textoutPanel.add(scrollPanel2);
textoutPanel.add(send);
southbuttonPanel.add(save);
southPanel.add(textoutPanel);
southPanel.add( southbuttonPanel);
// all of the chat panel
mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(northPanel, BorderLayout.NORTH);
mainPanel.add(southPanel, BorderLayout.SOUTH);
return mainPanel;
}
public JMenuBar createMenubars() { // the menubar plus items (not working yet)
JMenuBar menuBar = new JMenuBar();
JMenu setup = new JMenu("More Options");
checkbmenu1 = new JCheckBoxMenuItem("test");
checkbmenu1.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
checkbmenu1.setHorizontalAlignment(checkbmenu1.LEADING);
// menuItem1.setMnemonic(KeyEvent.VK_C);
JCheckBoxMenuItem checkbmenu2 = new JCheckBoxMenuItem("select all");
checkbmenu2.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
checkbmenu2.setHorizontalAlignment(checkbmenu2.LEADING);
JMenuItem menuItem1 = new JMenuItem("Handshake");
JMenuItem menuItem2 = new JMenuItem("Set Port");
JMenuItem menuItem3 = new JMenuItem("Send File");
JMenuItem menuItem4 = new JMenuItem("Quit");
menuItem1.addActionListener(menuListener);
menuItem2.addActionListener(menuListener);
menuItem3.addActionListener(menuListener);
menuItem4.addActionListener(menuListener);
checkbmenu1.addActionListener(menuListener);
checkbmenu2.addActionListener(menuListener);
setup.add(menuItem1);
setup.add(menuItem2);
setup.add(checkbmenu1);
setup.add(checkbmenu2);
setup.add(menuItem3);
setup.add(menuItem4);
menuBar.add(setup);
return menuBar;
}
public synchronized void setThreadCount() {
threadcount = threadcount + 1;
System.out.println("ip count " + threadcount);
}
public synchronized int getThreadCount() {
return threadcount;
}
public void getIp() {
try {
ipIn.setText(Inet4Address.getLocalHost().getHostAddress());
} catch (UnknownHostException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
class MenuListener implements ActionListener { // not working yet
public void menuSelected(MenuEvent me) {
}
public void menuDeselected(MenuEvent me) {
}
public void menuCanceled(MenuEvent me) {
}
public void actionPerformed(ActionEvent ae) {
}
}
class panelListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("CONNECT")) {
// start the outgoing call constructor
sc2 = new SocketConnection(ipOut.getText(), port);
sc1.closeConnection();
sc1.interrupt();
}
if (cmd.equals("SEND")) { // sends the chat message
String line = null;
line = textOut.getText();
textIn.append("Me: " + line + "\n");
textOut.setText("");
if (state.equals(SocketState.LISTENING))
sc1.transmit().println(line + "\n");
if (state.equals(SocketState.ME_CONNECTING))
sc2.transmit().println(line + "\n");
}
if (cmd.equals("SAVE")) { // not working
System.out.println("save");
}
}
}
/**
*
* The second private inner class takes care of the socket connections.
*
*
*
*/
private class SocketConnection extends Thread {
private int port;
private String ip = null;
private Socket socket;
private ServerSocket server;
PrintWriter socketout;
public SocketConnection(int port) {
state = SocketState.LISTENING; // incoming/ waiting for caller
listen = true;
this.port = port;
start();
setThreadCount();
System.out.println("first socket constructor");
}
public SocketConnection(String ip, int port) {
state = SocketState.ME_CONNECTING; // sending/ calling out to peer
this.ip = ip;
this.port = port;
start();
setThreadCount();
System.out.println("second socket constructor");
}
public void run() {
try {
/* Here, waiting for the peer to connect.
* When connected the waiting socket "server" shuts down.
* Or the waiting-clause gets interrupted when the
* application calls out to the peer through "connect".
* For this action one needs the IP of the peer.
*/
if (state.equals(SocketState.LISTENING)) {
server = new ServerSocket(port);
textIn.append(" listening to incoming calls, state " +
state + "\n" +
" threadcount >>> " + getThreadCount() + "\n" +
" portnumber " + port + "\n\n");
socket = server.accept(); // handle the connection here
server.close();
textIn.append(" connecting to incoming call, state " +
state + "\n" +
" threadcount >>> " + getThreadCount() + "\n" +
" is server closed >>> " + server.isClosed() + "\n" +
" socket >>> " + socket + "\n" +
" port: " + port + "\n\n");
}
else
/* From here, the application calls out.
* It is important to know that the same application
* waits for calls passively and calls out actively,
* depending on: if (state == SocketState.ME_CONNECTING){
*
*/
if (state.equals(SocketState.ME_CONNECTING)) {
socket = new Socket(ip, port);
// socket.setSoTimeout(5000); // time out after 10 seconds
textIn.append(" calling out connecting to, state " +
state + "\n" +
" ID " + ip + "\n" +
" port " + port + "\n" +
" threadcount >>> " + getThreadCount() + "\n" +
" server >>> " + server + "\n" +
" socket >>> " + socket + "\n" + "\n\n");
}
/* From here on a connection is established, either
* passive or active and the chat routine of Me and Peer
* should begin.... or not.....
*
*/
}
catch (IOException ex) {
textIn.append(" socket catch, state " + state + " > " +
" threadcount >>> " + getThreadCount() + "\n" +
" IP >>> " + ip + "\n" +
" port >>> " + port + "\n" +
" socket >>> " + socket + "\n" +
" socket >>> " + socket + "\n" +
ex + "\n\n");
}
/* The reading and writing methods
* concerning the chat communication
* (reading and writing happens simultaneously)
*
*/
if (socket != null) {
try { // reading and sending text lines
textIn.append(" getting into buffer connection state " +
state + "\n" +
" threadcount >>> " + getThreadCount() + "\n" +
" socket >>> " + socket + "\n" +
" IP >>> " + ip + "\n" +
" port >>> " + port + "\n" +
"\n\n" );
String linein;
BufferedReader socketin = new BufferedReader (new
InputStreamReader(socket.getInputStream()));
// the socketout is connected with the "send" button
// see at the buttom the transmite method!
socketout = new PrintWriter
(socket.getOutputStream(), true /*autoFlush */);
while ((linein = socketin.readLine()) != null) {
if (!linein.equals(""))
textIn.append("peer: " + linein + "\n");
}
}
catch(Exception e) {
textIn.append(" communication error, state " + state + " > " + e
+ " socket " + socket + "\n\n");
}
finally {
closeConnection();
}
}
else textIn.append(" socket is null no communication \n\n");
} // end of the run method
public boolean Handschake(String handshake, String hnd) { // not working yet
if (handshake.equals(hnd))
return true;
else
return false;
}
public PrintWriter transmit() { // communicating with the GUI main clase
if (socketout == null)
textIn.append(" The socked for transmission is null \n\n");
return socketout;
}
public boolean Serverclossed() {
return server.isClosed();
}
void closeConnection() { // close and clean up both sockets
try {
if (server != null && !server.isClosed()) {
server.close();
textIn.append(" server socket closseddddddd " + "\n\n");
}
else
if (socket != null && !socket.isClosed()) {
socket.close();
textIn.append(" socket clossedddddddddd " + "\n\n");
}
}
catch (IOException ex) {
textIn.append(" error in clossing connections \n");
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex + "\n\n");
}
}
} // end of the inner class
}