JavaFx: Table view with different cell data type by row on the same column, HOW TO? - class

How to get different data class type on each row of the same column for a JavaFx table view?

Based on this post, here is a simple example that demonstrate how to get different data class type by row on the same column in a javaFx table view:
package application;
import java.time.LocalDateTime;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
public class Main extends Application {
private final TableView<Person<?>> tableView = new TableView<>();
private Person<Integer> person1 = new Person<>("Jacob", "Smith", 28, 4);
private Person<Integer> person2 = new Person<>("Isabella", "Johnson", 19, 5);
private Person<String> person3 = new Person<>("Bob", "The Sponge", 13, "Say Hi!");
private Person<LocalDateTime> person4 = new Person<>("Time", "Is Money", 45, LocalDateTime.now());
private Person<Double> person5 = new Person<>("John", "Doe", 32, 457.89);
private final ObservableList<Person<?>> data = FXCollections.observableArrayList(person1, person2, person3, person4,
person5);
#SuppressWarnings("unchecked")
#Override
public void start(Stage primaryStage) {
TableColumn<Person<?>, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person<?>, String> lastNameCol = new TableColumn<>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<Person<?>, Integer> ageCol = new TableColumn<>("Age");
ageCol.setMinWidth(50);
ageCol.setCellValueFactory(new PropertyValueFactory<>("age"));
TableColumn<Person<?>, ?> particularValueCol = new TableColumn<>("Particular Value");
particularValueCol.setMinWidth(200);
particularValueCol.setCellValueFactory(new PropertyValueFactory<>("particularValue"));
tableView.setItems(data);
// Type safety: A generic array of Table... is created for a varargs
// parameter
// -> #SuppressWarnings("unchecked") to start method!
tableView.getColumns().addAll(firstNameCol, lastNameCol, ageCol, particularValueCol);
// Output in console the selected table view's cell value/class to check
// that the data type is correct.
SystemOutTableViewSelectedCell.set(tableView);
// To check that table view is correctly refreshed on data changed..
final Button agePlusOneButton = new Button("Age +1");
agePlusOneButton.setOnAction((ActionEvent e) -> {
Person<?> person = tableView.getSelectionModel().getSelectedItem();
try {
person.setAge(person.getAge() + 1);
} catch (NullPointerException npe) {
//
}
});
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(tableView, agePlusOneButton);
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().addAll(vbox);
primaryStage.setWidth(600);
primaryStage.setHeight(750);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public static class Person<T> {
private final StringProperty firstName;
private final StringProperty lastName;
private final IntegerProperty age;
private final ObjectProperty<T> particularValue;
private Person(String firstName, String lastName, Integer age, T particularValue) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.age = new SimpleIntegerProperty(age);
this.particularValue = new SimpleObjectProperty<T>(particularValue);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
public Integer getAge() {
return age.get();
}
public void setAge(Integer age) {
this.age.set(age);
}
public IntegerProperty ageProperty() {
return age;
}
public T getParticularValue() {
return particularValue.get();
}
public void setParticularValue(T particularValue) {
this.particularValue.set(particularValue);
}
public ObjectProperty<T> particularValueProperty() {
return particularValue;
}
}
public static final class SystemOutTableViewSelectedCell {
#SuppressWarnings({ "rawtypes", "unchecked" })
public static void set(TableView tableView) {
tableView.getSelectionModel().setCellSelectionEnabled(true);
ObservableList selectedCells = tableView.getSelectionModel().getSelectedCells();
selectedCells.addListener(new ListChangeListener() {
#Override
public void onChanged(Change c) {
TablePosition tablePosition = (TablePosition) selectedCells.get(0);
Object val = tablePosition.getTableColumn().getCellData(tablePosition.getRow());
System.out.println("Selected Cell (Row: " + tablePosition.getRow() + " / Col: "
+ tablePosition.getColumn() + ") Value: " + val + " / " + val.getClass());
}
});
}
}
}

Related

Multiple MongoDB Connectors with SpringBoot REST api

I have three databases and I used MongoTemplate to have possibility connect to these databases from my application.
but when I use for example POST Method in Postman, I have error 404, not found.
In the console anything is fine and when I try http://localhost:8080/, also I have this error There was an unexpected error (type=Not Found, status=404).
No message available.
I searched too much and read so many things for example like https://dzone.com/articles/multiple-mongodb-connectors-with-spring-boot, but I could not undesrtood how can I define multiple MongoDB Connectors and fix this problem.
The MultipleMongoConfige:
package spring.mongo.thesis.config;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import com.mongodb.MongoClient;
import lombok.RequiredArgsConstructor;
#Configuration
#RequiredArgsConstructor
#EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {
private final MultipleMongoProperties mongoProperties = new MultipleMongoProperties();
#Primary
#Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate() throws Exception {
return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
}
#Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() throws Exception {
return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
}
#Bean(name = "thirdMongoTemplate")
public MongoTemplate thirdMongoTemplate() throws Exception {
return new MongoTemplate(thirdFactory(this.mongoProperties.getThird()));
}
#Bean
#Primary
public MongoDbFactory primaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
}
#Bean
public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
}
#Bean
public MongoDbFactory thirdFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
}
}
The PrimaryMongoConfig:
package spring.mongo.thesis.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
#Configuration
#EnableMongoRepositories(basePackages = "spring.mongo.thesis.repository.primary",
mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {
}
The MultipleMongoProperty:
package spring.mongo.thesis.config;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
private MongoProperties third = new MongoProperties();
public MongoProperties getPrimary() {
return primary;
}
public void setPrimary(MongoProperties primary) {
this.primary = primary;
}
public MongoProperties getSecondary() {
return secondary;
}
public void setSecondary(MongoProperties secondary) {
this.secondary = secondary;
}
public MongoProperties getThird() {
return third;
}
public void setThird(MongoProperties third) {
this.third = third;
}
}
The PlayerController:
package spring.mongo.thesis.controller.primary;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.mongo.thesis.repository.primary.PlayerModel;
import spring.mongo.thesis.repository.primary.PlayerRepository;
#RestController
#RequestMapping("/player")
public class PlayerController {
#Autowired
private PlayerRepository repo;
//Getting Player ID
#GetMapping("/{nickname}")
public ResponseEntity<?> getPlayerByID(#PathVariable String nickname){
try {
PlayerModel p = repo.findById(nickname).get();
return ResponseEntity.ok(p);
} catch (Exception e) {
return ResponseEntity.status(404).body("Not Found!");
}
}
//Get All Players
#GetMapping
public List<PlayerModel> getAllPlayers() {
return repo.findAll();
}
//Delete Players
#DeleteMapping
public String deleteAllPlayers(){
repo.deleteAll();
return "Deleted!";
}
//#ExceptionHandler(MethodArgumentNotValidException.class)
//public void handleMissingParams(MissingServletRequestParameterException ex) {
// String name = ex.getParameterName();
//System.out.println(name + " parameter is missing");
// Actual exception handling
//}
//Create Player
#PostMapping
public ResponseEntity<?> createPlayer(#RequestBody #Valid PlayerModel player) {
PlayerModel findplayer = repo.findByNickname(player.getNickname());
if(findplayer != null) {
return ResponseEntity.status(409).body("Conflict!");
}
repo.save(player);
return ResponseEntity.status(201).body("Created!");
}
//Delete player By ID
#DeleteMapping("/{nickname}")
public ResponseEntity<?> deletePlayerByID(#PathVariable String nickname){
try {
PlayerModel p = repo.findById(nickname).get();
repo.deleteById(nickname);
return ResponseEntity.ok(p);
} catch (Exception e) {
return ResponseEntity.status(404).body("Not Found!");
}
}
//Update Player By ID
#PutMapping("/{nickname}")
public ResponseEntity<?> updatePlayerByID(
#PathVariable("nickname")String nickname,
#RequestBody #Valid PlayerModel player){
PlayerModel findplayer = repo.findByNickname(player.getNickname());
if(findplayer == null)
return ResponseEntity.status(404).
body("There is not Player with indicated Nickname!");
else
player.setNickname(nickname);
repo.save(player);
return ResponseEntity.ok(player);
}
}
The PlayerRepository:
package spring.mongo.thesis.repository.primary;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface PlayerRepository extends MongoRepository<PlayerModel, String>{
PlayerModel findByNickname(String nickname);
}
The PrimaryMongoConfig:
package spring.mongo.thesis.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
#Configuration
#EnableMongoRepositories(basePackages = "spring.mongo.thesis.repository.primary",
mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {
}
and my Application:
package spring.mongo.thesis.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.println("Hello World!");
}
}
The Player Class:
package spring.mongo.thesis.repository.primary;
import javax.validation.constraints.NotBlank;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = "player")
public class PlayerModel {
#Id
#NotBlank
private String nickname;
#NotBlank
private String firstname;
#NotBlank
private String lastname;
#NotBlank
private String email;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "PlayerModel [nickname=" + nickname + ", firstname=" + firstname + ", lastname=" + lastname + ", email="
+ email + "]";
}
}
The application.yml:
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
mongodb:
primary:
host: localhost
port: 27017
database: player-db
secondary:
host: localhost
port: 27017
database: game-db
third:
host: localhost
port: 27017
database: score-db

Drools : Getting the catched word in a list in THEN

Below is my pojo class
-----------------------------------pojo_Classes2.RootDoc.java-----------------------------------
package pojo_Classes2;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"content",
"person"
})
public class RootDoc {
#JsonProperty("content")
private String content;
#JsonProperty("person")
private List<String> person = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("content")
public String getContent() {
return content;
}
#JsonProperty("content")
public void setContent(String content) {
this.content = content;
}
#JsonProperty("person")
public List<String> getPerson() {
return person;
}
#JsonProperty("person")
public void setPerson(List<String> person) {
this.person = person;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Here is the type of rule which i want to apply
$list1=[gaurav,gagan,anshu....]
...................................................................................................................
Rule1
If
content contains any of the above $list1
Then
Retrieve which name was captured in content and set person the person name in then
............................................................................................................
For eg. gaurav and gagan were captured in content then set get that gaurav and gagan were matched in content and get them back in then part.
Is it possible in drools
Yes, but create object of your class like:
when
$rd : Rootdoc(****your query****);
then
rd.setPerson(query);
end

JavaFX TableView items do not change after changes to the table in the UI

I have a TableView which I populate with MappingItem objects. The goal is to create a mapping between an Excel source fields to database fields.
In the TableView I have two columns. One is of <MappingItem, String> and represents an Excel header. The other is of <MappingItem, GoldplusField> and represents a database field. The second column's cells are ComboBoxTableCell which has a list of fields from my DB.
The problem is that after I change the selection in the second column combobox, the MappingItem does not get updated by my selection. I tried to get the selected Cell and extract the item but I always get Null references.
This is the UI:
This is a sample code:
package tableviewexample;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class TableViewExample extends Application {
#Override
public void start(Stage primaryStage) {
TableView<MappingItem> table = new TableView<>();
// FIRST COLUMN
TableColumn<MappingItem, String> colA = new TableColumn<>("Excel Column");
colA.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, String>, ObservableValue<String>> () {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<MappingItem, String> param) {
return new ReadOnlyObjectWrapper(param.getValue().getExcelColumnName());
}
});
//SECOND COLUMN
TableColumn<MappingItem, GoldplusField> colB = new TableColumn<>("Database Field Column");
colB.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, GoldplusField>, ObservableValue<GoldplusField>> () {
#Override
public ObservableValue<GoldplusField> call(TableColumn.CellDataFeatures<MappingItem, GoldplusField> param) {
return new ReadOnlyObjectWrapper(param.getValue().getGpField());
}
});
GoldplusField gp1 = new GoldplusField("T1", "fName", "First Name");
GoldplusField gp2 = new GoldplusField("T1", "phn", "Phone");
ObservableList<GoldplusField> fieldsList = FXCollections.observableArrayList(gp1, gp2);
colB.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), fieldsList));
colB.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<MappingItem, GoldplusField>>() {
public void handle(TableColumn.CellEditEvent<MappingItem, GoldplusField> e) {
GoldplusField gpf = colB.getCellData(table.getFocusModel().getFocusedItem());
System.out.println(gpf.getGpName());
MappingItem item = table.getSelectionModel().getSelectedItem();
System.out.println(item.getGpField().getGpName());
}
});
table.setEditable(true);
table.getColumns().addAll(colA, colB);
MappingItem mi1 = new MappingItem("name");
MappingItem mi2 = new MappingItem("phone");
ObservableList<MappingItem> miList = FXCollections.observableArrayList(mi1, mi2);
table.setItems(miList);
StackPane root = new StackPane();
root.getChildren().add(table);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
class FieldToStringConvertor extends StringConverter<GoldplusField> {
#Override
public String toString(GoldplusField object) {
if (object != null)
return object.getGpName();
else
return "";
}
#Override
public GoldplusField fromString(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
class MappingItem {
private String excelColumnName;
private GoldplusField gpField;
public String getExcelColumnName() { return excelColumnName; }
public void setExcelColumnName(String excelColumnName) { this.excelColumnName = excelColumnName; }
public GoldplusField getGpField() { return gpField; }
public void setGpField(GoldplusField gpField) { this.gpField = gpField; }
public MappingItem(String columnName) {
this.excelColumnName= columnName;
}
public MappingItem(GoldplusField gpField) {
this.gpField = gpField;
}
public MappingItem(String columnName, GoldplusField gpField) {
this.excelColumnName = columnName;
this.gpField = gpField;
}
}
class GoldplusField {
private String table;
private String dbName;
private String gpName;
public String getDbName() { return dbName; }
public String getGpName() { return gpName; }
public String getTable() { return table; }
public void setDbName(String dbName) { this.dbName = dbName; }
public void setGpName(String gpName) { this.gpName = gpName; }
public void setTable(String table) { this.table = table; }
public GoldplusField(String table, String dbName, String gpName) {
this.dbName = dbName;
this.gpName = gpName;
this.table = table;
}
}
}
OK. As have been mentioned, the problem was, probably, that the properties were not "writable".
I ended up changing my objects properties to JavaFX Properties. Then I set up a PropertyValueFactory for each of them and passed it to the column's CellValueFactory.
Thank you.
private void populateSourceColumnsColumn() {
ArrayList<MappingItem> items = new ArrayList<> ();
ArrayList<String> headers = SheetHelper.getTableHeadersAsString(sheet, true);
for (String header : headers) {
items.add(new MappingItem(header) );
}
ObservableList<MappingItem> itemsList = FXCollections.observableArrayList(items);
mappingTable.setItems(itemsList);
// First Column
PropertyValueFactory<MappingItem, String> fNameCellValueFactory = new PropertyValueFactory<>("excelColumnName");
inputColumnsColumn.setCellValueFactory(fNameCellValueFactory);
// Second Column
PropertyValueFactory<MappingItem, GoldplusField> gpFieldCellValueFactory = new PropertyValueFactory<>("gpField");
goldplusFieldsColumn.setCellValueFactory(gpFieldCellValueFactory);
GoldplusDatabase gpDb = new GoldplusDatabase(DatasourceContext.INSTANCE.getDataSource());
ObservableList<GoldplusField> fieldsList = FXCollections.observableArrayList(gpDb.getContactFields());
goldplusFieldsColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), fieldsList));
}
public class MappingItem {
private StringProperty excelColumnName = new SimpleStringProperty(this, "excelColumnName");
private ObjectProperty<GoldplusField> gpField = new SimpleObjectProperty<GoldplusField>(this, "gpField");
public String getExcelColumnName() {
return excelColumnName.get();
}
public void setExcelColumnName(String excelColumnName) {
this.excelColumnName.set(excelColumnName);
}
public StringProperty excelColumnNameProperty() {
return excelColumnName;
}
public GoldplusField getGpField() {
return gpField.get();
}
public void setGpField(GoldplusField gpField) {
this.gpField.set(gpField);
}
public ObjectProperty gpFieldProperty() {
return this.gpField;
}
public MappingItem() {
super();
}
public MappingItem(String columnName) {
this.excelColumnName.set(columnName);
}
public MappingItem(GoldplusField gpField) {
this.gpField.set(gpField);
}
public MappingItem(String columnName, GoldplusField gpField) {
this.excelColumnName.set(columnName);
this.gpField.set(gpField);
}
}
public class GoldplusField {
private StringProperty table = new SimpleStringProperty(this, "table");
private StringProperty dbName = new SimpleStringProperty(this, "dbName");
private StringProperty gpName = new SimpleStringProperty(this, "gpName");
public String getDbName() {
return dbName.get();
}
public String getGpName() {
return gpName.get();
}
public String getTable() {
return table.get();
}
public void setDbName(String dbName) {
this.dbName.set(dbName);
}
public void setGpName(String gpName) {
this.gpName.set(gpName);
}
public void setTable(String table) {
this.table.set(table);
}
public StringProperty tableProperty() {
return this.table;
}
public StringProperty gpNameProperty() {
return this.gpName;
}
public StringProperty dbNameProperty() {
return this.dbName;
}
public GoldplusField(String table, String dbName, String gpName) {
this.dbName.set(dbName);
this.gpName.set(gpName);
this.table.set(table);
}
}

Apply table filter

I have this example of Java table which generates values every second.
Short example:
MainApp.java
public class MainApp extends Application
{
private TableView<Employee> table;
private TextField txtField;
private ObservableList<Employee> data;
MyService myService;
#Override
public void start(Stage stage) throws Exception
{
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<Void>
{
#Override
protected Task<Void> createTask()
{
return new Task<Void>()
{
#Override
protected Void call() throws Exception
{
data = getTableData();
table.setItems(FXCollections.observableArrayList(data));
return null;
}
};
}
}
public static void main(String[] args)
{
launch(args);
}
private void initTable()
{
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().empIdProperty();
}
});
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().nameProperty();
}
});
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, Number>, ObservableValue<Number>>()
{
#Override
public ObservableValue<Number> call(TableColumn.CellDataFeatures<Employee, Number> p)
{
return p.getValue().ageProperty();
}
});
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().cityProperty();
}
});
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
}
private void initFilter()
{
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener(new InvalidationListener()
{
#Override
public void invalidated(Observable o)
{
if (txtField.textProperty().get().isEmpty())
{
table.setItems(data);
return;
}
ObservableList<Employee> tableItems = FXCollections.observableArrayList();
ObservableList<TableColumn<Employee, ?>> cols = table.getColumns();
for (int i = 0; i < data.size(); i++)
{
for (int j = 0; j < cols.size(); j++)
{
TableColumn col = cols.get(j);
String cellValue = col.getCellData(data.get(i)).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(txtField.textProperty().get().toLowerCase()))
{
tableItems.add(data.get(i));
break;
}
}
}
table.setItems(tableItems);
}
});
}
private ObservableList<Employee> getTableData()
{
ObservableList<Employee> list = FXCollections.observableArrayList();
String[] name =
{
"Sriram", "Pete", "Eric", "Dawson", "John"
};
String[] city =
{
"New York", "Chicago", "Little Rock", "Los Angeles", "Oakland"
};
for (int i = 0; i < 5; i++)
{
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
}
Employee.java
public class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
p
ublic Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
I noticed that the filter that I use to filter the content is applied only for the current Service run.
For next run the filter is not applied.
Use a FilteredList to manage the filtering. Instead of updating the list directly, replace the contents of its source list from the service. When the text in the text field changes, just update the predicate for the filtered list.
As an aside, your code updates the TableView from a background thread, which violates the threading rules of JavaFX. This is fixed in the example below.
SSCCE:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FilteredTableViewExample extends Application {
private TableView<Employee> table;
private TextField txtField;
private FilteredList<Employee> tableData;
private ObservableList<Employee> data;
MyService myService;
#Override
public void start(Stage stage) throws Exception {
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<List<Employee>> {
#Override
protected Task<List<Employee>> createTask() {
Task<List<Employee>> task = new Task<List<Employee>>() {
#Override
protected List<Employee> call() throws Exception {
return getTableData();
}
};
task.setOnSucceeded(e -> data.setAll(task.getValue()));
return task ;
}
}
public static void main(String[] args) {
launch(args);
}
private void initTable() {
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(p -> p.getValue().empIdProperty());
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(p -> p.getValue().nameProperty());
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(p -> p.getValue().ageProperty());
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(p -> p.getValue().cityProperty());
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
data = FXCollections.observableArrayList();
tableData = new FilteredList<>(data);
table.setItems(tableData);
}
private void initFilter() {
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener((obs, oldText, newText) -> {
if (txtField.textProperty().get().isEmpty()) {
tableData.setPredicate(employee -> true);
return;
}
tableData.setPredicate(employee -> {
String text = newText.toLowerCase();
for (TableColumn<Employee, ?> col : table.getColumns()) {
String cellValue = col.getCellData(employee).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(text)) {
return true;
}
}
return false;
});
});
}
private List<Employee> getTableData() {
List<Employee> list = new ArrayList<>();
String[] name = { "Sriram", "Pete", "Eric", "Dawson", "John" };
String[] city = { "New York", "Chicago", "Little Rock", "Los Angeles", "Oakland" };
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
public static class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
public Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
}

GWT: gwt-exporter: passing objects

I've been struggling with passing Java objects from Java through JSNI (gwt-exporter generated) into Java and wonder if anybody can help?
I am creating an object in Java ("Person"), passing it to a JSNI method ("displayPerson") that invokes a Java method exposed with gwt-exporter ("CommonService.displayPerson"); however the parameter to the last stage becomes null.
If I pass a String it works OK; it's just with my objects I hit the problem.
Person is defined in a GWT application JAR inherited by the other GWT application.
Thanks for looking,
Mike
GWT application
package com.anstis.pluginserver.client;
import com.anstis.plugincommon.shared.Person;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
public class PluginServer implements EntryPoint {
public void onModuleLoad() {
GWT.create(CommonService.class);
onLoadImpl();
RootPanel.get("container").add(getButton());
}
private native void onLoadImpl() /*-{
if ($wnd.jscOnLoad && typeof $wnd.jscOnLoad == 'function') $wnd.jscOnLoad();
}-*/;
private Button getButton() {
Button btn = new Button("Click!");
btn.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Person p = new Person();
p.setName("Smurf");
p.setAge(500);
displayPerson(p);
}
});
return btn;
}
private native void displayPerson(Person person) /*-{
// The below displays shows 'person' is not null
alert("PluginServer.displayPerson.person is " + (person != null ? "not " : "") + "null");
try {
var pluginServer = new $wnd.com.anstis.pluginserver.CommonService();
// The below displays shows 'pluginServer' is not null
alert("PluginServer.displayPerson.pluginServer = " + pluginServer);
pluginServer.displayPerson(person);
} catch(err) {
alert(err);
}
}-*/;
}
CommonService.java
package com.anstis.pluginserver.client;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.Exportable;
import com.anstis.plugincommon.shared.Person;
import com.anstis.plugincommon.shared.PluginCallback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
#Export
public class CommonService implements Exportable {
public void displayPerson(Person person) {
//The below shows 'person' *IS* null
Window.alert("CommonService.displayPerson.person is "
+ (person != null ? "not " : "") + "null");
Window.alert("Name=" + person.getName());
}
}
Person.java
package com.anstis.plugincommon.shared;
import org.timepedia.exporter.client.Exportable;
public class Person implements Exportable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
You need no to implement Exportable for Person class.
public class Person {
and it works.
If anybody else stumbles across this question, I now have a working example at git://github.com/manstis/gwt-plugins.git