using listeners instead of a main thread for main logic

This commit is contained in:
Daniel Collin 2015-10-20 15:52:23 +00:00
parent 3177714fc5
commit 3634a61ee5
11 changed files with 229 additions and 47 deletions

View file

@ -11,22 +11,18 @@ import com.coder.client.Session;
import com.coder.client.gui.editor.EditorWindow; import com.coder.client.gui.editor.EditorWindow;
import com.coder.client.gui.editor.EditorWindowListener; import com.coder.client.gui.editor.EditorWindowListener;
import com.coder.client.gui.login.LoginDialog; import com.coder.client.gui.login.LoginDialog;
import com.coder.client.gui.login.LoginDialogAction; import com.coder.client.gui.login.LoginDialogListener;
import com.coder.client.gui.project.SelectProjectDialog; import com.coder.client.gui.selectProject.SelectProjectDialog;
import com.coder.client.gui.project.SelectProjectDialogListener; import com.coder.client.gui.selectProject.SelectProjectDialogListener;
import com.coder.client.gui.selectServer.SelectServerDialog;
import com.coder.client.gui.selectServer.SelectServerDialogListener;
import com.coder.server.CoderServer; import com.coder.server.CoderServer;
import com.coder.server.message.CoderMessage; import com.coder.server.message.CoderMessage;
import com.coder.server.message.ConfigData;
import com.coder.server.message.ProjectListData;
import com.coder.server.message.ProjectListReqMsg; import com.coder.server.message.ProjectListReqMsg;
import com.coder.server.message.ProjectRspMsg;
import zutil.log.CompactLogFormatter; import zutil.log.CompactLogFormatter;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
public class CoderClient extends Application{ public class CoderClient extends Application{
@ -34,14 +30,17 @@ public class CoderClient extends Application{
private int port = CoderServer.SERVER_PORT; private int port = CoderServer.SERVER_PORT;
private static final int DEFAULT_CONNECTION_RETRIES = 5; private static final int DEFAULT_CONNECTION_RETRIES = 5;
private Session session; private Session session;
private String url;
private Stage mainStage; private Stage mainStage;
private int connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES; //if zero, try forever
private String url;
private String username = null; private String username = null;
private char[] password = null; private char[] password = null;
private int connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES; //if zero, try forever
private EditorWindow editorWindow; private EditorWindow editorWindow;
private LoginDialog loginDialog; private LoginDialog loginDialog;
private SelectProjectDialog selectProjectDialog; private SelectProjectDialog selectProjectDialog;
private SelectServerDialog selectServerDialog;
public static void main(String[] args) { public static void main(String[] args) {
Application.launch(args); Application.launch(args);
@ -56,6 +55,7 @@ public class CoderClient extends Application{
//parse program arguments //parse program arguments
Map<String, String> params = this.getParameters().getNamed(); Map<String, String> params = this.getParameters().getNamed();
String url = null;
String username = null; String username = null;
char[] password = null; char[] password = null;
boolean reconnectForever = false; boolean reconnectForever = false;
@ -67,11 +67,15 @@ public class CoderClient extends Application{
password = value.toCharArray(); password = value.toCharArray();
}else if(key.equals("retry-connect-forever")){ }else if(key.equals("retry-connect-forever")){
reconnectForever = true; reconnectForever = true;
}else if(key.equals("url")){
url = value;
} }
} }
//create a client instance //create a client instance
this.url = "127.0.0.1"; if(url != null){
this.url = url;
}
if(username != null){ if(username != null){
this.username = username; this.username = username;
if(password != null){ if(password != null){
@ -88,16 +92,69 @@ public class CoderClient extends Application{
this.editorWindow = new EditorWindow(); this.editorWindow = new EditorWindow();
this.loginDialog = new LoginDialog(); this.loginDialog = new LoginDialog();
this.selectProjectDialog = new SelectProjectDialog(); this.selectProjectDialog = new SelectProjectDialog();
this.selectServerDialog = new SelectServerDialog();
//register listeners //register listeners
registerListeners(); registerListeners();
//start program logic //start program logic
run(); selectServerDialog.showOnStage(mainStage);
//run();
} }
private void registerListeners() { private void registerListeners() {
this.selectServerDialog.addSelectProjectDialogListener(new SelectServerDialogListener() {
@Override
public void willShow() {
selectServerDialog.setURL(url);
}
@Override
public void cancel() {
//TODO
}
@Override
public void connect(String serverUrl) {
//selectServerDialog.hide();
url = serverUrl;
//connect session
session = Session.setupConnection(url, port);
if(session == null){
logger.warning("Could not setup a connection to " + url + ":" + port);
url = null;
selectServerDialog.showOnStage(mainStage);
}
loginDialog.showOnStage(mainStage);
}
});
this.loginDialog.addLoginDialogListener(new LoginDialogListener(){
@Override
public void willShow() {
loginDialog.setUsername(username);
loginDialog.setPassword(password);
}
@Override
public void cancel() {
//TODO
}
@Override
public void login(String uname, char[] paswd) {
username = uname;
password = paswd;
//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);
}
selectProjectDialog.showOnStage(mainStage);
}
});
this.selectProjectDialog.addSelectProjectDialogListener(new SelectProjectDialogListener() { this.selectProjectDialog.addSelectProjectDialogListener(new SelectProjectDialogListener() {
@Override @Override
public void willShow() { public void willShow() {
@ -116,17 +173,15 @@ public class CoderClient extends Application{
} }
@Override @Override
public void openProject(String selectedProjectName) { public void openProject(String selectedProjectName) {
selectProjectDialog.close();
editorWindow.showOnStage(mainStage); editorWindow.showOnStage(mainStage);
} }
@Override @Override
public void newProject() { public void newProject() {
selectProjectDialog.close();
//TODO //TODO
} }
@Override @Override
public void cancel() { public void cancel() {
selectProjectDialog.close(); //TODO
} }
}); });
@ -142,7 +197,7 @@ public class CoderClient extends Application{
session = null; session = null;
} }
} }
/*
public void run(){ public void run(){
//keep track of the number of connection retries to the server //keep track of the number of connection retries to the server
int connectionRetries = 0; int connectionRetries = 0;
@ -242,5 +297,6 @@ public class CoderClient extends Application{
// this.projectEditorWindow.dispose(); // this.projectEditorWindow.dispose();
System.exit(0); System.exit(0);
} }
*/
} }

View file

@ -52,12 +52,9 @@ public abstract class GuiWindow implements Initializable{
modalStage.showAndWait(); modalStage.showAndWait();
} }
/** public void hide(){
* hide the stage
*/
public void close(){
if(stage != null){ if(stage != null){
stage.close(); this.stage.hide();
} }
} }

View file

@ -2,6 +2,7 @@ package com.coder.client.gui.login;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -16,18 +17,20 @@ import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.gui.selectProject.SelectProjectDialogListener;
public class LoginDialog extends GuiWindow { public class LoginDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<LoginDialogListener> listeners;
@FXML private TextField usernameTextField; @FXML private TextField usernameTextField;
@FXML private PasswordField passwordPasswordField; @FXML private PasswordField passwordPasswordField;
@FXML private Button cancelButton; @FXML private Button cancelButton;
@FXML private Button loginButton; @FXML private Button loginButton;
private LoginDialogAction action;
public LoginDialog() throws IOException { public LoginDialog() throws IOException {
super(LoginDialog.class.getResource("LoginDialog.fxml")); super(LoginDialog.class.getResource("LoginDialog.fxml"));
this.listeners = new HashSet<LoginDialogListener>();
} }
@Override @Override
@ -37,8 +40,12 @@ public class LoginDialog extends GuiWindow {
@Override @Override
protected void willShow(){ protected void willShow(){
action = LoginDialogAction.CANCEL; for(LoginDialogListener listener : this.listeners){
passwordPasswordField.setText(""); listener.willShow();
}
if(!usernameTextField.getText().isEmpty() && !passwordPasswordField.getText().isEmpty()){
loginButton.fire();
}
if(!usernameTextField.getText().isEmpty()){ if(!usernameTextField.getText().isEmpty()){
passwordPasswordField.requestFocus(); passwordPasswordField.requestFocus();
} }
@ -57,31 +64,28 @@ public class LoginDialog extends GuiWindow {
@FXML @FXML
protected void login(ActionEvent event){ protected void login(ActionEvent event){
action = LoginDialogAction.LOGIN; for(LoginDialogListener listener : this.listeners){
this.close(); listener.login(usernameTextField.getText(), passwordPasswordField.getText().toCharArray());
}
} }
@FXML @FXML
protected void cancel(ActionEvent event){ protected void cancel(ActionEvent event){
action = LoginDialogAction.CANCEL; for(LoginDialogListener listener : this.listeners){
this.close(); listener.cancel();
} }
public LoginDialogAction getAction(){
return action;
} }
public void setUsername(String username){ public void setUsername(String username){
usernameTextField.setText(username); usernameTextField.setText(username);
} }
public String getUsername(){ public void setPassword(char[] password){
return usernameTextField.getText(); passwordPasswordField.setText(new String(password));
} }
public char[] getPassword(){ public void addLoginDialogListener(LoginDialogListener listener) {
//TODO: fix this since is not safe since the password will be in a string this.listeners.add(listener);
return passwordPasswordField.getText().toCharArray();
} }
} }

View file

@ -1,6 +0,0 @@
package com.coder.client.gui.login;
public enum LoginDialogAction {
LOGIN,
CANCEL
}

View file

@ -0,0 +1,9 @@
package com.coder.client.gui.login;
public interface LoginDialogListener {
public void cancel();
public void login(String username, char[] password);
public void willShow();
}

View file

@ -1,4 +1,4 @@
package com.coder.client.gui.project; package com.coder.client.gui.selectProject;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;

View file

@ -1,4 +1,4 @@
package com.coder.client.gui.project; package com.coder.client.gui.selectProject;
public interface SelectProjectDialogListener { public interface SelectProjectDialogListener {

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="217.0" prefWidth="396.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER">
<content>
<ListView fx:id="serverListView" prefHeight="200.0" prefWidth="200.0" />
</content>
</ScrollPane>
<GridPane prefHeight="77.0" prefWidth="396.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<HBox alignment="CENTER_RIGHT" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<Button fx:id="cancelButton" mnemonicParsing="false" onAction="#cancel" text="Cancel">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="connectButton" mnemonicParsing="false" onAction="#connect" text="Connect">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" />
</children>
</GridPane>
</children>
</VBox>

View file

@ -0,0 +1,68 @@
package com.coder.client.gui.selectServer;
import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import zutil.log.LogUtil;
import com.coder.client.gui.GuiWindow;
public class SelectServerDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger();
private HashSet<SelectServerDialogListener> listeners;
private String url = null;
@FXML private Button cancelButton;
@FXML private Button connectButton;
public SelectServerDialog() throws IOException {
super(SelectServerDialog.class.getResource("SelectServerDialog.fxml"));
listeners = new HashSet<SelectServerDialogListener>();
}
@Override
protected void willShow() {
for(SelectServerDialogListener listener : this.listeners){
listener.willShow();
}
if(url != null){
connectButton.fire();
}
}
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
// TODO Auto-generated method stub
}
@FXML
protected void cancel(ActionEvent event){
for(SelectServerDialogListener listener : this.listeners){
listener.cancel();
}
}
@FXML
protected void connect(ActionEvent event){
for(SelectServerDialogListener listener : this.listeners){
listener.connect(url);
}
}
public void addSelectProjectDialogListener(SelectServerDialogListener listener){
this.listeners.add(listener);
}
public void setURL(String url) {
this.url = url;
}
}

View file

@ -0,0 +1,11 @@
package com.coder.client.gui.selectServer;
public interface SelectServerDialogListener {
void willShow();
void cancel();
void connect(String url);
}