package clueless.view;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
import clueless.controller.GameController;
import clueless.events.ServerClientInfoEvent;
import java.net.*;
import java.text.ParseException;
import java.io.*;
/**
* SetupView
* Game setup window
* @author G2
*/
public class SetupView extends AbstractView {
/** Handle to the game controller. */
GameController controller = null;
/**
* Is user hosting the game?
*/
private boolean hostMode;
/**
* InetAddress of serverIP
* if (hostmode) serverIP will be loopback
* otherwise serverIP is manually entered by user in joinGame()
*/
private InetAddress serverIP;
/**
* TCP port for server. All users must use the same.
* GUI defaults to Port 7777
*/
private int serverPort = -1;
/**
* Number of players to wait for if hosting game [3-6]
* GUI defaults to 3
*/
private int numPlayers = 0;
/**
* SetupView() : Default Constructor
*/
public SetupView(GameController controller) {
this.controller = controller;
controller.addView(this);
modeSelect();
return;
}
/**
* modeSelect() : Gives user option to Host or Join Game
* Determines if server will be started
*/
private void modeSelect(){
jfrm = new JFrame("Host or Join Game?");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(170, 110);
jfrm.setResizable(false);
jfrm.setAlwaysOnTop(true);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setLocation((screen.width - jfrm.getWidth())/2,
(screen.height - jfrm.getHeight())/2);
JButton jbtnHost = new JButton("Host");
JButton jbtnJoin = new JButton("Join");
jbtnHost.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
hostMode = true;
jfrm.dispose();
try {
hostGame();
} catch (IOException e) {
JOptionPane.showMessageDialog(jfrm, "Network Error");
} catch (ParseException e) {
e.printStackTrace();
}
return;
}
});
jbtnJoin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
hostMode = false;
jfrm.dispose();
try {
joinGame();
} catch (ParseException e) {
e.printStackTrace();
}
return;
}
});
JLabel jlab1 = new JLabel("Welcome to Clue-Less");
JLabel jlab2 = new JLabel("Host or join game?");
jfrm.add(jlab1);
jfrm.add(jlab2);
jfrm.add(jbtnHost);
jfrm.add(jbtnJoin);
jfrm.setVisible(true);
}
/**
* hostGame() : Dialog box for user to start game server
* Setter for serverIP and serverPort
* @throws IOException
* @throws ParseException
*/
private void hostGame() throws IOException, ParseException{
String extIP = null;
// Find External IP (needed if WAN game)
try
{
URL whatismyip = new URL("http://api-nyc01.exip.org/?call=ip");
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
extIP = in.readLine();
}
catch(IOException ex)
{
System.err.println(ex.toString());
}
// Find Internal IP (needed if LAN only game)
InetAddress address = InetAddress.getLocalHost();
String intIP = address.getHostAddress();
if(extIP == null)
extIP = intIP;
jfrm = new JFrame("You are Hosting Game");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(220, 180);
jfrm.setResizable(false);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setAlwaysOnTop(true);
jfrm.setLocation((screen.width - jfrm.getWidth())/2,
(screen.height - jfrm.getHeight())/2);
JLabel external = new JLabel("WAN IP address: " + extIP);
JLabel internal = new JLabel("LAN IP address: " + intIP);
JLabel portLbl = new JLabel("Enter TCP port:");
JLabel numPlayerLbl = new JLabel("Number of Players:");
MaskFormatter portFormat = new MaskFormatter("*****");
portFormat.setValidCharacters("0123456789");
portFormat.setPlaceholderCharacter('0');
portFormat.setOverwriteMode(true);
final JFormattedTextField portField = new JFormattedTextField(portFormat);
portField.setText("07777");
MaskFormatter numPlayerFormat = new MaskFormatter("*");
numPlayerFormat.setValidCharacters("3456");
numPlayerFormat.setOverwriteMode(true);
final JFormattedTextField numPlayerField = new JFormattedTextField(numPlayerFormat);
numPlayerField.setText("3");
JButton start = new JButton("Start Server");
/**
* ActionListener for start button
*/
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
try {
serverIP = InetAddress.getLocalHost();
System.out.println(serverIP);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
try {
serverPort = Integer.parseInt(portField.getText());
numPlayers = Integer.parseInt(numPlayerField.getText());
} catch (java.lang.Exception e) {
}
// Error check user specified TCP port value
if ((serverPort < 0) || (serverPort > 65535)){
JOptionPane.showMessageDialog(jfrm, "Enter valid TCP port [0-65535]");
serverPort = -1;
}
// If valid serverPort is entered when button is pressed, dispose
if(serverPort != -1) {
controller.fireServerClientInfoEvent(new ServerClientInfoEvent(this, true, serverIP, serverPort, numPlayers));
jfrm.dispose();
return;
}
}
});
jfrm.add(external);
jfrm.add(internal);
jfrm.add(portLbl);
jfrm.add(portField);
jfrm.add(numPlayerLbl);
jfrm.add(numPlayerField);
jfrm.add(start);
jfrm.setVisible(true);
}
/**
* joinGame() : Dialog box for user to enter server IP address
* Setter for serverIP and serverPort
* @throws ParseException
* @throws Exception
*/
private void joinGame() throws ParseException {
jfrm = new JFrame("Joining Game");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(350, 110);
jfrm.setResizable(false);
jfrm.setAlwaysOnTop(true);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setLocation((screen.width - jfrm.getWidth())/2,
(screen.height - jfrm.getHeight())/2);
JLabel ipLbl = new JLabel("Enter Host IP address");
JLabel dot0 = new JLabel(".");
JLabel dot1 = new JLabel(".");
JLabel dot2 = new JLabel(".");
MaskFormatter octetFormat = new MaskFormatter("***");
octetFormat.setValidCharacters("0123456789");
octetFormat.setPlaceholderCharacter('0');
octetFormat.setOverwriteMode(true);
final JFormattedTextField oct0 = new JFormattedTextField(octetFormat);
final JFormattedTextField oct1 = new JFormattedTextField(octetFormat);
final JFormattedTextField oct2 = new JFormattedTextField(octetFormat);
final JFormattedTextField oct3 = new JFormattedTextField(octetFormat);
oct0.setColumns(2);
oct1.setColumns(2);
oct2.setColumns(2);
oct3.setColumns(2);
final JLabel portLbl = new JLabel("Enter Host TCP port");
MaskFormatter portFormat = new MaskFormatter("*****");
portFormat.setValidCharacters("0123456789");
portFormat.setPlaceholderCharacter('0');
portFormat.setOverwriteMode(true);
final JFormattedTextField portField = new JFormattedTextField(portFormat);
portField.setText("07777");
JButton join = new JButton("Join Server");
/**
* Action Listener for join button
*/
join.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
// Array that will form server IP address
int[] ipAsInts = {-1,-1,-1,-1};
byte[] ipAsBytes = new byte[4];
// Indicates if a user specified IP address is valid
boolean ipValid = false;
// Load user GUI inputs to set SetupView instance variables
try {
ipAsInts[0] = Integer.parseInt(oct0.getText());
ipAsInts[1] = Integer.parseInt(oct1.getText());
ipAsInts[2] = Integer.parseInt(oct2.getText());
ipAsInts[3] = Integer.parseInt(oct3.getText());
} catch (java.lang.Exception e) {}
try {serverPort = Integer.parseInt(portField.getText());
} catch (java.lang.Exception e) {}
// Error Check for valid IP address range
for (int i = 0; i < ipAsInts.length; i++){
if (ipAsInts[i] > 255) {
JOptionPane.showMessageDialog(jfrm, "Enter valid IP octets [0-255]");
ipValid = false;
break;
}
ipAsBytes[i] = (byte)ipAsInts[i];
ipValid = true;
}
// Error Check for valid TCP port range
if (serverPort > 65535){
JOptionPane.showMessageDialog(jfrm, "Enter valid TCP port [0-65535]");
serverPort = -1;
}
// Set serverIP and Dispose JFrame when all valid
if((serverPort != -1) && (ipValid)) {
try {
serverIP = InetAddress.getByAddress(ipAsBytes);
} catch (UnknownHostException e) {
e.printStackTrace();
}
controller.fireServerClientInfoEvent(new ServerClientInfoEvent(this, false, serverIP, serverPort, -1));
jfrm.dispose();
return;
}
}
});
jfrm.add(ipLbl);
jfrm.add(oct0);
jfrm.add(dot0);
jfrm.add(oct1);
jfrm.add(dot1);
jfrm.add(oct2);
jfrm.add(dot2);
jfrm.add(oct3);
jfrm.add(portLbl);
jfrm.add(portField);
jfrm.add(join);
jfrm.setVisible(true);
}
}