Build a Java 3-tier application from scratch – Part 6: Client view

Welcome to the final part of my tutorial. In this last part we are going to write our view and run the client application.

The client application consists of a login and a data pane. When you’ve successfully logged in, the visibility of these panes will be switched. That’s all you have to know. In case you want to use scene builder to create the client GUI here’s a picture of what you have to build:

client Scene Builder

View

If you’re too lazy simply copy the fxml definitions.

  • Update the Home fxml markup file.

Home.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.image.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="342.0" prefWidth="528.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.issueman.client.HomeView">
   <effect>
      <Glow />
   </effect>
   <children>
      <Pane fx:id="pnData" prefHeight="342.0" prefWidth="528.0" visible="false">
         <children>
            <TableView fx:id="tvEmployer" onMouseClicked="#clickTableView" prefHeight="342.0" prefWidth="317.0">
               <columns>
                  <TableColumn fx:id="tcId" prefWidth="50.0" text="ID" />
                  <TableColumn fx:id="tcName" prefWidth="135.0" text="Name" />
                  <TableColumn fx:id="tcCompany" prefWidth="131.0" text="Company" />
               </columns>
            </TableView>
            <TextField fx:id="txName" layoutX="327.0" layoutY="83.0" />
            <TextField fx:id="txCompany" layoutX="327.0" layoutY="127.0" />
            <Button fx:id="btAdd" layoutX="327.0" layoutY="171.0" mnemonicParsing="false" onAction="#clickAdd" text="Add" />
            <Button fx:id="btUpdate" layoutX="374.0" layoutY="171.0" mnemonicParsing="false" onAction="#clickUpdate" text="Update" />
            <Button fx:id="btDelete" layoutX="443.0" layoutY="171.0" mnemonicParsing="false" onAction="#clickDelete" text="Delete" />
         </children>
      </Pane>
      <Pane fx:id="pnLogin" prefHeight="342.0" prefWidth="528.0">
         <children>
            <TextField fx:id="txUsername" layoutX="171.0" layoutY="104.0" />
            <PasswordField fx:id="pfPassword" layoutX="171.0" layoutY="140.0" />
            <Button fx:id="btLogin" layoutX="236.0" layoutY="190.0" mnemonicParsing="false" onAction="#clickLogin" text="Login" />
         </children>
      </Pane>
   </children>
</AnchorPane>

Every view requires a controller, see there fx:controller="ch.issueman.client.HomeView". I’ve called this controller <view name>View.java in order to avoid using the word controller too much.

  • Upate the view handler.

HomeView.java

package ch.issueman.client;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Pane;
import ch.issueman.common.Employer;
import ch.issueman.common.User;

public class HomeView implements Initializable {

	private static Controller<Employer, Integer> controller = new Controller<Employer, Integer>(Employer.class, null);

	@FXML
	private Button btAdd;

	@FXML
	private Button btUpdate;

	@FXML
	private Button btDelete;

	@FXML
	private Button btLogin;
	
	@FXML
	private Pane pnLogin;
	
	@FXML
	private Pane pnData;
	
	@FXML
	private TextField txUsername;
	
	@FXML
	private TextField txName;
	
	@FXML
	private TextField txCompany;
	
	@FXML
	private PasswordField pfPassword;
	
	@FXML
	private TableView<Employer> tvEmployer;

	@FXML
	private TableColumn<Employer, Integer> tcId;

	@FXML
	private TableColumn<Employer, String> tcName;
	
	@FXML
	private TableColumn<Employer, String> tcCompany;
	
	public void initialize(URL arg0, ResourceBundle arg1) {
		tcId.setCellValueFactory(new PropertyValueFactory<Employer, Integer>("id"));
		tcName.setCellValueFactory(new PropertyValueFactory<Employer, String>("name"));
		tcCompany.setCellValueFactory(new PropertyValueFactory<Employer, String>("company"));
		refreshPersonTable();
	}

	public void refreshPersonTable() {
		tvEmployer.setItems(FXCollections.observableArrayList(controller.getAll()));
	}

	@FXML
	public void clickTableView() {
		Employer e = tvEmployer.getSelectionModel().getSelectedItem();
		txName.textProperty().set(e.getName());
		txCompany.textProperty().set(e.getCompany());
	}

	@FXML
	public void clickAdd() {
		controller.persist(new Employer(txName.getText(), txCompany.getText()));
		refreshPersonTable();
	}

	@FXML
	public void clickUpdate() {
		Employer e = tvEmployer.getSelectionModel().getSelectedItem();
		e.setName(txName.getText());
		e.setCompany(txCompany.getText());
		controller.update(e);
		refreshPersonTable();
	}

	@FXML
	public void clickDelete() {
		Employer e = tvEmployer.getSelectionModel().getSelectedItem();
		controller.delete(e);
		refreshPersonTable();
	}
	
	@FXML
	public void clickLogin(){
		User user = new User("", txUsername.getText(), pfPassword.getText(), "");
		controller = new Controller<Employer, Integer>(Employer.class, user);
		if(controller.login()){
			pnData.setVisible(true);
			pnLogin.setVisible(false);
		}else{
			txUsername.setText("");
			pfPassword.setText("");
		}
	}
}

Make sure that you understand this class, it’s not that difficult. Every GUI components is connected to variables and every action (click, focus, etc.) requires a method in the view handler.

Finally open the command line.

  • Navigate to the project directory: cd <project>
  • Start the webservice: gradle jettyRun
  • Run the App.java file within eclipse.
  • Open the browser on http://localhost:8080/webservice/user copy the login data from one of the users and login in with your client.

If you did everything right you should see the employer entities.

Congratulations 😀 in case you got this far you are a professional Java developer from now on.

Thanks for joining and a nice feedback in comments section.

Download Code

You can download the project from here: https://github.com/janikvonrotz/issue-manager/releases/tag/v2.2

Links

Leave a Reply