diff --git a/lib/controlsfx-8.20.9-LICENSE.txt b/lib/controlsfx-8.20.9-LICENSE.txt new file mode 100644 index 0000000..3985baa --- /dev/null +++ b/lib/controlsfx-8.20.9-LICENSE.txt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2013, 2014, ControlsFX + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of ControlsFX, any associated website, nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/src/com/coder/client/CoderClient.java b/src/com/coder/client/CoderClient.java index 57a9689..17a65a6 100644 --- a/src/com/coder/client/CoderClient.java +++ b/src/com/coder/client/CoderClient.java @@ -5,8 +5,6 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JOptionPane; - import com.coder.client.Session; import com.coder.client.gui.editor.EditorWindow; import com.coder.client.gui.editor.EditorWindowListener; @@ -25,6 +23,9 @@ import com.coder.server.message.ProjectRspMsg; import zutil.log.CompactLogFormatter; import zutil.log.LogUtil; +import zutil.net.ssdp.SSDPClient; +import zutil.net.ssdp.SSDPClient.SSDPServiceListener; +import zutil.net.ssdp.StandardSSDPInfo; import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; @@ -45,7 +46,12 @@ public class CoderClient extends Application{ private String serverURL = null; private int serverPort = CoderServer.SERVER_PORT; private String username = null; - private char[] password = null; + private char[] password = null; //should only be anything else than null if defined by program argument + private String loginErrorMessage = ""; + private String project = null; + + //services + SSDPClient ssdpClient; public static void main(String[] args) { Application.launch(args); @@ -74,13 +80,15 @@ public class CoderClient extends Application{ }catch(NumberFormatException e){ logger.warning("port argument to program is not of a integer type. using default port."); } + }else if(key.equals("project")){ + this.project = value; } } if(this.username == null){ //ignore the password if no username was set this.password = null; } - //loading GUI + //setup GUI elements this.mainStage = mainStage; mainStage.setTitle("CoderClient"); try{ @@ -90,6 +98,15 @@ public class CoderClient extends Application{ setupEditWindow(); }catch(IOException e){ logger.log(Level.SEVERE, "could not load all GUI elements", e); + System.exit(1); + } + + //setup SSDP client + try{ + setupSSDPClient(); + }catch(IOException e){ + logger.log(Level.SEVERE, "could not setup SSDP client", e); + System.exit(1); } //start program logic @@ -103,6 +120,13 @@ public class CoderClient extends Application{ @Override public void willShow() { closeCurrentSession(); + ssdpClient.clearServices(); + selectServerDialog.clearServerList(); + if(ssdpClient != null){ + ssdpClient.requestService("coder:discover"); + }else{ + logger.severe("could not send a SSDP request since the client is not setup"); + } selectServerDialog.setServerAddress(serverURL); selectServerDialog.setServerPort(serverPort); } @@ -121,13 +145,13 @@ public class CoderClient extends Application{ if(session == null){ logger.warning("Could not setup a connection to " + serverURL + ":" + port); serverURL = null; + serverPort = CoderServer.SERVER_PORT; selectServerDialog.showOnStage(mainStage); }else{ loginDialog.showOnStage(mainStage); } } }); - } private void setupLoginDialog() throws IOException { @@ -137,6 +161,7 @@ public class CoderClient extends Application{ public void willShow() { loginDialog.setUsername(username); loginDialog.setPassword(password); + loginDialog.setErrorMessage(loginErrorMessage); } @Override public void cancel() { @@ -151,14 +176,16 @@ public class CoderClient extends Application{ //authenticate session boolean authenticated = session.authenticate(username, password); if(!authenticated){ - JOptionPane.showMessageDialog(null, "Wrong username or password", "Authentication Failed", JOptionPane.INFORMATION_MESSAGE); logger.severe("Authentication failed: wrong username or password"); password = null; - loginDialog.showOnStage(mainStage); + loginErrorMessage = "Wrong username or password"; + selectServerDialog.showOnStage(mainStage); + }else{ + loginErrorMessage = ""; + setupSessionListener(); //resister a message listener to the session + session.start(); //start receiving traffic from the server + selectProjectDialog.showOnStage(mainStage); } - setupSessionListener(); //resister a message listener to the session - session.start(); //start receiving traffic from the server - selectProjectDialog.showOnStage(mainStage); } private void setupSessionListener(){ session.addCoderMessageReceivedListener(new CoderMessageReceivedListener() { @@ -187,17 +214,22 @@ public class CoderClient extends Application{ } }); } - + private void setupSelectProjectDialog() throws IOException { this.selectProjectDialog = new SelectProjectDialog(); this.selectProjectDialog.addSelectProjectDialogListener(new SelectProjectDialogListener() { @Override public void willShow() { selectProjectDialog.clearProjectList(); - sendProjectListReq(); + if(project == null){ + sendProjectListReq(); + }else{ + selectProjectDialog.setProject(project); + } } @Override - public void openProject(String selectedProjectName) { + public void open(String selectedProjectName) { + project = selectedProjectName; editorWindow.showOnStage(mainStage); } @Override @@ -247,6 +279,25 @@ public class CoderClient extends Application{ }); } + private void setupSSDPClient() throws IOException{ + this.ssdpClient = new SSDPClient(); + ssdpClient.setListener(new SSDPServiceListener() { + @Override + public void newService(final StandardSSDPInfo service) { + if(selectServerDialog != null){ + Platform.runLater(new Runnable() { + @Override + public void run() { + String ip = service.getInetAddress().getHostAddress(); + selectServerDialog.addServerToList(ip); + } + }); + } + } + }); + ssdpClient.start(); + } + private void closeCurrentSession(){ if(this.session != null){ logger.info("disconnecting from server"); diff --git a/src/com/coder/client/Session.java b/src/com/coder/client/Session.java index 7059f5f..2d246d7 100644 --- a/src/com/coder/client/Session.java +++ b/src/com/coder/client/Session.java @@ -70,11 +70,11 @@ public class Session extends Thread { try { msg = in.readGenericObject(); } catch (IOException e) { - //logger.log(Level.SEVERE, "socket is probably closed by the peer", e); + logger.log(Level.FINE, "socket was probably closed by the peer", e); break; } if(msg == null){ - //logger.severe("socket is probably closed by the peer"); + logger.fine("socket was probably closed by the peer"); break; }else{ handleMessage(msg); diff --git a/src/com/coder/client/gui/login/LoginDialog.fxml b/src/com/coder/client/gui/login/LoginDialog.fxml index 4695360..f62f5d5 100644 --- a/src/com/coder/client/gui/login/LoginDialog.fxml +++ b/src/com/coder/client/gui/login/LoginDialog.fxml @@ -1,42 +1,33 @@ + - - - - - - - - - - + + - - - - - + diff --git a/src/com/coder/client/gui/login/LoginDialog.java b/src/com/coder/client/gui/login/LoginDialog.java index 318502d..68a859c 100644 --- a/src/com/coder/client/gui/login/LoginDialog.java +++ b/src/com/coder/client/gui/login/LoginDialog.java @@ -11,6 +11,7 @@ import zutil.log.LogUtil; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.input.KeyCode; @@ -26,6 +27,7 @@ public class LoginDialog extends GuiWindow { @FXML private PasswordField passwordPasswordField; @FXML private Button cancelButton; @FXML private Button loginButton; + @FXML private Label errorLabel; public LoginDialog() throws IOException { super(LoginDialog.class.getResource("LoginDialog.fxml")); @@ -34,7 +36,7 @@ public class LoginDialog extends GuiWindow { @Override public void initialize(URL fxmlFileLocation, ResourceBundle resources) { - + errorLabel.setText(""); } @Override @@ -42,11 +44,14 @@ public class LoginDialog extends GuiWindow { for(LoginDialogListener listener : this.listeners){ listener.willShow(); } - if(!usernameTextField.getText().isEmpty() && !passwordPasswordField.getText().isEmpty()){ + if(usernameTextField.getText() != null && !usernameTextField.getText().isEmpty() && passwordPasswordField.getText() != null && !passwordPasswordField.getText().isEmpty()){ loginButton.fire(); - } - if(!usernameTextField.getText().isEmpty()){ - passwordPasswordField.requestFocus(); + }else{ + if(errorLabel.getText() != null && errorLabel.getText().isEmpty() && usernameTextField.getText() != null && !usernameTextField.getText().isEmpty()){ + passwordPasswordField.requestFocus(); + }else{ + usernameTextField.requestFocus(); + } } } @@ -96,4 +101,8 @@ public class LoginDialog extends GuiWindow { return "Login"; } + public void setErrorMessage(String msg) { + errorLabel.setText(msg); + } + } diff --git a/src/com/coder/client/gui/selectProject/ProjectListCell.fxml b/src/com/coder/client/gui/selectProject/ProjectListCell.fxml new file mode 100644 index 0000000..b9200d1 --- /dev/null +++ b/src/com/coder/client/gui/selectProject/ProjectListCell.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + diff --git a/src/com/coder/client/gui/selectProject/ProjectListCell.java b/src/com/coder/client/gui/selectProject/ProjectListCell.java new file mode 100644 index 0000000..e9b796b --- /dev/null +++ b/src/com/coder/client/gui/selectProject/ProjectListCell.java @@ -0,0 +1,42 @@ +package com.coder.client.gui.selectProject; + +import java.io.IOException; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; + +class ProjectListCell extends ListCell { + + @FXML private Label nameLabel; + @FXML private Label typeLabel; + @FXML private Label descriptionLabel; + private Node node; + + public ProjectListCell() throws IOException{ + FXMLLoader loader = new FXMLLoader(ProjectListCell.class.getResource("ProjectListCell.fxml")); + loader.setController(this); + this.node = (Node)loader.load(); + } + + @Override + protected void updateItem(ProjectListItem item, boolean empty){ + super.updateItem(item, empty); + if(empty){ + setText(""); + setGraphic(null); + }else if(item != null){ + setText(""); + nameLabel.setText(item.getName()); + typeLabel.setText(item.getType()); + descriptionLabel.setText(item.getDescription()); + setGraphic(node); + }else{ + setText("NULL"); + setGraphic(null); + } + } + +} diff --git a/src/com/coder/client/gui/selectProject/ProjectListItem.java b/src/com/coder/client/gui/selectProject/ProjectListItem.java index dfa5f78..b1b94e9 100644 --- a/src/com/coder/client/gui/selectProject/ProjectListItem.java +++ b/src/com/coder/client/gui/selectProject/ProjectListItem.java @@ -1,18 +1,30 @@ package com.coder.client.gui.selectProject; -public class ProjectListItem { - private String projectName; +class ProjectListItem { + private String name; private String type; private String description; public ProjectListItem(String projectName, String type, String description) { - this.projectName = projectName; + this.name = projectName; this.type = type; this.description = description; } + public String getName(){ + return this.name; + } + + public String getType(){ + return this.type; + } + + public String getDescription(){ + return this.description; + } + public String toString(){ - return "ProjectName="+projectName+", type="+type+", description="+description; + return "PROJECT: ProjectName="+name+", type="+type+", description="+description; } } diff --git a/src/com/coder/client/gui/selectProject/SelectProjectDialog.fxml b/src/com/coder/client/gui/selectProject/SelectProjectDialog.fxml index e129cad..a71c0c2 100644 --- a/src/com/coder/client/gui/selectProject/SelectProjectDialog.fxml +++ b/src/com/coder/client/gui/selectProject/SelectProjectDialog.fxml @@ -6,12 +6,11 @@ - - + @@ -30,7 +29,7 @@ - -