Implemented SSDP client and is now using graphical list cells in ListViews

This commit is contained in:
Daniel Collin 2015-10-22 14:08:31 +00:00
parent 120dded24f
commit 34cf5865fe
16 changed files with 428 additions and 86 deletions

View file

@ -1,42 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<GridPane prefHeight="113.0" prefWidth="294.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints>
<ColumnConstraints maxWidth="142.0" minWidth="10.0" prefWidth="76.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="228.0" minWidth="10.0" prefWidth="198.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<AnchorPane prefHeight="116.0" prefWidth="378.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="username" />
<TextField fx:id="usernameTextField" onKeyPressed="#keyPressed" prefHeight="25.0" prefWidth="291.0" GridPane.columnIndex="1" />
<Label text="password" GridPane.rowIndex="1" />
<PasswordField fx:id="passwordPasswordField" onKeyPressed="#keyPressed" prefHeight="25.0" prefWidth="291.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<HBox alignment="CENTER_RIGHT" prefHeight="69.0" prefWidth="218.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<Label layoutX="10.0" layoutY="17.0" text="username" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="17.0" />
<TextField fx:id="usernameTextField" layoutX="80.0" layoutY="13.0" onKeyPressed="#keyPressed" prefHeight="25.0" prefWidth="291.0" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="13.0" />
<Label layoutX="10.0" layoutY="48.0" text="password" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="48.0" />
<PasswordField fx:id="passwordPasswordField" layoutX="80.0" layoutY="44.0" onKeyPressed="#keyPressed" prefHeight="25.0" prefWidth="291.0" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="44.0" />
<Label fx:id="errorLabel" alignment="TOP_LEFT" layoutX="10.0" layoutY="75.0" maxWidth="1.7976931348623157E308" prefHeight="35.0" prefWidth="242.0" text="error" textFill="RED" wrapText="true" />
<HBox alignment="CENTER_RIGHT" layoutX="42.0" layoutY="34.0" prefHeight="35.0" prefWidth="200.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="0.0">
<children>
<Button fx:id="cancelButton" mnemonicParsing="false" onAction="#cancel" text="Cancel">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="loginButton" mnemonicParsing="false" onAction="#login" text="Login">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="cancelButton" mnemonicParsing="false" onAction="#cancel" text="Cancel">
<HBox.margin>
<Insets />
</HBox.margin>
</Button>
</children>
</HBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</GridPane>
</AnchorPane>

View file

@ -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);
}
}

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0" prefWidth="186.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="nameLabel" layoutX="52.0" layoutY="17.0" prefHeight="24.0" prefWidth="316.0" text="Project Name" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0">
<font>
<Font name="System Bold" size="16.0" />
</font>
</Label>
<Label fx:id="typeLabel" layoutX="30.0" layoutY="23.0" prefHeight="17.0" text="Project Type" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="30.0">
<padding>
<Insets right="15.0" />
</padding>
<font>
<Font name="System Bold Italic" size="12.0" />
</font>
</Label>
<Label fx:id="descriptionLabel" layoutX="114.0" layoutY="23.0" prefHeight="17.0" text="Description" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="117.0" AnchorPane.rightAnchor="5.0">
<font>
<Font name="System Italic" size="12.0" />
</font>
</Label>
</children>
</AnchorPane>

View file

@ -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<ProjectListItem> {
@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);
}
}
}

View file

@ -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;
}
}

View file

@ -6,12 +6,11 @@
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" prefHeight="164.0" prefWidth="396.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<ListView fx:id="projectListView" prefHeight="200.0" prefWidth="200.0" />
<ListView fx:id="projectListView" onKeyPressed="#keyPressed" onMouseClicked="#mouseClickedOnList" prefHeight="200.0" prefWidth="200.0" />
</content>
</ScrollPane>
<GridPane maxHeight="-Infinity" minHeight="-Infinity" prefHeight="50.0" prefWidth="396.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
@ -30,7 +29,7 @@
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="openProjectButton" mnemonicParsing="false" onAction="#openProject" text="Open Project">
<Button fx:id="openButton" defaultButton="true" disable="true" mnemonicParsing="false" onAction="#open" text="Open">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>

View file

@ -4,10 +4,13 @@ import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import zutil.log.LogUtil;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
@ -17,6 +20,8 @@ import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;
import com.coder.client.gui.GuiWindow;
@ -30,7 +35,9 @@ public class SelectProjectDialog extends GuiWindow {
@FXML private ListView<ProjectListItem> projectListView;
@FXML private Button newProjectButton;
@FXML private Button cancelButton;
@FXML private Button openProjectButton;
@FXML private Button openButton;
private String projectName = null;
public SelectProjectDialog() throws IOException {
super(SelectProjectDialog.class.getResource("SelectProjectDialog.fxml"));
@ -42,6 +49,11 @@ public class SelectProjectDialog extends GuiWindow {
for(SelectProjectDialogListener listener : this.listeners){
listener.willShow();
}
if(this.projectName != null){
openButton.setDisable(false);
openButton.fire();
}
openButton.setDisable(true);
}
@Override
@ -51,32 +63,41 @@ public class SelectProjectDialog extends GuiWindow {
projectListView.setCellFactory(new Callback<ListView<ProjectListItem>, ListCell<ProjectListItem>>(){
@Override
public ListCell<ProjectListItem> call(ListView<ProjectListItem> arg0) {
System.out.println("cell factory");
ListCell<ProjectListItem> cell = new ListCell<ProjectListItem>(){
@Override
protected void updateItem(ProjectListItem item, boolean empty){
System.out.println("update item: " + item);
super.updateItem(item, empty);
if(empty){
setText("");
setGraphic(null);
}
if(item != null){
setText(item.toString());
//setGraphic(null);
}
}
};
return cell;
try {
return new ProjectListCell();
} catch (IOException e) {
logger.log(Level.SEVERE, "could not crate a ProjectListCell instance", e);
}
return null;
}
});
projectListView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ProjectListItem>() {
@Override
public void changed(ObservableValue<? extends ProjectListItem> observable, ProjectListItem oldValue, ProjectListItem vewValue) {
if(observable.getValue() != null){
logger.fine("ProjectListItem [" + observable.getValue() + "] selected in the project list");
openButton.setDisable(false);
}else{
openButton.setDisable(true);
}
}
});
}
@FXML
protected void mouseClickedOnList(MouseEvent event){
if(event.getButton().equals(MouseButton.PRIMARY)){
if(event.getClickCount() == 2){ //if doublecklick
openButton.fire();
}
}
}
@FXML
protected void keyPressed(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER){
logger.fine("User pressed the ENTER key");
openProjectButton.fire();
openButton.fire();
}else if(event.getCode() == KeyCode.ESCAPE){
logger.fine("User pressed the ESCAPE key");
cancelButton.fire();
@ -108,11 +129,15 @@ public class SelectProjectDialog extends GuiWindow {
}
@FXML
protected void openProject(ActionEvent event){
protected void open(ActionEvent event){
if(this.projectName == null){
ProjectListItem selectedItem = projectListView.getSelectionModel().getSelectedItem();
projectName = selectedItem.getName();
}
for(SelectProjectDialogListener listener : this.listeners){
//TODO: get selected project in the list view
String selectedProjectName = "project name";
listener.openProject(selectedProjectName);
if(projectName != null){
listener.open(projectName);
}
}
}
@ -133,7 +158,11 @@ public class SelectProjectDialog extends GuiWindow {
@Override
protected String getTitle() {
return "Select Project";
return "Open Project";
}
public void setProject(String project) {
this.projectName = project;
}
}

View file

@ -6,7 +6,7 @@ public interface SelectProjectDialogListener {
void cancel();
void openProject(String selectedProjectName);
void open(String selectedProjectName);
void willShow();

View file

@ -5,14 +5,15 @@
<?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">
<AnchorPane xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER">
<ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" prefHeight="248.0" prefWidth="396.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<ListView fx:id="serverListView" prefHeight="200.0" prefWidth="200.0" />
<ListView fx:id="serverListView" onKeyPressed="#keyPressed" onMouseClicked="#mouseClickedOnList" prefHeight="200.0" prefWidth="200.0" />
</content>
</ScrollPane>
<GridPane prefHeight="77.0" prefWidth="396.0">
<GridPane layoutY="171.0" prefHeight="50.0" prefWidth="396.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
@ -21,14 +22,14 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<HBox alignment="CENTER_RIGHT" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1">
<HBox alignment="CENTER_RIGHT" maxHeight="-Infinity" minHeight="-Infinity" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<Button fx:id="exitButton" mnemonicParsing="false" onAction="#exit" text="Exit">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button fx:id="connectButton" mnemonicParsing="false" onAction="#connect" text="Connect">
<Button fx:id="connectButton" defaultButton="true" disable="true" mnemonicParsing="false" onAction="#connect" text="Connect">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
@ -39,4 +40,4 @@
</children>
</GridPane>
</children>
</VBox>
</AnchorPane>

View file

@ -4,11 +4,23 @@ import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;
import zutil.log.LogUtil;
@ -17,9 +29,12 @@ import com.coder.client.gui.GuiWindow;
public class SelectServerDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger();
private HashSet<SelectServerDialogListener> listeners;
private ObservableList<ServerListItem> serverList;
private String address = null;
private int port = -1;
@FXML private ListView<ServerListItem> serverListView;
@FXML private Button exitButton;
@FXML private Button connectButton;
@ -34,15 +49,60 @@ public class SelectServerDialog extends GuiWindow {
listener.willShow();
}
if(address != null && port != -1){
connectButton.setDisable(false);
connectButton.fire();
}
connectButton.setDisable(true);
}
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
// TODO Auto-generated method stub
serverList = FXCollections.observableArrayList();
serverListView.setItems(serverList);
serverListView.setCellFactory(new Callback<ListView<ServerListItem>, ListCell<ServerListItem>>(){
@Override
public ListCell<ServerListItem> call(ListView<ServerListItem> arg0) {
try {
return new ServerListCell();
} catch (IOException e) {
logger.log(Level.SEVERE, "could not crate a ServerListCell instance", e);
}
return null;
}
});
serverListView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ServerListItem>() {
@Override
public void changed(ObservableValue<? extends ServerListItem> observable, ServerListItem oldValue, ServerListItem vewValue) {
if(observable.getValue() != null){
logger.fine("ServerListItem [" + observable.getValue() + "] selected in the server list");
address = observable.getValue().getIP();
connectButton.setDisable(false);
}else{
connectButton.setDisable(true);
}
}
});
}
@FXML
protected void mouseClickedOnList(MouseEvent event){
if(event.getButton().equals(MouseButton.PRIMARY)){
if(event.getClickCount() == 2){
connectButton.fire();
}
}
}
@FXML
protected void keyPressed(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER){
logger.fine("User pressed the ENTER key");
connectButton.fire();
}else if(event.getCode() == KeyCode.ESCAPE){
logger.fine("User pressed the ESCAPE key");
exitButton.fire();
}
}
@FXML
protected void exit(ActionEvent event){
@ -68,12 +128,22 @@ public class SelectServerDialog extends GuiWindow {
public void setServerPort(int serverPort) {
this.port = serverPort;
}
@Override
protected String getTitle() {
return "Select Server";
}
public void addServerToList(String ip) {
logger.fine("Adding server \"" + ip + "\" to server list");
ServerListItem item = new ServerListItem(ip);
this.serverList.add(item);
}
public void clearServerList(){
logger.fine("Clearing server list");
serverList.clear();
}
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0" prefWidth="186.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="serverNameLabel" layoutX="52.0" layoutY="17.0" prefHeight="24.0" prefWidth="316.0" text="Server Name" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0">
<font>
<Font name="System Bold" size="16.0" />
</font>
</Label>
<Label fx:id="ipLabel" layoutX="30.0" layoutY="23.0" prefHeight="17.0" text="IP" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="10.0">
<padding>
<Insets right="15.0" />
</padding>
<font>
<Font name="System Bold Italic" size="12.0" />
</font>
</Label>
</children>
</AnchorPane>

View file

@ -0,0 +1,37 @@
package com.coder.client.gui.selectServer;
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 ServerListCell extends ListCell<ServerListItem> {
@FXML private Label ipLabel;
private Node node;
public ServerListCell() throws IOException{
FXMLLoader loader = new FXMLLoader(ServerListCell.class.getResource("ServerListCell.fxml"));
loader.setController(this);
this.node = (Node)loader.load();
}
@Override
protected void updateItem(ServerListItem item, boolean empty){
super.updateItem(item, empty);
if(empty){
setText("");
setGraphic(null);
}else if(item != null){
setText("");
ipLabel.setText(item.getIP());
setGraphic(node);
}else{
setText("NULL");
setGraphic(null);
}
}
}

View file

@ -0,0 +1,19 @@
package com.coder.client.gui.selectServer;
class ServerListItem {
private String ip = null;
public ServerListItem(String ip){
this.ip = ip;
}
public String getIP(){
return this.ip;
}
public String toString(){
return "SERVER: ip="+ip;
}
}