jeudi 27 septembre 2012

Put it all together (JavaFX 2.x Custom component, FXML, JAX-RS 2.0 client API)

In my last post, I wrote about how to make custom component compatible with FXML and how to use it in an application.
Before that, I had tested the client API of JAX-RS 2.0 (with JSON and XML serialization).
And now, when I’m putting them together, I can write a small JavaFX 2 application which consumes REST services.

1. The REST service
For the REST service, I have used the same service that I used for try the JAX-RS 2.0 client API.

2. The JAX-RS 2.0 client API
For the JAX-RS 2.0 client API, I have upgraded to Jersey 2.0-m07.
This version fixes the JERSEY-1143 issue and changes the way to declare JSON implementation.

The XML version 
protected List<Music> findArtistByName(String artistBeginBy){
          
          Client client = ClientFactory.newClient();
                  
          GenericType<List<Music>> listm = new GenericType<List<Music>>() {};
          
          List<Music> listMusic = client.target("http://localhost:8080/RESTfulServices/rs/ArtisteNameBeginningBy/{beginBy}")         
                         .pathParam("beginBy", artistBeginBy)
                         .request(MediaType.APPLICATION_XML)
                         .get(listm);
          
          return listMusic;
      }  
The JSON version
For the JSON version of the client, I have used Jackson implementation.
protected List<Music> findArtistByName(String artistBeginBy){
           
          Client client = ClientFactory.newClient();
          
          client.configuration().register(new JacksonFeature());   
          
          ListMusic listMusic = client.target("http://localhost:8080/RESTfulServices/rs/ArtisteNameBeginningBy/{beginBy}")
                         .pathParam("beginBy", artistBeginBy)
                         .request(MediaType.APPLICATION_JSON)
                         .get(ListMusic.class); 
          
          if (listMusic==null){
              listMusic = new ListMusic();
          }
   
          return listMusic.getMusic();
       } 
3. The application
The application is based on the application that I wrote to show how to use a custom component with FXML.
I just have added one Table control to show the result of the query and called the REST service in handleSearchTextBoxSearchEvent method of the controller to fill the Table control.

The UI

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import com.paddyweblog.control.*?>


<VBox id="vBox1"  
          prefWidth="600.0"
          spacing="10.0"
          xmlns:fx="http://javafx.com/fxml" 
          fx:controller="putItAllTogether.Screen1">
    <children>
        <HBox id="hBox1" alignment="CENTER" spacing="10.0" >
            <children>
                <Label id="label1" contentDisplay="CENTER" text="Size font Text Search Text Box" />
                <ComboBox id="comboBox1" fx:id="comboBox1" onAction="#handleComboBoxAction" >
                    <items>
                        <FXCollections fx:factory="observableArrayList">
                            <String fx:value="10" />
                            <String fx:value="13" />
                            <String fx:value="15" />
                            <String fx:value="20" />
                            <String fx:value="25" />
                            <String fx:value="30" />
                            <String fx:value="35" />
                            <String fx:value="40" />
                            <String fx:value="45" />
                        </FXCollections>
                    </items>
                </ComboBox>
            </children>
        </HBox>
    </children>
    <children>
        <SearchTextBox fx:id="searchTextBox1" 
                       onCrossButtonMouseClicked="#handleSearchTextBoxCrossButtonOnMouseClicked" 
                       onSearchEvent="#handleSearchTextBoxSearchEvent">    
        </SearchTextBox>
    </children>
    <children>
        <TableView fx:id="tableView" >
            <columns>
                <TableColumn text="ID"  prefWidth="49">
                    <cellValueFactory><PropertyValueFactory property="id" />
                    </cellValueFactory>
                </TableColumn>
                <TableColumn text="Artist Name" prefWidth="149">
                    <cellValueFactory><PropertyValueFactory property="artisteName" />
                    </cellValueFactory>
                </TableColumn>
                <TableColumn text="Album Name" prefWidth="400">
                    <cellValueFactory><PropertyValueFactory property="albumTitle" />
                    </cellValueFactory>
                </TableColumn>
            </columns>    
        </TableView>
    </children>
</VBox>
The Controller

Screen1.java
package putItAllTogether;

import com.paddyweblog.control.SearchTextBox;
import com.paddyweblog.control.SearchTextBoxEvent;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Font;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.client.ClientFactory;

import org.glassfish.jersey.jackson.JacksonFeature;


public class Screen1 implements Initializable {
    
    @FXML private TableView<Music> tableView;
    
    @FXML
    private ComboBox comboBox1;
    
    @FXML
    private SearchTextBox searchTextBox1;
        
    @FXML
    private void handleComboBoxAction(ActionEvent event) {
        
        Font f = searchTextBox1.getFont();
        String name = f.getName();
        
        double sizeValue =  Double.parseDouble((String)comboBox1.getValue());
        Font fnew = new Font(name,sizeValue);
        searchTextBox1.setFont(fnew);
        
    }
     
    @FXML
    private void handleSearchTextBoxCrossButtonOnMouseClicked(MouseEvent mouseEvent){
        System.out.println("handleSearchTextBoxCrossButtonOnMouseClicked");
        ObservableList<Music> data = tableView.getItems();
        data.clear();
    }
    
    @FXML
    private void handleSearchTextBoxSearchEvent(SearchTextBoxEvent searchTextBoxEvent){
        System.out.println("handleSearchTextBoxSearchEvent"+searchTextBoxEvent.getText());
        
         ObservableList<Music> data = tableView.getItems();
         data.clear();
        
        if (searchTextBoxEvent.getText().length()>0){
            List<Music> listMusic = this.findArtistByName(searchTextBoxEvent.getText());
            System.out.println("listMusic : "+listMusic);    
           
            for (Music music :listMusic){
                data.add(music);
            }
        }    
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        Font f = searchTextBox1.getFont();       
        comboBox1.setValue(String.valueOf((int)f.getSize()));
    }   
    
    protected List<Music> findArtistByName(String artistBeginBy){
         
         Client client = ClientFactory.newClient();
                 
         GenericType<List<Music>> listm = new GenericType<List<Music>>() {};
         
         List<Music> listMusic = client.target("http://localhost:8080/RESTfulServices/rs/ArtisteNameBeginningBy/{beginBy}")         
                        .pathParam("beginBy", artistBeginBy)
                        .request(MediaType.APPLICATION_XML)
                        .get(listm);
         
         return listMusic;
     }  
    
   /* 
   protected List<Music> findArtistByName(String artistBeginBy){
         
        Client client = ClientFactory.newClient();
        
        client.configuration().register(new JacksonFeature());   
        
        ListMusic listMusic = client.target("http://localhost:8080/RESTfulServices/rs/ArtisteNameBeginningBy/{beginBy}")
                       .pathParam("beginBy", artistBeginBy)
                       .request(MediaType.APPLICATION_JSON)
                       .get(ListMusic.class); 
        
        if (listMusic==null){
            listMusic = new ListMusic();
        }
 
        return listMusic.getMusic();
     } 
     */
}
The JavaFX application

PutItAllTogether.java
package putItAllTogether;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class PutItAllTogether extends Application {
    
    public static void main(String[] args) {
        Application.launch(PutItAllTogether.class, args);
    }
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Screen1.fxml"));
        
        stage.setScene(new Scene(root));
        stage.show();
    }
}

4. Where I get the jars
Jersey jax-rs-ri 2.0-m7
Jersey org.glassfish.jersey.media- jackson 2.0m7
jackson

NetBeans project of the Application

NetBeans project of the Service

Aucun commentaire: