Combo Box JavaFx with FXML - combobox

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:

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, but limited, CheckBoxes in FXML/JavaFX

I'm trying to find a way to use check boxes to allow the user to pick two things from a list of three, and then have the remaining check box become disabled until one of the others is un-selected. I have a ChangeListener attached to all three check boxes, so I can register when two have been selected, but I don't know how to target the "other" box/boxes to disable/enable them.
ChangeListener checkboxlistener = new ChangeListener() {
int i = 0;
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
if((boolean) observable.getValue() == true) {
i++;
System.out.println(i);
} else {
i--;
System.out.println(i);
}
if(i == 2) {
//What should I put here, if anything?//
}
}
};
checkbox1.selectedProperty().addListener(checkboxlistener);
checkbox2.selectedProperty().addListener(checkboxlistener);
checkbox3.selectedProperty().addListener(checkboxlistener);
}
Keep a collection of selected check boxes and unselected check boxes. Add a listener to each check box's selectedProperty and make sure it is in the correct collections when the selection changes.
Then you can just observe the size of the collection of selected check boxes, and update the disable state of all the unselected check boxes accordingly.
Here's an example:
MultipleCheckBoxExampleController.java:
package multiplecheckbox;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
public class MultipleCheckBoxExampleController {
#FXML
private CheckBox checkBox1 ;
#FXML
private CheckBox checkBox2 ;
#FXML
private CheckBox checkBox3 ;
#FXML
private Button submitButton ;
private ObservableSet<CheckBox> selectedCheckBoxes = FXCollections.observableSet();
private ObservableSet<CheckBox> unselectedCheckBoxes = FXCollections.observableSet();
private IntegerBinding numCheckBoxesSelected = Bindings.size(selectedCheckBoxes);
private final int maxNumSelected = 2;
public void initialize() {
configureCheckBox(checkBox1);
configureCheckBox(checkBox2);
configureCheckBox(checkBox3);
submitButton.setDisable(true);
numCheckBoxesSelected.addListener((obs, oldSelectedCount, newSelectedCount) -> {
if (newSelectedCount.intValue() >= maxNumSelected) {
unselectedCheckBoxes.forEach(cb -> cb.setDisable(true));
submitButton.setDisable(false);
} else {
unselectedCheckBoxes.forEach(cb -> cb.setDisable(false));
submitButton.setDisable(true);
}
});
}
private void configureCheckBox(CheckBox checkBox) {
if (checkBox.isSelected()) {
selectedCheckBoxes.add(checkBox);
} else {
unselectedCheckBoxes.add(checkBox);
}
checkBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
unselectedCheckBoxes.remove(checkBox);
selectedCheckBoxes.add(checkBox);
} else {
selectedCheckBoxes.remove(checkBox);
unselectedCheckBoxes.add(checkBox);
}
});
}
}
MultipleCheckBoxExample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="multiplecheckbox.MultipleCheckBoxExampleController"
alignment="center" spacing="5">
<padding>
<Insets top="10" bottom="10" left="10" right="10" />
</padding>
<CheckBox fx:id="checkBox1" text="Choice 1" />
<CheckBox fx:id="checkBox2" text="Choice 2" />
<CheckBox fx:id="checkBox3" text="Choice 3" />
<Button fx:id="submitButton" text="Submit" />
</VBox>
Main.java:
package multiplecheckbox;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
VBox root = FXMLLoader.load(getClass().getResource("MultipleCheckBoxExample.fxml"));
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

Populating a TableView with data from Database JavaFX

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.)

Google Analytics (V4) OnCreate Cannot cast from Application

I have followed a better tutorial than the google one to start to get analytics in my app.
The problem is that
package com.sgdva.ishikawa;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.analytics.GoogleAnalytics;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import java.util.HashMap;
public class Ishikawa extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sources, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(Ishikawa.this, Sources.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// The following line should be changed to include the correct property id.
private static final String PROPERTY_ID = "UA-50596309-1";
// Logging TAG
private static final String TAG = "Ishikawa";
public static int GENERAL_TRACKER = 0;
public enum TrackerName {
APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg:
// roll-up tracking.
ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a
// company.
}
HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();
public Ishikawa() {
super();
}
synchronized Tracker getTracker(TrackerName trackerId) {
if (!mTrackers.containsKey(trackerId)) {
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
Tracker t = (trackerId == TrackerName.APP_TRACKER) ? analytics
.newTracker(R.xml.app_tracker)
: (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics
.newTracker(PROPERTY_ID) : analytics
.newTracker(R.xml.ecommerce_tracker);
mTrackers.put(trackerId, t);
}
return mTrackers.get(trackerId);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a Tracker (should auto-report)
((Ishikawa) getApplication())
.getTracker(Ishikawa.TrackerName.APP_TRACKER);
setContentView(R.layout.activity_ishikawa);
In this line
((Ishikawa) getApplication()).getTracker(Ishikawa.TrackerName.APP_TRACKER);
It says:Cannot cast from Application to Ishikawa
I have read that this is because my android name is not delcared in my manifest.xml but it is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sgdva.ishikawa"
android:versionCode="2"
android:versionName="1.1" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:name="com.sgdva.ishikawa.Ishikawa"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<!-- Google Analytics Version v4 needs this value for easy tracking -->
<meta-data android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="#xml/global_tracker" />
<activity
android:name="com.sgdva.ishikawa.Ishikawa"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sgdva.ishikawa.Machine"
android:label="#string/title_activity_machine"
android:screenOrientation="portrait" >
</activity>
<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|s mallestScreenSize"/>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.sgdva.ishikawa.MainActivity"
android:label="#string/title_activity_main"
android:screenOrientation="portrait">
</activity>
</application>
</manifest>
Why would this happen?
It was my bad, I was calling my "activity" as an "application"
((Ishikawa) getApplication()).getTracker(Ishikawa.TrackerName.APP_TRACKER);
I made another .class called "Tracker.java" get the code for analytics there and referenced it instead:
((Tracker) getApplication()).getTracker(Tracker.TrackerName.APP_TRACKER);

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);
}
}
}

Resources