Populating a TableView with data from Database JavaFX - database

I'm trying to populate my TableView in JavaFX with data from my database.
I've been trying a lot of different methods to try and get something working. I've been changing a lot of things but ultimately I haven't gotten anywhere. I think it has something to do with the way I'm loading my FXML file.
My database has 3 columns, so I'm not sure if I have to define everything from the database in my Artist class and that's why it's giving me errors.
I built my GUI with SceneBuilder so I'll attach my FXML file.
My main class
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
public class Main extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(Main.class
.getResource("artistSelection.fxml"));
Group rootGroup = loader.load();
final artistSelectionController controller = loader.getController();
controller.setStage(stage);
Scene scene = new Scene(rootGroup,600,400);
stage.setScene(scene);
StageStyle stageStyle = StageStyle.TRANSPARENT;
scene.setFill(Color.TRANSPARENT);
stage.initStyle(stageStyle);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
My Controller Class
public class artistSelectionController{
#FXML
private Rectangle rect;
#FXML
private ImageView logo;
#FXML
private HBox buttons;
#FXML
private Button newArtist;
#FXML
private Button closeScreen;
private Stage stage;
private double dragAnchorX;
private double dragAnchorY;
private PreparedStatement preparedStatement;
public void setStage(Stage stage){
this.stage = stage;
}
#FXML
public void closeScreenHandler(ActionEvent e){
stage.close();
}
#FXML
public void mousePressedHandler(MouseEvent me) {
dragAnchorX = me.getScreenX() - stage.getX();
dragAnchorY = me.getScreenY() - stage.getY();
}
#FXML
public void mouseDraggedHandler(MouseEvent me) {
stage.setX(me.getScreenX() - dragAnchorX);
stage.setY(me.getScreenY() - dragAnchorY);
}
#FXML
private static TableView<Artist> artistTable;
#FXML
private TableColumn<Artist, String> artistName;
private DBConnect objDbClass;
private Connection con;
private Logger logger;
#FXML
void initialize(){
// assert artistTable != null : "fx:id=\"tableview\" was not injected: check your FXML file 'UserMaster.fxml'.";
artistName.setCellValueFactory(
new PropertyValueFactory<Artist,String>("Artist"));
objDbClass = new DBConnect();
try{
con = objDbClass.getConnection();
buildData();
}
catch(ClassNotFoundException ce){
logger.newInput(ce.toString());
}
catch(SQLException ce){
logger.newInput(ce.toString());
}
}
private ObservableList<Artist> data;
public void buildData(){
data = FXCollections.observableArrayList();
try{
String SQL = "Select Name from ARTIST";
ResultSet rs = con.createStatement().executeQuery(SQL);
while(rs.next()){
Artist cm = new Artist();
cm.name.set(rs.getString("name"));
data.add(cm);
}
artistTable.setItems(data);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
}
My POJO
package application;
import javafx.beans.property.SimpleStringProperty;
public class Artist {
public SimpleStringProperty name = new SimpleStringProperty();
public SimpleStringProperty genre = new SimpleStringProperty();
public String getName() {
return name.get();
}
public String getGenre() {
return genre.get();
}
}
My Database Connector
import java.sql.*;
public class DBConnect{
public Connection getConnection() throws ClassNotFoundException, SQLException{
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://localhost/myStudio","root","root");
}
}
And finally my FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<Group fx:id="rootGroup" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application/artistSelectionController">
<children>
<Rectangle fx:id="rect" arcHeight="50.0" arcWidth="50.0" height="376.0" layoutX="13.0" layoutY="13.0" stroke="BLACK" strokeType="INSIDE" width="577.0">
<fill>
<LinearGradient cycleMethod="REPEAT" endX="1.0" endY="1.0" startY="1.0">
<stops>
<Stop color="#1b2f36" />
<Stop color="#1b2f36" offset="0.007662835249042145" />
<Stop color="#15596e" offset="1.0" />
</stops>
</LinearGradient>
</fill>
</Rectangle>
<ImageView fx:id="logo" fitHeight="411.0" fitWidth="606.0" layoutX="13.0" layoutY="13.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../Downloads/myStudio.png" />
</image>
</ImageView>
<TableView fx:id="artistTable" layoutX="316.0" layoutY="143.0" prefHeight="223.0" prefWidth="241.0">
<columns>
<TableColumn fx:id="artistName" editable="false" prefWidth="240.0" resizable="false" text="Artists" />
</columns>
</TableView>
<HBox fx:id="buttons" layoutX="65.0" layoutY="339.0" prefHeight="100.0" prefWidth="200.0" spacing="20.0">
<children>
<Button fx:id="newArtist" mnemonicParsing="false" prefWidth="75.0" text="New Artist" />
<Button fx:id="closeScreen" mnemonicParsing="false" prefWidth="75.0" text="Close" />
</children>
</HBox>
</children>
</Group>
Thanks

There seem to be many errors in your code.
First, you have made artistTable static. Don't do this - it makes no sense at all, and static fields won't be injected by the FXMLLoader. This is why you are getting the null pointer exception.
Second, the value you pass to the PropertyValueFactory ("Artist") does not match the name of any property in your model class Artist. (I.e. there is no ArtistProperty() method and no getArtist() method).
You probably want
artistName.setCellValueFactory(
new PropertyValueFactory<Artist,String>("name"));
which will tie the value for the column to the getName() method. See the PropertyValueFactory documentation for a description of how it works.
(You should probably define your POJO according to the JavaFX Property pattern described here. However just having a get...() method will work.)

Related

Working checkboxes in JavaFX table (CheckBoxTableCell)

(This is similar to a homework question.)
I recently made an example UI in Scenebuilder for something I later had to program with Java Swing. That more or less worked. Now it is my task, not for the actual development of the program, but for learning something in my job training, to make a similar UI with Scenebuilder, but this time an actually working one. The specifications are:
It's a window with a table in it.
At least two of the columns have radio boxes in them that look like checkboxes or checkboxes that act like radio boxes (because the company has weird standards).
It uses FXML files made with Scenebuilder for the layout.
Making the check boxes act as radio boxes should be easy, if I could just enable the editing. I found a lot of examples that do almost what I want, but are still all not really applicable to my situation. Here are some of them:
I started with this video and almost exactly copied the code to first have a working example. Then I adjusted it to my needs until I only had the check boxes to do (first working prototype had Booleans instead).
Then I took part of the full code of this answer to add the check boxes. That worked, but they don't react to clicks.
This, this and this seems to only apply to text fields, not checkboxes.
I then used the two lambda expressions from the second code block in this answer (actually I used the variant in the first answer and manually resolved some errors until suddenly Eclipse automatically converted it to lambda expressions). I also added the public ObservableValue<Boolean> getCompleted() method, Eclipse suggested some magic and then I had what you can see in the corresponding code below (without the console print).
I also added a listener to the boolean property, like this site (archive) apparently does (I think), but that doesn't seem like it helped much.
Here is a picture of how the dialog looks now, I still can't use the check boxes:
My question: How can I make it so that the check boxes react to clicks? React can mean outputting something on the console, I don't need a given code that makes it automatically disable the other checkbox, I want to figure that part out myself.
My code:
src.controller.MainController.java
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import view.Table;
public class MainController implements Initializable{
#FXML TableView<Table> tableID;
#FXML TableColumn<Table,String> iFirstName;
#FXML TableColumn<Table,String> iLastName;
#FXML TableColumn<Table,Boolean> iMalebox;
#FXML TableColumn<Table,Boolean> iFemalebox;
#Override public void initialize(URL location,ResourceBundle resources){
iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
iMalebox.setEditable(true);
// iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
// iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
iFemalebox.setCellValueFactory(p->p.getValue().getCompleted());
iFemalebox.setCellFactory(p->new CheckBoxTableCell<>());
// iMalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rMalebox"));
// iFemalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rFemalebox"));
tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true,false),new Table("Anna","Becker",false,true),new Table("Karl","Schmidt",true,false)));
tableID.setEditable(true);
}
}
src.controller.MainView.java
package controller;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainView extends Application{
#Override public void start(Stage primaryStage){
try{
// FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
AnchorPane page=(AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
Scene scene=new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Window Title");
primaryStage.show();
}catch(Exception e){
Logger.getLogger(MainView.class.getName()).log(Level.SEVERE,null,e);
}
}
public static void main(String[] args){
Application.launch(MainView.class,(java.lang.String[])null);
}
}
src.controller.MainController.fxml
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
<children>
<TableView fx:id="tableID" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="iFirstName" prefWidth="75.0" text="First name" />
<TableColumn fx:id="iLastName" prefWidth="75.0" text="Last name" />
<TableColumn fx:id="iMalebox" prefWidth="75.0" text="Male" />
<TableColumn fx:id="iFemalebox" prefWidth="75.0" text="Female" />
</columns>
</TableView>
</children>
</AnchorPane>
src.view.Table.java
package view;
import javafx.beans.InvalidationListener;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class Table{
private SimpleStringProperty rFirstName;
private SimpleStringProperty rLastName;
private SimpleBooleanProperty rMalebox;
private SimpleBooleanProperty rFemalebox;
public Table(String sFirstName,String sLastName,Boolean sMalebox,Boolean sFemalebox){
rFirstName=new SimpleStringProperty(sFirstName);
rLastName=new SimpleStringProperty(sLastName);
rMalebox=new SimpleBooleanProperty(sMalebox);
rMalebox.addListener((ChangeListener)(observable,oldValue,newValue)->{
System.out.println("test");
System.out.println("abc");
});
rFemalebox=new SimpleBooleanProperty(sFemalebox);
}
public String getRFirstName(){
return rFirstName.get();
}
public void setRFirstName(String v){
rFirstName.set(v);
}
public String getRLastName(){
return rLastName.get();
}
public void setRLastName(String v){
rLastName.set(v);
}
public Boolean getRMalebox(){
return rMalebox.get();
}
public void setRMalebox(Boolean v){
rMalebox.set(v);
}
public Boolean getRFemalebox(){
return rFemalebox.get();
}
public void setRFemalebox(Boolean v){
rFemalebox.set(v);
}
public ObservableValue<Boolean> getCompleted(){
return new ObservableValue<Boolean>(){
#Override public void removeListener(InvalidationListener arg0){}
#Override public void addListener(InvalidationListener arg0){}
#Override public void removeListener(ChangeListener<? super Boolean> listener){}
#Override public Boolean getValue(){
return null;
}
#Override public void addListener(ChangeListener<? super Boolean> listener){
System.out.println("Test");
}
};
}
}
I found a solution. Since I changed so much (I worked on getting this stupid thing to work for almost 20 hours after asking that question), it's not really useful to enumerate all the changes I did. But here is at least a working example.
There are very few lines responsible for making the "male" and "female" boxes trigger each other's opposites (which is specific to my task), everything else is just for getting actually properly working CheckBoxTableCells. One would think that that is a really common case and there should be standard methods for that, like for "print text into the console" or "read file", but apparently not, apparently everything has to be complicated in programming with UIs.
Anyway, rant aside, here is the working code:
src.controller.MainView.java
package controller;
import java.io.*;
import javafx.application.*;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MainView extends Application{
#Override public void start(Stage primaryStage) throws IOException{
primaryStage.setScene(new Scene((AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"))));
primaryStage.show();
}
public static void main(String[] args){
Application.launch(MainView.class);
}
}
src.controller.MainController.java
package controller;
import java.net.*;
import java.util.*;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.fxml.*;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.*;
import javafx.scene.control.cell.*;
import javafx.util.*;
import view.*;
public class MainController implements Initializable{
#FXML TableView<Table> tableID;
#FXML TableColumn<Table,String> iFirstName;
#FXML TableColumn<Table,String> iLastName;
#FXML TableColumn<Table,Boolean> iMalebox;
#FXML TableColumn<Table,Boolean> iFemalebox;
#Override public void initialize(URL location,ResourceBundle resources){
iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
iMalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
#Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
return cellData.getValue().maleCheckedProperty(true);
}
});
iMalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
#Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
return new CheckBoxTableCell<>();
}
});
iFemalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
#Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
return cellData.getValue().femaleCheckedProperty(true);
}
});
iFemalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
#Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
return new CheckBoxTableCell<>();
}
});
tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true),new Table("Anna","Becker",false),new Table("Karl","Schmidt",true)));
}
}
src.view.Table.java
package view;
import javafx.beans.property.*;
public class Table{
private String rFirstName;
private String rLastName;
public Table(String sFirstName,String sLastName,Boolean sMale){
rFirstName=sFirstName;
rLastName=sLastName;
maleCheckedProperty(false).set(sMale);
}
private SimpleBooleanProperty maleChecked=new SimpleBooleanProperty(false);
private SimpleBooleanProperty femaleChecked=new SimpleBooleanProperty(false);
public SimpleBooleanProperty maleCheckedProperty(boolean recursion){
if(recursion) femaleCheckedProperty(false).set(!maleChecked.get());
return maleChecked;
}
public SimpleBooleanProperty femaleCheckedProperty(boolean recursion){
if(recursion) maleCheckedProperty(false).set(!femaleChecked.get());
return femaleChecked;
}
public String getRFirstName(){
return rFirstName;
}
public String getRLastName(){
return rLastName;
}
}
src.controller.MainController.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="98.0" prefWidth="218.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
<children>
<TableView fx:id="tableID" editable="true" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="iFirstName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="First name" />
<TableColumn fx:id="iLastName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="Last name" />
<TableColumn fx:id="iMalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Male"/>
<TableColumn fx:id="iFemalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Female"/>
</columns>
</TableView>
</children>
</AnchorPane>

Multiple Columns in Oracle TableView

my code is working to 90% I think.
The Output is right, but not all columns are shown in the tableview.
I don't know where the problem is.
The fx:id is right, the code too, I believe.
Here's a picture of the openend program. I will give you also my output an my controller an table-code. The launching code isn't important.
Picture:
http://www.directupload.net/file/d/3791/aitj4rff_png.htm
Output:
*** Loaded Oracle-Driver ***
*** Connected with Database ***
Film: Hugo Gesehen: JA
Film: FAST and FURIOS 6 Gesehen: JA
Film: Emil Gesehen: NEIN
Film: DAS_BOOT Gesehen: JA
*** Database data saved to Observable List named 'data'
*** Table Items setted ***
table_controller:
package controller;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import oracle.jdbc.*;
import model.filmtable_data;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
#SuppressWarnings("unused")
public class table_controller implements Initializable {
private ObservableList<filmtable_data> filmData = FXCollections.observableArrayList();
#FXML
private TableView<filmtable_data> FilmTable;
#FXML
private TableColumn<filmtable_data, String> Filmtitel_Col;
#FXML
private TableColumn<filmtable_data, Integer> ID_Col;
#FXML
private TableColumn<filmtable_data, String> Gesehen_Col;
#Override
public void initialize(URL location, ResourceBundle resources) {
// Observable List
ID_Col.setCellValueFactory(new PropertyValueFactory<filmtable_data, Integer>("rID"));
Filmtitel_Col.setCellValueFactory(new PropertyValueFactory<filmtable_data, String>("rFilmtitel"));
Gesehen_Col.setCellValueFactory(new PropertyValueFactory<filmtable_data, String>("rGesehen"));
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("*** Loaded Oracle-Driver ***");
} catch (ClassNotFoundException e1) {
System.out.println("Driver-Loading failed.");
e1.printStackTrace();
}
try {
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:lukas/1234#10.140.79.39:1521:OTTO");
Statement statement = conn.createStatement();
ResultSet resultset = statement.executeQuery("SELECT FILMTITEL, GESEHEN FROM LUKA1");
String filmtitel = "empty";
String gesehen = "empty";
int zaehler = 1;
System.out.println("*** Connected with Database ***");
while (resultset.next()) {
filmtitel = resultset.getString("FILMTITEL");
gesehen = resultset.getString("GESEHEN");
System.out.println("Film: " + filmtitel + "\t\t\tGesehen: " + gesehen);
filmtable_data entry = new filmtable_data(zaehler, filmtitel, gesehen);
filmData.add(entry);
zaehler++;
}
System.out.println("*** Database data saved to Observable List named 'data'");
FilmTable.setItems(filmData);
System.out.println("*** Table Items setted ***");
statement.close();
} catch (SQLException e) {
System.out.println("Login fehlgeschlagen.");
e.printStackTrace();
}
}
}
filmtable_data:
package model;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class filmtable_data {
private final SimpleIntegerProperty rID;
private final SimpleStringProperty rFilmtitel;
private final SimpleStringProperty rGesehen;
public filmtable_data (Integer sID, String sFilmtitel, String sGesehen) {
this.rID = new SimpleIntegerProperty(sID);
this.rFilmtitel = new SimpleStringProperty(sFilmtitel);
this.rGesehen = new SimpleStringProperty(sGesehen);
}
public Integer getRID() {
return rID.get();
}
public void setRID(int set) {
rID.set(set);
}
public String getRFilmtitel() {
return rFilmtitel.get();
}
public void setRFilmtitel(String set) {
rFilmtitel.set(set);
}
public String setRGesehen() {
return rGesehen.get();
}
public void setRGesehen(String set) {
rGesehen.set(set);
}
}
the fx-file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="366.0" prefWidth="268.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.table_controller">
<children>
<TableView fx:id="FilmTable" prefHeight="366.0" prefWidth="425.0">
<columns>
<TableColumn fx:id="ID_Col" minWidth="-Infinity" prefWidth="43.0" text="ID" />
<TableColumn fx:id="Filmtitel_Col" prefWidth="137.0" text="Filmtitel" />
<TableColumn fx:id="Gesehen_Col" prefWidth="137.0" text="Gesehen" />
</columns>
</TableView>
</children>
</AnchorPane>
You have a typo in your POJO class, and there is not getter:
This is wrong:
public String setRGesehen() {
return rGesehen.get();
}
It should be:
public String getRGesehen() {
return rGesehen.get();
}
Notice you should add also the property methods, like:
public StringProperty rGesehenProperty() {
return rGesehen;
}
Even with the wrong getter, as the PropertyValueFactory looks first for the property, it would have worked.

Code is working in jdk7 not in jdk8

I took the sample code from How to create custom components in JavaFX 2.0 using FXML?. the code working fine in jdk7 but the checkbox and combo box values are not working in jdk8. I am not able to click the check box even and select the dropdown.
Please guide me for the same.
Please find the sample code below
Package structure
com.example.javafx.choice
ChoiceCell.java
ChoiceController.java
ChoiceModel.java
ChoiceView.fxml
com.example.javafx.mvc
FxmlMvcPatternDemo.java
MainController.java
MainView.fxml
MainView.properties
ChoiceCell.java
package com.example.javafx.choice;
import java.io.IOException;
import java.net.URL;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Node;
import javafx.scene.control.ListCell;
public class ChoiceCell extends ListCell<ChoiceModel>
{
#Override
protected void updateItem(ChoiceModel model, boolean bln)
{
super.updateItem(model, bln);
if(model != null)
{
URL location = ChoiceController.class.getResource("ChoiceView.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try
{
Node root = (Node)fxmlLoader.load(location.openStream());
ChoiceController controller = (ChoiceController)fxmlLoader.getController();
controller.setModel(model);
setGraphic(root);
}
catch(IOException ioe)
{
throw new IllegalStateException(ioe);
}
}
}
}
ChoiceController.java
package com.example.javafx.choice;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
public class ChoiceController
{
private final ChangeListener<String> LABEL_CHANGE_LISTENER = new ChangeListener<String>()
{
public void changed(ObservableValue<? extends String> property, String oldValue, String newValue)
{
updateLabelView(newValue);
}
};
private final ChangeListener<Boolean> IS_SELECTED_CHANGE_LISTENER = new ChangeListener<Boolean>()
{
public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue)
{
updateIsSelectedView(newValue);
}
};
private final ChangeListener<Boolean> IS_VISIBILITY1_CHANGE_LISTENER = new ChangeListener<Boolean>() {
public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue) {
updateIsVisibleView1(newValue);
}};
#FXML
private Label labelView;
#FXML
private CheckBox isSelectedView;
#FXML
ComboBox isVisible1;
private ChoiceModel model;
public ChoiceModel getModel()
{
return model;
}
public void setModel(ChoiceModel model)
{
if(this.model != null)
removeModelListeners();
this.model = model;
setupModelListeners();
updateView();
}
private void removeModelListeners()
{
model.labelProperty().removeListener(LABEL_CHANGE_LISTENER);
model.isSelectedProperty().removeListener(IS_SELECTED_CHANGE_LISTENER);
model.isVisibleProperty1().removeListener(IS_VISIBILITY1_CHANGE_LISTENER);
isSelectedView.selectedProperty().unbindBidirectional(model.isSelectedProperty());
}
private void setupModelListeners()
{
model.labelProperty().addListener(LABEL_CHANGE_LISTENER);
model.isSelectedProperty().addListener(IS_SELECTED_CHANGE_LISTENER);
model.isVisibleProperty1().addListener(IS_VISIBILITY1_CHANGE_LISTENER);
isSelectedView.selectedProperty().bindBidirectional(model.isSelectedProperty());
}
private void updateView()
{
updateLabelView();
updateIsSelectedView();
updateIsVisibleView1();
}
private void updateLabelView(){ updateLabelView(model.getLabel()); }
private void updateLabelView(String newValue)
{
labelView.setText(newValue);
}
private void updateIsSelectedView(){ updateIsSelectedView(model.isSelected()); }
private void updateIsSelectedView(boolean newValue)
{
isSelectedView.setSelected(newValue);
}
private void updateIsVisibleView1() {
updateIsVisibleView1(model.isVisible1());
}
private void updateIsVisibleView1(boolean newValue) {
isVisible1.setVisible(newValue);
}
}
ChoiceModel.java
package com.example.javafx.choice;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class ChoiceModel
{
private final StringProperty label;
private final BooleanProperty isSelected;
private final BooleanProperty isVisible1;
public ChoiceModel(String label, boolean isSelected, boolean isVisible1)
{
this.label = new SimpleStringProperty(label);
this.isSelected = new SimpleBooleanProperty(isSelected);
this.isVisible1 = new SimpleBooleanProperty(isVisible1);
}
public String getLabel(){ return label.get(); }
public void setLabel(String label){ this.label.set(label); }
public StringProperty labelProperty(){ return label; }
public boolean isSelected(){ return isSelected.get(); }
public void setSelected(boolean isSelected){ this.isSelected.set(isSelected); }
public BooleanProperty isSelectedProperty(){ return isSelected; }
public boolean isVisible1()
{
return isVisible1.get();
}
public void setVisible1(boolean isVisible1)
{
this.isVisible1.set(isVisible1);
}
public BooleanProperty isVisibleProperty1()
{
return isVisible1;
}
}
ChoiceView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.collections.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.example.javafx.choice.ChoiceController">
<children>
<CheckBox fx:id="isSelectedView" />
<Label fx:id="labelView" />
<ComboBox id="isVisible1" fx:id="isVisible1" value="last 7 digits" visible="false">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="last 10 digits" />
<String fx:value="last 9 digits" />
<String fx:value="last 8 digits" />
<String fx:value="last 7 digits" />
<String fx:value="last 6 digits" />
<String fx:value="last 5 digits" />
<String fx:value="last 4 digits" />
<String fx:value="last 3 digits" />
</FXCollections>
</items>
</ComboBox>
</children>
</HBox>
FxmlMvcPatternDemo.java
package com.example.javafx.mvc;
import com.example.javafx.choice.ChoiceController;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FxmlMvcPatternDemo extends Application
{
public static void main(String[] args) throws ClassNotFoundException
{
Application.launch(FxmlMvcPatternDemo.class, args);
}
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load
(
FxmlMvcPatternDemo.class.getResource("MainView.fxml"),
ResourceBundle.getBundle(FxmlMvcPatternDemo.class.getPackage().getName()+".MainView")/*properties file*/
);
ChoiceController controller = new ChoiceController();
stage.setScene(new Scene(root));
stage.show();
}
}
MainController.java
package com.example.javafx.mvc;
import com.example.javafx.choice.ChoiceCell;
import com.example.javafx.choice.ChoiceModel;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
public class MainController implements Initializable
{
#FXML
private ListView<ChoiceModel> choicesView;
#Override
public void initialize(URL url, ResourceBundle rb)
{
choicesView.setCellFactory(new Callback<ListView<ChoiceModel>, ListCell<ChoiceModel>>()
{
public ListCell<ChoiceModel> call(ListView<ChoiceModel> p)
{
return new ChoiceCell();
}
});
choicesView.setItems(FXCollections.observableArrayList
(
new ChoiceModel("Tiger", true, false),
new ChoiceModel("Shark", false, true),
new ChoiceModel("Bear", false, true),
new ChoiceModel("Wolf", true, true)
));
}
#FXML
private void handleForceChange(ActionEvent event)
{
if(choicesView != null && choicesView.getItems().size() > 0)
{
boolean isSelected = choicesView.getItems().get(0).isSelected();
choicesView.getItems().get(0).setSelected(!isSelected);
}
}
}
MainView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.javafx.mvc.MainController"
prefWidth="300"
prefHeight="400"
fillWidth="false"
>
<children>
<Label text="%title" />
<ListView fx:id="choicesView" />
<Button text="Force Change" onAction="#handleForceChange" />
</children>
</VBox>
MainView.proprties
title=JavaFX 2.0 FXML MVC demo
I didn't dig deeper but refactoring like as following should suffice. Double check for correct executions of attached and removed listeners.
public class ChoiceCell extends ListCell<ChoiceModel> {
private Node root;
private ChoiceController controller;
public ChoiceCell() {
URL location = ChoiceController.class.getResource("ChoiceView.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
root = (Node) fxmlLoader.load(location.openStream());
controller = (ChoiceController) fxmlLoader.getController();
} catch (IOException ioe) {
throw new IllegalStateException(ioe);
}
}
#Override
protected void updateItem(ChoiceModel model, boolean bln) {
super.updateItem(model, bln);
if (model != null) {
controller.setModel(model);
setGraphic(root);
} else {
setGraphic(null);
}
}
}

How to change the cursor type when a TableView class was added to a Swing application?

We can resize column width by dragging the column divider in the table header. This is a built-in feature of the TableView class.
Normally, the cursor will become to east-resize (or west-resize) type with positioning the cursor just to the right of a column header.
However, I found that the cursor is remaining the default type at the same position if I integrate JavaFX into Swing Application. That is adding the TableView to a Scene, and then adding this Scene to a JFXPanel, finally, adding this JFXPanel to the JFrame.
The sample codes are listing below:
public class Run extends JFrame {
Run() {
setSize(600, 450);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
final JFXPanel fxPanel = new JFXPanel();
this.getContentPane().add(fxPanel);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private void initFX(JFXPanel fxPanel) {
Scene scene = null;
try {
scene = FXMLLoader.load(
new File("res/fxml_example.fxml").toURI().toURL()
);
} catch (Exception ex) {
ex.printStackTrace();
}
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Run().setVisible(true);
}
});
}
}
fxml_example.fxml:
<?import javafx.scene.Scene?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<Scene xmlns:fx="http://javafx.com/fxml">
<TableView fx:id="tableView"
editable="true">
<columns>
<TableColumn text="COL1">
</TableColumn>
<TableColumn text="COL2">
</TableColumn>
<TableColumn text="COL3">
</TableColumn>
<TableColumn text="COL4">
</TableColumn>
<TableColumn text="COL5">
</TableColumn>
</columns>
</TableView>
</Scene>
So, are there anyone can advise how to fix these codes; make the cursor can change to east-resize (or west-resize) type when this TableView class was added to a Swing application?

Combo Box JavaFx with FXML

how can i use to Combo Box with FXML? i need to set dynamic data.. Does anyone have an example?
This is my Sample.fxml
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication15.SampleController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
<ComboBox fx:id="ciudad" prefWidth="123.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<cellValueFactory>
<PropertyValueFactory property="firstName" />
</cellValueFactory>
</ComboBox>
</children>
</AnchorPane>
See this JavaFX FXML ComboBox demo app. For dynamic data you can either dynamically generate your fxml using something like Velocity or, probably better, populate an ObservableList and provide it to your fxml injected ComboBox instance.
Here is a modified version of the demo app which populates the ObservableList of ComboBox items in the controller initializer.
fruitcombo.css
/** fruitcombo.css
place in same directory as FruitComboApplication.java
ensure build system copies the css file to the build output path */
.layout {
-fx-background-color: cornsilk;
}
#selected-fruit-frame {
-fx-border-color: burlywood;
-fx-border-width: 5;
-fx-background-color: white;
}
.bold-label {
-fx-font-weight: bold;
}
fruitcombo.fxml
<?xml version="1.0" encoding="UTF-8"?>
<!-- fruitcombo.fxml
place in same directory as FruitComboApplication.java
ensure build system copies the fxml file to the build output path -->
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?scenebuilder-stylesheet fruitcombo.css?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="205.0" prefWidth="168.0" styleClass="layout" xmlns:fx="http://javafx.com/fxml" fx:controller="fruit.FruitComboController">
<children>
<ComboBox fx:id="fruitCombo" layoutX="15.0" layoutY="33.0" prefWidth="90.0" promptText="choose"/>
<Label id="fruitSelectorLabel" layoutX="15.0" layoutY="10.0" styleClass="bold-label" text="Fruit Selector" />
<VBox alignment="TOP_CENTER" layoutX="14.0" layoutY="62.0" prefHeight="134.0" prefWidth="140.0" spacing="8.0">
<children>
<StackPane id="selected-fruit-frame" minHeight="100.0" minWidth="118.0" prefHeight="108.0" prefWidth="140.0">
<children>
<ImageView fx:id="orangeImage" fitHeight="91.99999237060547" fitWidth="122.66666035739114" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://i.i.com.com/cnwk.1d/i/tim/2011/03/10/orange_iStock_000001331357X_540x405.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
<ImageView fx:id="pearImage" fitHeight="93.0" fitWidth="124.0" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://smoothiejuicerecipes.com/pear.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
<ImageView fx:id="appleImage" fitHeight="93.0" fitWidth="124.0" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://uhallnyu.files.wordpress.com/2011/11/green-apple.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
</children>
</StackPane>
<Label fx:id="selectedFruit" textAlignment="CENTER" />
</children>
</VBox>
</children>
<stylesheets>
<URL value="#fruitcombo.css" />
</stylesheets>
</AnchorPane>
FruitComboController.java
package fruit;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
/** JavaFX fxml controller for fruit combo fxml demo application. */
public class FruitComboController implements Initializable {
#FXML // fx:id="appleImage"
private ImageView appleImage; // Value injected by FXMLLoader
#FXML // fx:id="fruitCombo"
private ComboBox<String> fruitCombo; // Value injected by FXMLLoader
#FXML // fx:id="orangeImage"
private ImageView orangeImage; // Value injected by FXMLLoader
#FXML // fx:id="pearImage"
private ImageView pearImage; // Value injected by FXMLLoader
#FXML // fx:id="selectedFruit"
private Label selectedFruit; // Value injected by FXMLLoader
#Override // This method is called by the FXMLLoader when initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
assert appleImage != null : "fx:id=\"appleImage\" was not injected: check your FXML file 'fruitcombo.fxml'.";
assert fruitCombo != null : "fx:id=\"fruitCombo\" was not injected: check your FXML file 'fruitcombo.fxml'.";
assert orangeImage != null : "fx:id=\"orangeImage\" was not injected: check your FXML file 'fruitcombo.fxml'.";
assert pearImage != null : "fx:id=\"pearImage\" was not injected: check your FXML file 'fruitcombo.fxml'.";
assert selectedFruit != null : "fx:id=\"selectedFruit\" was not injected: check your FXML file 'fruitcombo.fxml'.";
// populate the fruit combo box with item choices.
fruitCombo.getItems().setAll("Apple", "Orange", "Pear");
// bind the selected fruit label to the selected fruit in the combo box.
selectedFruit.textProperty().bind(fruitCombo.getSelectionModel().selectedItemProperty());
// listen for changes to the fruit combo box selection and update the displayed fruit image accordingly.
fruitCombo.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> selected, String oldFruit, String newFruit) {
if (oldFruit != null) {
switch(oldFruit) {
case "Apple": appleImage.setVisible(false); break;
case "Orange": orangeImage.setVisible(false); break;
case "Pear": pearImage.setVisible(false); break;
}
}
if (newFruit != null) {
switch(newFruit) {
case "Apple": appleImage.setVisible(true); break;
case "Orange": orangeImage.setVisible(true); break;
case "Pear": pearImage.setVisible(true); break;
}
}
}
});
}
}
FruitComboApplication.java
package fruit;
import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/** Main application class for fruit combo fxml demo application */
public class FruitComboApplication extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) throws IOException {
stage.setTitle("Choices");
stage.getIcons().add(new Image("http://files.softicons.com/download/application-icons/pixelophilia-icons-by-omercetin/png/32/apple-green.png"));
AnchorPane layout = FXMLLoader.load(
new URL(FruitComboApplication.class.getResource("fruitcombo.fxml").toExternalForm())
);
stage.setScene(new Scene(layout));
stage.show();
}
}
Sample Program Output:

Resources