After waiting a long time for it , finally javafx 2.0 beta was released.
I downloaded netbeans IDE 7 and Javafx FX 2.0 plugin. After playing with several javafx sample projects everthing seemed fine and I decided to develop a new application based on my sample finance project available at
http://code.google.com/p/seahorse-ria-framework/downloads/list.
You can also download javafx 2.0 based sample client application from
http://code.google.com/p/seahorse-ria-framework/downloads/list.
Sample javaFX client application contains a login and customer search page. For the authentication and customer search operations JEE based server side application is called from JSE based javaFX application.
I already had sample server side business project uploaded to google code, so I needed only to develop javaFX based rich client application that calls existing server based application.
Developing a sample application took several hours, most of job was coping codes from javafx samples projects into my sample project. A few thing did not worked as I expected.(promp text ) .
Generally everthing was fine and it was very simple to develop an application with Javafx 2.0.
Following diagram shows software architecture of sample application;
Following code segment shows login page;
package com.seahorse.test.javafx;
import com.seahorse.bean.config.property.PropertyHelper;
import com.seahorse.bean.constant.SeaHorseConstants;
import com.seahorse.bean.container.BeanHelper;
import com.seahorse.common.util.ExceptionUtil;
import com.seahorse.support.web.SeaHorseStandaloneInitializer;
import com.seahorse.test.service.LoginService;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
public class Login extends Application {
final Label messageLabel = new Label("");
@Override
public void start(final Stage stage) {
Image image = new Image(getClass().getResourceAsStream("not.png"));
messageLabel.setGraphic(new ImageView(image));
messageLabel.setTextFill(Color.web("#0076a3"));
messageLabel.setTextAlignment(TextAlignment.JUSTIFY);
messageLabel.setWrapText(true);
messageLabel.setMaxWidth(300);
GridPane grid = new GridPane();
grid.setPadding(new Insets(0, 10, 10, 10));
grid.setVgap(5);
grid.setHgap(5);
Label userIdLabel = new Label("User Id");
GridPane.setConstraints(userIdLabel, 0, 0);
grid.getChildren().add(userIdLabel);
final TextBox userIdText = new TextBox();
userIdText.setText("1");
userIdText.setPromptText("Enter User id");
userIdText.setColumns(20);
GridPane.setConstraints(userIdText, 1, 0);
grid.getChildren().add(userIdText);
Label passwordLabel = new Label("Password");
GridPane.setConstraints(passwordLabel, 0, 1);
grid.getChildren().add(passwordLabel);
final PasswordBox passwordText = new PasswordBox();
passwordText.setText("seahorse");
passwordText.setPromptText("Enter password");
GridPane.setConstraints(passwordText, 1, 1);
grid.getChildren().add(passwordText);
final Button submit = new Button("Login");
submit.setOnMouseEntered(new EventHandler
() {
@Override public void handle(MouseEvent e) {
submit.setScaleX(1.25);
submit.setScaleY(1.25);
}
});
submit.setOnMouseExited(new EventHandler() {
@Override public void handle(MouseEvent e) {
submit.setScaleX(1);
submit.setScaleY(1);
}
});
Button clear = new Button("Clear");
HBox hbButton = new HBox();
hbButton.setPadding(new Insets(5, 0, 0, 0));
hbButton.setSpacing(10);
hbButton.getChildren().addAll( submit,clear);
GridPane.setConstraints(hbButton, 1, 2);
grid.getChildren().add(hbButton);
submit.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent e) {
if (userIdText.getText() == null
userIdText.getText().isEmpty()
passwordText.getText() == null
passwordText.getText().isEmpty() ) {
messageLabel.setText("User Id and password can not be empty!");
return;
}
LoginService loginService = BeanHelper.getBean(LoginService.class);
boolean isAuthorized = false;
try {
isAuthorized = loginService.login(Integer.valueOf(userIdText.getText()).intValue() , passwordText.getText() );
} catch (Exception ex) {
messageLabel.setText(ExceptionUtil.handleException(ex).getMessage());
messageLabel.setTextFill(Color.rgb(210, 39, 30));
}
if (isAuthorized) {
CustomerSearch ll = new CustomerSearch();
ll.start(stage);
}
}
});
clear.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent e) {
userIdText.clear();
passwordText.clear();
messageLabel.setText("");
}
});
VBox vb = new VBox();
vb.setPadding(new Insets(10, 0, 0, 10));
vb.setSpacing(10);
vb.getChildren().addAll( messageLabel,grid);
final Scene scene = new Scene(vb, 300, 150);
stage.setScene(scene);
stage.setTitle("Login Page");
stage.setVisible(true);
}
public static void main(String[] args) {
SeaHorseStandaloneInitializer.initialize();
//weblogic (check port number)
PropertyHelper.getPropertyManager().setProperty(SeaHorseConstants.DEFAULT_REMOTE_SERVER_NAME, http://localhost:7001/remote/remote/);
Application.launch(args);
}
}
After running login , following login page is displayed
When login button is pressed, login service on remote server will be called using the following code segment
LoginService loginService = BeanHelper.getBean(LoginService.class);
boolean isAuthorized = false;
try {
isAuthorized = loginService.login(Integer.valueOf(userIdText.getText()).intValue() , passwordText.getText() );
after successfull login, customer search page is called using the following code segment;
package com.seahorse.test.javafx;
import com.seahorse.bean.container.BeanHelper;
import com.seahorse.common.util.ExceptionUtil;
import com.seahorse.test.model.Customer;
import com.seahorse.test.service.CustomerService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextBox;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class CustomerSearch {
final TextBox searchText = new TextBox();
private TableView
tableView;
private ObservableList tableItems;
public static class CustomerFX {
private IntegerProperty customerId;
public void setCustomerId(Integer value) {
customerIdProperty().set(value);
}
public Integer getCustomerId() {
return customerId.get();
}
public IntegerProperty customerIdProperty() {
if (customerId == null) {
customerId = new IntegerProperty();
}
return customerId;
}
private StringProperty name;
public void setName(String value) {
nameProperty().set(value);
}
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
if (name == null) {
name = new StringProperty();
}
return name;
}
private StringProperty surname;
public void setSurname(String value) {
surnameProperty().set(value);
}
public String getSurname() {
return surname.get();
}
public StringProperty surnameProperty() {
if (surname == null) {
surname = new StringProperty();
}
return surname;
}
}
public void start(Stage primaryStage) {
primaryStage.setWidth(500);
primaryStage.setHeight(400);
primaryStage.setTitle("Customer Search Page");
VBox vb = new VBox();
vb.setPadding(new Insets(10, 10, 10, 10));
vb.setSpacing(10);
Scene scene = new Scene(vb, 500, 400, Color.BEIGE);
// searchText.setPromptText("Enter Customer id"); does not work!!
searchText.setColumns(20);
Label searchLabel = new Label("Search:");
HBox searchBox = new HBox();
searchBox.setSpacing(5);
searchBox.setAlignment(Pos.CENTER_LEFT);
searchBox.getChildren().addAll(searchLabel, searchText);
final ChoiceBox cb = new ChoiceBox(FXCollections.observableArrayList(
"Customer ID", "First Name", "Last Name"));
cb.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() {
public void changed(ObservableValue ov, Number value, Number new_value) {
if (new_value.intValue() == 0) {
searchText.clear();
//searchText.setPromptText("Enter Customer id"); // does not workkkk!!!
} else if (new_value.intValue() == 1) {
searchText.clear();
//searchText.setPromptText("Enter First Name");
} else {
searchText.clear();
//searchText.setPromptText("Enter Last Name");
}
}
});
Label criteriaLabel = new Label("Using:");
HBox criteriaBox = new HBox();
criteriaBox.setSpacing(5);
criteriaBox.setAlignment(Pos.CENTER_LEFT);
criteriaBox.getChildren().addAll(criteriaLabel, cb);
Button searchButton = new Button();
searchButton.setText("Search");
Button btnClear = new Button();
btnClear.setText("Clear");
btnClear.setOnAction(new EventHandler() {
public void handle(ActionEvent event) {
tableItems.clear();
cb.getSelectionModel().selectFirst();
}
});
HBox hbButtonBox = new HBox();
hbButtonBox.setPadding(new Insets(5, 0, 0, 0));
hbButtonBox.setSpacing(10);
hbButtonBox.getChildren().addAll(searchBox, criteriaBox, searchButton, btnClear);
searchButton.setOnAction(new EventHandler() {
public void handle(ActionEvent event) {
btnSearchPressed(cb.getSelectionModel().getSelectedIndex(), searchText);
}
});
primaryStage.setScene(scene);
primaryStage.setVisible(true);
tableItems = FXCollections.observableArrayList();
tableView = new TableView(tableItems);
TableColumn col1 = new TableColumn("Cust ID");
TableColumn col2 = new TableColumn("First Name");
TableColumn col3 = new TableColumn("Last Name");
col1.setProperty("customerId");
col2.setProperty("name");
col3.setProperty("surname");
tableView.getColumns().setAll(col1, col2, col3);
vb.getChildren().addAll(hbButtonBox, tableView);
}
public void btnSearchPressed(int selection, TextBox searchText) {
CustomerService customerService = BeanHelper.getBean(CustomerService.class);
List customers = null;
try {
if (selection == 0) {
if (searchText.getText() == null || searchText.getText().isEmpty()) {
tableItems.clear();
return;
}
Customer cust = customerService.getCustomer(Integer.valueOf(searchText.getText()).longValue());
List list = new ArrayList();
list.add(cust);
customers = list;
} else if (selection == 1) {
customers = customerService.getCustomersByFirstName(searchText.getText());
} else {
customers = customerService.getCustomersByLastName(searchText.getText());
}
fillTable(customers);
} catch (Exception ex) {
tableItems.clear();
Logger.getLogger(CustomerSearch.class.getName()).log(Level.SEVERE, null, ExceptionUtil.handleException(ex).getMessage());
}
}
public void fillTable(List customers) {
tableItems.clear();
if (customers == null || customers.isEmpty()) {
return;
}
ObservableList newItems = FXCollections.observableArrayList();
for (int i = 0; i < customers.size(); i++) {
CustomerFX p = new CustomerFX();
Customer customer = customers.get(i);
p.setName(customer.getName());
p.setSurname(customer.getSurname());
p.setCustomerId(Integer.valueOf((int) customer.getCustomerId()));
newItems.add(p);
}
tableView.getItems().setAll(newItems);
}
}
after successfull login, customer search page is displayed; you can search customers according to customer id, name and last name.
Labels: javafx, javafx 2.0, javafx 2.0 beta, javafx 2.0 enterprise application, javafx 2.0 sample application