This question already has answers here:
Javafx PropertyValueFactory not populating Tableview
(2 answers)
Javafx tableview not showing data in all columns
(3 answers)
Closed 1 year ago.
I am using the following code to generate a TableView:
#FXML
private TableView<Customer> customerTable;
#FXML
private TableColumn<Customer, String> customerIDColumn;
#FXML
private TableColumn<Customer, String> customerNameColumn;
#FXML
private TableColumn<Customer, String> customerPhoneColumn;
#FXML
private TableColumn<Customer, String> customerAddressColumn;
#FXML
private TableColumn<Customer, String> customerPostalCodeColumn;
#FXML
private TableColumn<Customer, String> customerDivisionColumn;
#FXML
private TableColumn<Customer, String> customerCountryColumn;
ObservableList<Customer> customerOL = FXCollections.observableArrayList();
PropertyValueFactory<Customer, String> custCustomerIDFactory = new PropertyValueFactory<>("customerID");
PropertyValueFactory<Customer, String> custNameFactory = new PropertyValueFactory<>("customerName");
PropertyValueFactory<Customer, String> custPhoneFactory = new PropertyValueFactory<>("phone"); //String value "CustomerPhone" calls getCustomerPhone method
PropertyValueFactory<Customer, String> custCountryFactory = new PropertyValueFactory<>("country");
PropertyValueFactory<Customer, String> custDivisionFactory = new PropertyValueFactory<>("division");
PropertyValueFactory<Customer, String> custAddressFactory = new PropertyValueFactory<>("address");
PropertyValueFactory<Customer, String> custPostalCodeFactory = new PropertyValueFactory<>("postalCode");
customerIDColumn.setCellValueFactory(custCustomerIDFactory);
customerNameColumn.setCellValueFactory(custNameFactory);
customerPhoneColumn.setCellValueFactory(custPhoneFactory);
customerCountryColumn.setCellValueFactory(custCountryFactory);
customerDivisionColumn.setCellValueFactory(custDivisionFactory);
customerAddressColumn.setCellValueFactory(custAddressFactory);
customerPostalCodeColumn.setCellValueFactory(custPostalCodeFactory);
Customer cust = new Customer();
cust.setCustomerID(result.getInt("Customer_ID"));
cust.setCustomerName(result.getString("Customer_Name"));
cust.setCustomerPhone(result.getString("Phone"));
cust.setCustomerAddress(result.getString("Address"));
cust.setCustomerPostalCode(result.getString("Postal_Code"));
cust.setCustomerDivision(result.getString("Division"));
cust.setCustomerCountry(result.getString("Country"));
customerOL.addAll(cust);
customerTable.setItems(customerOL);
the above is a part of java code. But I think it explains what I am trying to do.
The line customerOL.addAll(cust); adds 3 customer data into the customerOL object.
The Country, Division, etc all values are getting populated properly in the object. But when the table view is generated strangely I only see the values of ID and Customer Name being populated. The rest of the values are empty as could be seen below:
I am not sure what could be causing this. Here is the FXML file corresponding to this
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="customerAddLabel" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="683.0" prefWidth="824.0"
style="-fx-background-color: silver; -fx-border-color: black; -fx-border-radius: 5;"
xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="c195.View_Controller.CustomerScreenController">
<children>
<Label alignment="TOP_CENTER" layoutX="300.0" layoutY="14.0" prefHeight="38.0" prefWidth="226.0"
style="-fx-border-color: gray; -fx-border-radius: 5;" text="Customer" textAlignment="CENTER">
<font>
<Font name="System Bold Italic" size="25.0"/>
</font>
</Label>
<AnchorPane layoutX="16.0" layoutY="102.0" prefHeight="404.0" prefWidth="363.0"
style="-fx-background-color: white;">
<children>
<TableView fx:id="customerTable" layoutY="1.0" prefHeight="403.0" prefWidth="363.0"
style="-fx-border-color: black; -fx-border-radius: 5;">
<columns>
<TableColumn fx:id="customerIDColumn" prefWidth="63.0" text="ID"/>
<TableColumn fx:id="customerNameColumn" prefWidth="175.0" text="Customer Name"/>
<TableColumn fx:id="customerPhoneColumn" prefWidth="123.0" text="Phone"/>
<TableColumn fx:id="customerAddressColumn" prefWidth="123.0" text="Address"/>
<TableColumn fx:id="customerPostalCodeColumn" prefWidth="123.0" text="Postal Code"/>
<TableColumn fx:id="customerDivisionColumn" prefWidth="123.0" text="Division"/>
<TableColumn fx:id="customerCountryColumn" prefWidth="123.0" text="Country"/>
</columns>
</TableView>
</children>
</AnchorPane>
<TitledPane alignment="CENTER" animated="false" layoutX="413.0" layoutY="100.0" prefHeight="464.0"
prefWidth="374.0" text="Customer Details">
<content>
<GridPane prefHeight="292.0" prefWidth="373.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="172.2000732421875" minWidth="10.0"
prefWidth="99.80004272460937"/>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="268.199951171875" minWidth="10.0"
prefWidth="253.39995727539065"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<TextField fx:id="customerCustomerIDTextField" onAction="#CustomerCustomerIDTextFieldHandler"
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label fx:id="customerCustomerIDLabel" text="Customer ID" GridPane.rowIndex="1"/>
<Label fx:id="customerCustomerNameLabel" text="Company Name" GridPane.rowIndex="2"/>
<Label fx:id="customerAddressLabel" text="Address" GridPane.rowIndex="4"/>
<Label fx:id="customerAddress2Label" text="POC" GridPane.rowIndex="3"/>
<Label fx:id="customerCityLabel" text="City" GridPane.rowIndex="5"/>
<Label fx:id="customerCountryLabel" text="Country" GridPane.rowIndex="6"/>
<Label fx:id="customerPostalCodeLabel" text="Postal Code" GridPane.rowIndex="7"/>
<Label fx:id="customerPhoneLabel" text="Phone No." GridPane.rowIndex="8"/>
<TextField fx:id="customerCustomerNameTextField"
onAction="#CustomerCustomerNameTextFieldHandler" GridPane.columnIndex="1"
GridPane.rowIndex="2"/>
<TextField fx:id="customerAddressTextField" onAction="#CustomerAddressTextFieldHandler"
GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<TextField fx:id="customerAddress2TextField" onAction="#CustomerAddress2TextFieldHandler"
GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<ComboBox fx:id="customerCityComboBox" onAction="#CustomerCityComboBoxHandler" prefHeight="26.0"
prefWidth="252.0" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
<ComboBox fx:id="customerCountryComboBox" onAction="#CustomerCountryComboBoxHandler"
prefHeight="26.0" prefWidth="252.0" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
<TextField fx:id="customerPostalCodeTextField" onAction="#CustomerPostalCodeTextFieldHandler"
GridPane.columnIndex="1" GridPane.rowIndex="7"/>
<TextField fx:id="customerPhoneTextField" onAction="#CustomerPhoneTextFieldHandler"
GridPane.columnIndex="1" GridPane.rowIndex="8"/>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="20.0"
GridPane.columnIndex="1">
<children>
<RadioButton fx:id="customerActiveRadioButton" mnemonicParsing="false"
onAction="#CustomerActiveRadioButtonHandler" text="Active"/>
<RadioButton fx:id="customerInactiveRadioButton" mnemonicParsing="false"
onAction="#CustomerInactiveRadioButtonHandler" text="Inactive"/>
</children>
</HBox>
</children>
</GridPane>
</content>
</TitledPane>
<ButtonBar layoutX="587.0" layoutY="564.0" prefHeight="40.0" prefWidth="200.0">
<buttons>
<Button fx:id="customerSaveButton" minWidth="66.0" mnemonicParsing="false"
onAction="#CustomerSaveButtonHandler" prefHeight="26.0" text="Save"/>
<Button fx:id="customerCancelButton" mnemonicParsing="false" onAction="#CustomerCancelButtonHandler"
text="Cancel"/>
</buttons>
</ButtonBar>
<ButtonBar layoutX="500.0" layoutY="613.0" prefHeight="40.0" prefWidth="200.0">
<buttons>
<Button fx:id="customerBackButton" mnemonicParsing="false" onAction="#CustomerBackButtonHandler"
text="Back"/>
<Button fx:id="customerAddButton" mnemonicParsing="false" onAction="#CustomerAddButtonHandler"
text="Add"/>
<Button fx:id="customerDeleteButton" mnemonicParsing="false" onAction="#CustomerDeleteButtonHandler"
text="Delete"/>
</buttons>
</ButtonBar>
<Label fx:id="customerLabel" layoutX="542.0" layoutY="52.0" prefHeight="40.0" prefWidth="90.0"
textFill="#1924e8">
<font>
<Font name="System Bold Italic" size="20.0"/>
</font>
</Label>
<Label layoutX="34.0" layoutY="517.0" prefHeight="27.0" prefWidth="327.0"
text="Click on Customer in Table to Update" textFill="#eb0c13">
<font>
<Font name="System Bold Italic" size="18.0"/>
</font>
</Label>
</children>
</AnchorPane>
I am not sure how to debug this. As the values in the ObservableList<Customer> are getting populated properly, it just doesn't appear in the TableView.
Here is the Customer class:
public class Customer {
private int customerID; //Auto incremented in database
private String customerName;
private int active;
private Date createDate;
private String createdBy;
private String address;
private String address2;
private String division;
private String postalCode;
private String phone;
private String country;
private Date lastUpdate;
private String lastUpdateBy;
public Customer() {
}
public Customer(int customerID, String customerName, int active, String address, String address2, String division, String postalCode, String phone, String country, Date lastUpdate, String lastUpdateBy) {
setCustomerID(customerID);
setCustomerName(customerName);
setCustomerActive(active);
setCustomerAddress(address);
setCustomerAddress2(address2);
setCustomerDivision(division);
setCustomerPostalCode(postalCode);
setCustomerPhone(phone);
setCustomerCountry(country);
setCustomerLastUpdate(lastUpdate);
setCustomerLastUpdateBy(lastUpdateBy);
}
public Customer(int customerID, String customerName) {
setCustomerID(customerID); //this is Auto Incremented in the database
setCustomerName(customerName);
}
public int getCustomerID() {
return customerID;
}
public String getCustomerName() {
return customerName;
}
public int getCustomerActive() {
return active;
}
public String getCustomerAddress() {
return address;
}
public String getCustomerAddress2() {
return address2;
}
public String getCustomerCity() {
return division;
}
public String getCustomerPostalCode() {
return postalCode;
}
public String getCustomerPhone() {
return phone;
}
public String getCustomerCountry() {
return country;
}
public Date getCustomerLastUpdate() {
return lastUpdate;
}
public String getCustomerLastUpdateBy() {
return lastUpdateBy;
}
public void setCustomerID(int customerID) {
this.customerID = customerID;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public void setCustomerActive(int active) {
this.active = active;
}
public void setCustomerAddress(String address) {
this.address = address;
}
public void setCustomerAddress2(String address2) {
this.address2 = address2;
}
public void setCustomerDivision(String city) {
this.division = city;
}
public void setCustomerPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public void setCustomerPhone(String phone) {
this.phone = phone;
}
public void setCustomerCountry(String country) {
this.country = country;
}
public void setCustomerLastUpdate(Date lastUpdate) {
this.lastUpdate = lastUpdate;
}
public void setCustomerLastUpdateBy(String lastUpdateBy) {
this.lastUpdateBy = lastUpdateBy;
}
}
Related
I need to pass the date property to the setCellValueFactory , this is the code for the seters and geters of my Persona class, what is the correct method to do that, i think i having an issue whit the correct declaration, so i need a real direction here, i need to declare some date in the java.sql.date class, do some reference? any idea?. please a little help here.
package application;
import java.time.LocalDate;
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;
public class Persona {
private StringProperty nombres;
private StringProperty apellidos;
private IntegerProperty id_cliente;
private ObjectProperty <LocalDate>fechacliente;
public Persona ( String nombres, String apellidos, Integer id_cliente, Object fechacliente) {
this.nombres= new SimpleStringProperty (nombres);
this.apellidos= new SimpleStringProperty ( apellidos);
this.id_cliente=new SimpleIntegerProperty (id_cliente);
this.fechacliente= new SimpleObjectProperty<LocalDate>();
}
public Object getFecha() {
return fechacliente.get();
}
public void setFecha(Object fechacliente) {
this.fechacliente=new SimpleObjectProperty<>();
}
public String getNombres() {
return nombres.get();
}
public void setNombres(String nombres) {
this.nombres=new SimpleStringProperty (nombres);
}
public String getApellidos() {
return apellidos.get();
}
public void setApellidos(String apellidos) {
this.apellidos=new SimpleStringProperty ( apellidos);
}
public Integer getId_cliente() {
return id_cliente.get();
}
public void setid_cliente(Integer id_cliente) {
this.id_cliente=new SimpleIntegerProperty (id_cliente);
}
}
Some of Controller here that set the values to the tableview
public void initialize(URL arg0, ResourceBundle arg1) {
clienteid.setCellValueFactory(new PropertyValueFactory <Persona, Integer>("id_cliente"));
nombrescol.setCellValueFactory(new PropertyValueFactory <Persona, String>("nombres"));
apellidoscol.setCellValueFactory(new PropertyValueFactory <Persona, String>("apellidos"));
fechacli.setCellValueFactory(new PropertyValueFactory <Persona, LocalDate>("fechacliente"));
seleccionaregistros();
seleccionanombre();
seleccionapellido();
}
this is the method i am using to retrieve the data in the tableview but the date does not show
public void seleccionaregistros() {
ObservableList <Persona> data =FXCollections.observableArrayList();
Connection conn=null;{
try {
conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=prueba", "sa", "milkas87");
Statement mostrar=conn.createStatement();
ResultSet rs;
rs= mostrar.executeQuery("select * from cliente");
while ( rs.next() )
{
data.add(new Persona(
rs.getString("nombre"),
rs.getString("apellido"),
rs.getInt("id"),
rs.getDate(4)
));
tablacliente.setItems(data);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
The date does not show in the tableview , i need to format the date to pass that value in the tableview i think. please some orientation here be helpful.
this is my FXML Code
<?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="497.0" prefWidth="943.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ConexionController">
<children>
<Pane layoutY="-3.0" prefHeight="605.0" prefWidth="1084.0">
<children>
<Button fx:id="btn" layoutX="145.0" layoutY="109.0" mnemonicParsing="false" onAction="#cargarconexion" prefHeight="46.0" prefWidth="117.0" text="Prueba Conexion" />
<Button fx:id="mtn" layoutX="15.0" layoutY="183.0" mnemonicParsing="false" onAction="#cargarregistro" prefHeight="46.0" prefWidth="117.0" text="Inserta Registro" />
<Label layoutX="14.0" layoutY="279.0" prefHeight="17.0" prefWidth="105.0" text="NOMBRES" />
<Label layoutX="15.0" layoutY="327.0" prefHeight="17.0" prefWidth="79.0" text="APELLIDOS" />
<TextField fx:id="nm" layoutX="159.0" layoutY="275.0" prefHeight="25.0" prefWidth="149.0" />
<TextField fx:id="ap" layoutX="159.0" layoutY="323.0" />
<Button fx:id="lmp" layoutX="159.0" layoutY="484.0" mnemonicParsing="false" onAction="#borrarcasillatexto" prefHeight="25.0" prefWidth="150.0" text="Limpiar Texto" />
<TableView fx:id="tablacliente" layoutX="355.0" layoutY="15.0" prefHeight="383.0" prefWidth="696.0">
<columns>
<TableColumn fx:id="clienteid" prefWidth="159.0" text="ID" />
<TableColumn fx:id="nombrescol" prefWidth="159.0" text="NOMBRES" />
<TableColumn fx:id="apellidoscol" minWidth="0.0" prefWidth="169.0" text="APELLIDOS" />
<TableColumn fx:id="fechacli" prefWidth="235.0" text="FECHA DE NACIMIENTO" />
</columns>
</TableView>
<Button fx:id="mts" layoutX="15.0" layoutY="109.0" mnemonicParsing="false" onAction="#mostrartodo" prefHeight="46.0" prefWidth="117.0" text="Mostrar" />
<TextField fx:id="bq" layoutX="554.0" layoutY="417.0" prefHeight="25.0" prefWidth="149.0" />
<Button fx:id="bqd" layoutX="758.0" layoutY="417.0" mnemonicParsing="false" onAction="#buscanm" prefHeight="25.0" prefWidth="155.0" text="BUSCAR NOMBRE" />
<Button fx:id="bqape" layoutX="758.0" layoutY="458.0" mnemonicParsing="false" onAction="#buscaape" prefHeight="25.0" prefWidth="155.0" text="BUSCAR POR APELLIDO" />
<TextField fx:id="bqa" layoutX="554.0" layoutY="458.0" />
<ComboBox layoutX="159.0" layoutY="430.0" prefWidth="150.0" />
<Label layoutX="15.0" layoutY="434.0" prefHeight="17.0" prefWidth="55.0" text="GENERO" />
<MenuBar fx:id="menucombo" layoutY="3.0">
<menus>
<Menu mnemonicParsing="false" text="Agregar">
<items>
<MenuItem mnemonicParsing="false" onAction="#inicializacombo" text="Datos Cliente" />
</items>
</Menu>
</menus>
</MenuBar>
<Button fx:id="botonborrar" layoutX="758.0" layoutY="507.0" mnemonicParsing="false" onAction="#borraregistroid" prefHeight="25.0" prefWidth="155.0" text="BORRAR REGISTRO" />
<TextField fx:id="borrar" layoutX="554.0" layoutY="507.0" />
<DatePicker fx:id="mifecha" layoutX="158.0" layoutY="371.0" prefHeight="25.0" prefWidth="150.0" />
<Label layoutX="15.0" layoutY="375.0" prefHeight="17.0" prefWidth="150.0" text="FECHA DE NACIMIENTO" />
</children>
</Pane>
</children>
</AnchorPane>
You're using JavaFX properties incorrectly. A property for a JavaFX Bean needs a getter, setter (if writable), and a property getter. Also, the setter should not be creating a new property each time; it should be setting the value of the existing property.
To simplify your example, if we have a Person with a single property, name, it would look like this:
public class Person {
private final StringProperty name = new SimpleStringProperty(this, "name");
public Person(String name) {
setName(name);
}
public final void setName(String name) { // setter
this.name.set(name);
}
public final String getName() { // getter
return name.get();
}
public final StringProperty nameProperty() { // property getter
return name;
}
}
Note: You can still initialize the properties in the constructor, instead of at the field declaration, if you want.
To use the name property in a TableView or TreeTableView you would simply return it in the cellValueFactory. Example using a TableView:
TableView<Person> table = new TableView<>();
TableColumn<Person, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(features -> features.getValue().nameProperty());
table.getColumns().add(nameCol);
Another issue with your code is that you're using a raw ObjectProperty. Don't use raw types. Instead, you should be using an ObjectProperty<Date> where Date is java.sql.Date. For example:
public class Person {
private final ObjectProperty<Date> clientDate = new SimpleObjectProperty<>(this, "clientDate");
public final void setClientDate(Date clientDate) {
this.clientDate.set(clientDate);
}
public final Date getClientDate() {
return clientDate.get();
}
public final ObjectProperty<Date> clientDateProperty() {
return clientDate;
}
}
Note: It'd probably be better to use one of the java.time classes (e.g. LocalDate, OffsetDateTime, etc...).
And again, to add it to a TableView it'd look like:
TableView<Person> table = new TableView<>();
TableColumn<Person, Date> clientDateCol= new TableColumn<>("Client Date");
clientDateCol.setCellValueFactory(features -> features.getValue().clientDateProperty());
table.getColumns().add(clientDateCol);
Someone help me, How I can pass a value from TableView(TableView show data from database) to textField and then the same value save to database??
Regards
ps I can Show the source code;
I think I m not able to explain it, I show u piece of code
this is my 1 st fxml file where I take data from user:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mojprogram.elkosz.controllers.AddCashRegisterController">
<children>
<GridPane prefHeight="398.0" prefWidth="624.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="295.0" minWidth="10.0" prefWidth="193.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="449.0" minWidth="10.0" prefWidth="407.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Model Kasy Fiskalnej" GridPane.rowIndex="1" />
<Label text="Numer Seryjny" GridPane.rowIndex="2" />
<Label text="Data Zakupu" GridPane.rowIndex="3" />
<Label text="Data Pierwszego Przeglądu" GridPane.rowIndex="4" />
<Button fx:id="choisebutton" mnemonicParsing="false" onAction="#choiceCompany" text="Firma" />
<Label text="Data Następnego Przeglądu" GridPane.rowIndex="5" />
<TextField fx:id="companytextfieldCH" GridPane.columnIndex="1" />
<TextField fx:id="cashMachinetextfield" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="serialnumber" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<DatePicker fx:id="buydate" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<DatePicker fx:id="firstcheck" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<DatePicker fx:id="nextchech" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Button fx:id="addmachine" mnemonicParsing="false" onAction="#addCashRegister" text="Dodaj" GridPane.columnIndex="1" GridPane.rowIndex="6" />
</children>
</GridPane>
</children>
</HBox>
This is Controller:
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.io.IOException;
public class AddCashRegisterController {
#FXML
private Button addRegister;
#FXML
private TextField cashMachinetextfield;
#FXML
private TextField serialnumber;
#FXML
private DatePicker buydate;
#FXML
private DatePicker firstcheck;
#FXML
private DatePicker nextcheck;
#FXML
private TextField companytextfieldCH;
private CashRegisterModel cashRegisterModel;
public void choiceCompany() {
Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/ChoiceCompany.fxml"));
try {
Parent parent = loader.load();
ChoiceCompanyController controller = loader.getController();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
#FXML
private void initialize(){
this.cashRegisterModel = new CashRegisterModel();
}
public void addCashRegister() {
}
}
This is fxml file with Tableview
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox fx:id="choiceCompany" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="487.0" prefWidth="743.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mojprogram.elkosz.controllers.ChoiceCompanyController">
<children>
<TableView fx:id="CompanyTableView" onMouseClicked="#choice" prefHeight="446.0" prefWidth="743.0">
<columns>
<TableColumn fx:id="companycolumn" prefWidth="120.0" text="Nazwa Firmy" />
<TableColumn fx:id="NIPcolumn" prefWidth="116.0" text="NIP" />
<TableColumn fx:id="citycolumn" minWidth="0.0" prefWidth="115.0" text="Miejscowość" />
<TableColumn fx:id="streetcolum" minWidth="0.0" prefWidth="113.0" text="Ulica" />
<TableColumn fx:id="contactcolumn" prefWidth="124.0" text="Osoba Kontaktowa" />
<TableColumn fx:id="phonecolumn" prefWidth="153.0" text="Numer Telefonu" />
</columns>
</TableView>
<HBox alignment="CENTER_RIGHT" prefHeight="100.0" prefWidth="200.0">
<children>
<Button fx:id="closeButton" mnemonicParsing="false" onAction="#closeButtonaction" prefHeight="25.0" prefWidth="75.0" text="Ok" />
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<VBox.margin>
<Insets right="35.0" />
</VBox.margin>
</HBox>
</children>
</VBox>
This is controller of this
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import mojprogram.elkosz.modelFX.CompanyFx;
import mojprogram.elkosz.modelFX.CompanyListModel;
import org.omg.CORBA.portable.ApplicationException;
import java.awt.*;
public class ChoiceCompanyController {
#FXML
public Button closeButton;
public VBox getChoiceCompany() {
return choiceCompany;
}
#FXML
private VBox choiceCompany;
#FXML
private TableView<CompanyFx> CompanyTableView;
#FXML
private TableColumn<CompanyFx, String> companycolumn;
#FXML
private TableColumn<CompanyFx, String> NIPcolumn;
#FXML
private TableColumn<CompanyFx, String> citycolumn;
#FXML
private TableColumn<CompanyFx, String> streetcolum;
#FXML
private TableColumn<CompanyFx, String> contactcolumn;
#FXML
private TableColumn<CompanyFx, String> phonecolumn;
private CompanyListModel companyListModel;
#FXML
private void initialize(){
this.companyListModel = new CompanyListModel();
try {
this.companyListModel.iniati();
} catch (ApplicationException e) {
e.printStackTrace();
}
this.CompanyTableView.setItems(this.companyListModel.getCompanyFxObservableList());
this.companycolumn.setCellValueFactory(cellData -> cellData.getValue().companyNameFxProperty());
this.NIPcolumn.setCellValueFactory(cellData -> cellData.getValue().NIPfxProperty());
this.citycolumn.setCellValueFactory(cellData -> cellData.getValue().cityfxProperty());
this.streetcolum.setCellValueFactory(cellData -> cellData.getValue().streetfxProperty());
this.contactcolumn.setCellValueFactory(cellData -> cellData.getValue().contactpersonfxProperty());
phonecolumn.setCellValueFactory(cellData -> cellData.getValue().phonenumberfxProperty());
}
#FXML
public void choice() {
//CompanyTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
CompanyFx selected = CompanyTableView.getSelectionModel().getSelectedItem();
System.out.print(selected.toString());
}
#FXML
public void closeButtonaction() {
Stage stage = (Stage) closeButton.getScene().getWindow();
stage.close();
}
}
From this tableview I try to pass value to textfield and then I want to save it in new table of database
I don't understant what you need exactly ,but i think that you desire to get value from row of TableView and pass value of cell to TextField, you can do this if you acces to rows and get values from cells one by one.
PersonView.setRowFactory(event -> {
TableRow<Person> row = new TableRow<>();
row.setOnMouseEntered(event -> {
try {
if (row.isSelected) {
if (row.getItem().getId() != null && row.getItem().getName() != null) {
String Id=row.getItem.getId();
String Name=row.getItem.getId();
IdTextField.setText(Id);
NameTextField.setText(Name);
}
});
return row;
});
I hope this code can help you
I just don't get what I'm doing wrong. Everything seems OK, but data just don't wont to load in table.
This is controller class of stage:
package application.controllers;
import application.meetings.MeetingData;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import java.net.URL;
import java.util.ResourceBundle;
public class EditMeetingPopUpController {
#FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
#FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
#FXML // fx:id="dateAndTimeInformation"
private DatePicker dateAndTimeInformation; // Value injected by FXMLLoader
#FXML // fx:id="hoursInformation"
private ComboBox<String> hoursInformation; // Value injected by FXMLLoader
#FXML // fx:id="minutesInformation"
private ComboBox<String> minutesInformation; // Value injected by FXMLLoader
#FXML // fx:id="placeInformation"
private TextField placeInformation; // Value injected by FXMLLoader
#FXML // fx:id="categoryInformation"
private ComboBox<String> categoryInformation; // Value injected by FXMLLoader
#FXML // fx:id="contactsInformation"
private ComboBox<String> contactsInformation; // Value injected by FXMLLoader
#FXML // fx:id="allSelectedContactsTextArea"
private TextArea allSelectedContactsTextArea; // Value injected by FXMLLoader
#FXML // fx:id="commentInformation"
private TextArea commentInformation; // Value injected by FXMLLoader
// Table variables
#FXML // fx:id="meetingTable"
private TableView<MeetingData> meetingTable; // Value injected by FXMLLoader
#FXML // fx:id="dateAntTimeColumn"
private TableColumn<MeetingData, String> dateAntTimeColumn; // Value injected by FXMLLoader
#FXML // fx:id="placeColumn"
private TableColumn<MeetingData, String> placeColumn; // Value injected by FXMLLoader
#FXML // fx:id="categoryColumn"
private TableColumn<MeetingData, String> categoryColumn; // Value injected by FXMLLoader
#FXML // fx:id="contactsColumn"
private TableColumn<MeetingData, String> contactsColumn; // Value injected by FXMLLoader
#FXML // fx:id="commentsColumn"
private TableColumn<MeetingData, String> commentsColumn; // Value injected by FXMLLoader
#FXML // Add more contactsColumn to contactsColumn list
void addContactToAllContactsTextArea(ActionEvent event) {
}
#FXML
void editMeeting(ActionEvent event) {
}
#FXML
void loadInformationForMeeting(ActionEvent event) {
ObservableList<MeetingData> data = getMeetingData();
this.meetingTable = new TableView<>();
this.meetingTable.setItems(data);
this.placeColumn.setCellValueFactory(new PropertyValueFactory<MeetingData, String>("date"));
this.placeColumn.setCellValueFactory(new PropertyValueFactory<MeetingData, String>("place"));
this.categoryColumn.setCellValueFactory(new PropertyValueFactory<MeetingData, String>("category"));
this.contactsColumn.setCellValueFactory(new PropertyValueFactory<MeetingData, String>("contacts"));
this.commentsColumn.setCellValueFactory(new PropertyValueFactory<MeetingData, String>("comments"));
this.meetingTable.getColumns().add(this.dateAntTimeColumn);
this.meetingTable.getColumns().add(this.placeColumn);
this.meetingTable.getColumns().add(this.categoryColumn);
this.meetingTable.getColumns().add(this.contactsColumn);
this.meetingTable.getColumns().add(this.commentsColumn);
// // TODO: 01-Feb-17 delete this after finish
// for (MeetingData meetingData : data) {
// System.out.println(meetingData.getDate());
// System.out.println(meetingData.getPlace());
// System.out.println(meetingData.getCategory());
// System.out.println(meetingData.getContacts());
// System.out.println(meetingData.getComments());
// System.out.println("----- END -----");
// System.out.println();
// }
}
// get all meetings
public ObservableList<MeetingData> getMeetingData() {
ObservableList<MeetingData> data = FXCollections.observableArrayList();
data.add(new MeetingData("sdzgzrdbf", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
data.add(new MeetingData("sEDGdb", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
data.add(new MeetingData("sdzgsbfgzrdbf", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
data.add(new MeetingData("zsrbd", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
data.add(new MeetingData("rbdbdb", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
data.add(new MeetingData("rsbdbd", "sgzsfbs", "EDbfb", "sbdbf", "zbdd"));
return data;
}
#FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert dateAndTimeInformation != null : "fx:id=\"dateAndTimeInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert hoursInformation != null : "fx:id=\"hoursInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert minutesInformation != null : "fx:id=\"minutesInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert placeInformation != null : "fx:id=\"placeInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert categoryInformation != null : "fx:id=\"categoryInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert contactsInformation != null : "fx:id=\"contactsInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert allSelectedContactsTextArea != null : "fx:id=\"allSelectedContactsTextArea\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert commentInformation != null : "fx:id=\"commentInformation\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert meetingTable != null : "fx:id=\"meetingTable\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert dateAntTimeColumn != null : "fx:id=\"dateAntTimeColumn\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert placeColumn != null : "fx:id=\"placeColumn\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert categoryColumn != null : "fx:id=\"categoryColumn\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert contactsColumn != null : "fx:id=\"contactsColumn\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
assert commentsColumn != null : "fx:id=\"commentsColumn\" was not injected: check your FXML file 'EditMeetingPopUp.fxml'.";
}
}
This is data class:
package application.meetings;
public class MeetingData {
// Fields
private String date;
private String place;
private String category;
private String contacts;
private String comments;
// Constructors
public MeetingData(String date, String place, String category, String contacts, String comments) {
this.date = date;
this.place = place;
this.category = category;
this.contacts = contacts;
this.comments = comments;
}
// Setters
public void setDate(String date) {
this.date = date;
}
public void setPlace(String place) {
this.place = place;
}
public void setCategory(String category) {
this.category = category;
}
public void setContacts(String contacts) {
this.contacts = contacts;
}
public void setComments(String comments) {
this.comments = comments;
}
// Getters
public String getDate() {
return date;
}
public String getPlace() {
return place;
}
public String getCategory() {
return category;
}
public String getContacts() {
return contacts;
}
public String getComments() {
return comments;
}
}
And finally FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="450.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controllers.EditMeetingPopUpController">
<bottom>
<HBox alignment="CENTER_RIGHT" BorderPane.alignment="CENTER">
<children>
<Button mnemonicParsing="false" onAction="#loadInformationForMeeting" text="Зареди информация">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Button>
<Button defaultButton="true" mnemonicParsing="false" onAction="#editMeeting" prefWidth="80.0" text="Редактирай">
<HBox.margin>
<Insets />
</HBox.margin></Button>
</children>
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</HBox>
</bottom>
<center>
<VBox alignment="CENTER">
<children>
<HBox alignment="CENTER_LEFT">
<children>
<Label prefWidth="70.0" text="Дата" />
<DatePicker fx:id="dateAndTimeInformation" prefWidth="220.0" promptText="Дата" showWeekNumbers="true">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
<tooltip>
<Tooltip text="Полето е задължително" />
</tooltip>
</DatePicker>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT">
<children>
<Label prefWidth="70.0" text="Час" />
<ComboBox fx:id="hoursInformation" prefWidth="70.0">
<HBox.margin>
<Insets left="20.0" right="5.0" />
</HBox.margin>
<tooltip>
<Tooltip text="Полето е задължително" />
</tooltip>
</ComboBox>
<Label text="часa">
<HBox.margin>
<Insets right="20.0" />
</HBox.margin>
</Label>
<ComboBox fx:id="minutesInformation" prefWidth="70.0">
<HBox.margin>
<Insets right="5.0" />
</HBox.margin>
<tooltip>
<Tooltip text="Полето е задължително" />
</tooltip>
</ComboBox>
<Label text="мин.">
<HBox.margin>
<Insets />
</HBox.margin>
</Label>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="218.0">
<children>
<Label prefWidth="70.0" text="Място" />
<TextField fx:id="placeInformation" prefWidth="220.0" promptText="Място на срещата">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</TextField>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="253.0">
<children>
<Label prefWidth="70.0" text="Категория" />
<ComboBox fx:id="categoryInformation" prefWidth="220.0" promptText="Изберете категория">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</ComboBox>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="240.0">
<children>
<Label prefWidth="70.0" text="Участници" />
<ComboBox fx:id="contactsInformation" onAction="#addContactToAllContactsTextArea" prefWidth="220.0" promptText="Изберете участници">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
<tooltip>
<Tooltip text="Полето е задължително" />
</tooltip>
</ComboBox>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox>
<children>
<Pane prefHeight="100.0" prefWidth="70.0" />
<TextArea fx:id="allSelectedContactsTextArea" editable="false" prefHeight="100.0" prefWidth="220.0" promptText="Участници в срещата">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</TextArea>
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="10.0" layoutY="293.0">
<children>
<Label alignment="TOP_LEFT" prefHeight="100.0" prefWidth="70.0" text="Коментар" />
<TextArea fx:id="commentInformation" prefHeight="100.0" prefWidth="220.0" promptText="Въведете коментар">
<HBox.margin>
<Insets bottom="10.0" left="20.0" />
</HBox.margin>
<tooltip>
<Tooltip text="Полето е задължително" />
</tooltip>
</TextArea>
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</HBox>
</children>
</VBox>
</center>
<left>
<VBox BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</VBox>
</left>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
<top>
<Label alignment="CENTER" prefWidth="600.0" text="Моля изберете среща за редактиране">
<font>
<Font name="System Bold" size="14.0" />
</font>
<BorderPane.margin>
<Insets bottom="10.0" left="360.0" />
</BorderPane.margin>
</Label>
</top>
<right>
<TableView fx:id="meetingTable" editable="true" prefWidth="600.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="dateAntTimeColumn" prefWidth="75.0" text="Дата и час" >
<cellValueFactory>
<PropertyValueFactory property="date" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="placeColumn" prefWidth="75.0" text="Място" >
<cellValueFactory>
<PropertyValueFactory property="place" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="categoryColumn" prefWidth="75.0" text="Категория" >
<cellValueFactory>
<PropertyValueFactory property="category" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="contactsColumn" prefWidth="75.0" text="Участници" >
<cellValueFactory>
<PropertyValueFactory property="contacts" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="commentsColumn" prefWidth="114.0" text="Коментар" >
<cellValueFactory>
<PropertyValueFactory property="comments" />
</cellValueFactory>
</TableColumn>
</columns>
<BorderPane.margin>
<Insets bottom="10.0" />
</BorderPane.margin>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</right>
</BorderPane>
I would be very grateful if you can help me and explain from where is mistake.
First, your loadInformationforMeeting() method creates a new TableView, adds data to it, reconfigures the table columns (with the same configuration they already have...) and adds the table columns to the new table.
However, since the new table is not ever placed in the UI, you never see the data. There is no need to create a new table.
Secondly, if you use the existing table (the one defined by the FXML file), it already has the columns attached, and those columns already have cell value factories. So you should not add the columns to the table again, and do not need to repeat the configuration of the columns.
All you need is
#FXML
void loadInformationForMeeting(ActionEvent event) {
ObservableList<MeetingData> data = getMeetingData();
this.meetingTable.setItems(data);
}
In this simple JavaFX application, when a new user is added, text that says "New User added" is printed into a text area in the first tab. How can an additional tab be added and text "New User added" printed into a text area in it each time a new user is added?
Any help would be greatly appreciated.
View > PersonOverview.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<HBox xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.makery.address.PersonOverviewController">
<children>
<TableView fx:id="personTable" prefHeight="298.0" prefWidth="246.0">
<columns>
<TableColumn fx:id="firstNameColumn" prefWidth="75.0" text="First Name" />
<TableColumn fx:id="lastNameColumn" prefWidth="75.0" text="Last Name" />
</columns>
</TableView>
<VBox prefHeight="298.0" prefWidth="271.0">
<children>
<AnchorPane prefHeight="284.0" prefWidth="227.0">
<children>
<Label layoutX="9.0" layoutY="4.0" prefHeight="19.0" prefWidth="96.0" text="Person Details" />
<GridPane layoutX="108.0" layoutY="121.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="30.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="First Name" />
<Label text="Last Name" GridPane.rowIndex="1" />
<Label text="Street" GridPane.rowIndex="2" />
<Label text="City" GridPane.rowIndex="3" />
<Label text="Postal Code" GridPane.rowIndex="4" />
<Label text="Birthday" GridPane.rowIndex="5" />
<Label fx:id="firstNameLabel" text="Label" GridPane.columnIndex="1" />
<Label fx:id="lastNameLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label fx:id="streetLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label fx:id="cityLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label fx:id="postalCodeLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label fx:id="birthdayLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="5" />
</children>
</GridPane>
<ButtonBar buttonMinWidth="50.0" layoutX="14.0" layoutY="244.0" prefHeight="40.0" prefWidth="200.0">
<buttons>
<Button mnemonicParsing="false" onAction="#handleNewPerson" text="New" />
<Button mnemonicParsing="false" onAction="#handleEditPerson" text="Edit" />
<Button mnemonicParsing="false" onAction="#handleDeletePerson" text="Delete" />
</buttons>
</ButtonBar>
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</AnchorPane>
</children>
</VBox>
<TabPane prefHeight="296.0" prefWidth="337.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab>
<content>
<TextArea fx:id="textArea" prefHeight="264.0" prefWidth="302.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</HBox>
View > PersonOverviewController
package ch.makery.address;
import ch.makery.address.util.DateUtil;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import ch.makery.address.MainApp;
import ch.makery.address.model.Person;
public class PersonOverviewController {
#FXML
private TableView<Person> personTable;
#FXML
private TableColumn<Person, String> firstNameColumn;
#FXML
private TableColumn<Person, String> lastNameColumn;
#FXML
private Label firstNameLabel;
#FXML
private Label lastNameLabel;
#FXML
private Label streetLabel;
#FXML
private Label postalCodeLabel;
#FXML
private Label cityLabel;
#FXML
private Label birthdayLabel;
#FXML
private TextArea textArea;
// Reference to the main application.
private MainApp mainApp;
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public PersonOverviewController() {
}
/**
* Initializes the controller class. This method is automatically called
* after the fxml file has been loaded.
*/
#FXML
private void initialize() {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(
cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(
cellData -> cellData.getValue().lastNameProperty());
// Clear person details.
showPersonDetails(null);
// Listen for selection changes and show the person details when changed.
personTable.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> showPersonDetails(newValue));
}
/**
* Is called by the main application to give a reference back to itself.
*
* #param mainApp
*/
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
// Add observable list data to the table
personTable.setItems(mainApp.getPersonData());
}
/**
* Fills all text fields to show details about the person.
* If the specified person is null, all text fields are cleared.
*
* #param person the person or null
*/
private void showPersonDetails(Person person) {
if (person != null) {
// Fill the labels with info from the person object.
firstNameLabel.setText(person.getFirstName());
lastNameLabel.setText(person.getLastName());
streetLabel.setText(person.getStreet());
postalCodeLabel.setText(Integer.toString(person.getPostalCode()));
cityLabel.setText(person.getCity());
birthdayLabel.setText(DateUtil.format(person.getBirthday()));
// birthdayLabel.setText(...);
} else {
// Person is null, remove all the text.
firstNameLabel.setText("");
lastNameLabel.setText("");
streetLabel.setText("");
postalCodeLabel.setText("");
cityLabel.setText("");
birthdayLabel.setText("");
}
}
public void print(String message) {
textArea.appendText(message);
}
/**
* Called when the user clicks on the delete button.
*/
#FXML
private void handleDeletePerson() {
int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0) {
personTable.getItems().remove(selectedIndex);
} else {
// Nothing selected.
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.initOwner(mainApp.getPrimaryStage());
alert.setTitle("No Selection");
alert.setHeaderText("No Person Selected");
alert.setContentText("Please select a person in the table.");
alert.showAndWait();
}
}
/**
* Called when the user clicks the new button. Opens a dialog to edit
* details for a new person.
*/
#FXML
private void handleNewPerson() {
Person tempPerson = new Person();
boolean okClicked = mainApp.showPersonEditDialog(tempPerson);
if (okClicked) {
mainApp.getPersonData().add(tempPerson);
print("New User added");
}
}
/**
* Called when the user clicks the edit button. Opens a dialog to edit
* details for the selected person.
*/
#FXML
private void handleEditPerson() {
Person selectedPerson = personTable.getSelectionModel().getSelectedItem();
if (selectedPerson != null) {
boolean okClicked = mainApp.showPersonEditDialog(selectedPerson);
if (okClicked) {
showPersonDetails(selectedPerson);
}
} else {
// Nothing selected.
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.initOwner(mainApp.getPrimaryStage());
alert.setTitle("No Selection");
alert.setHeaderText("No Person Selected");
alert.setContentText("Please select a person in the table.");
alert.showAndWait();
}
}
}
In you're handleNewPerson method, you would have to add something like:
Tab tab = new Tab();
tab.setText("TabText");
TextArea ta = new TextArea("New User added");
tab.setContent(ta);
tabPan.getTabs().add(tab);
And add add:
#FXML
private TabPane tabPan;
And in the fxml add
fx:id="tabPan"
To the TabPane
Now I have not been able to test your program due to your program requires a lot of the other classes. But you can also see a good example of somthing similar her.
I'm building a DialogPane in FXML and I'm trying to figure out how to respond to button presses on the dialog since onAction is not a valid parameter for ButtonType. I've attached my FXML and Controller Class. There is very little documentation about DialogPane and even less about doing it in FXML so I'm not sure how to proceed.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ButtonType?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<DialogPane fx:id="loginPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="LoginController">
<content>
<GridPane hgap="5.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="300.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Driver Name" />
<TextField fx:id="driverTxt" GridPane.columnIndex="1" />
<Label text="URL" GridPane.rowIndex="1" />
<TextField fx:id="urlTxt" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Username" GridPane.rowIndex="2" />
<TextField fx:id="userTxt" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Password" GridPane.rowIndex="3" />
<TextField fx:id="passTxt" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</children>
</GridPane>
</content>
<buttonTypes>
<ButtonType fx:id="loginButton" text="Login" />
<ButtonType fx:id="cancelBtn" text="Cancel" />
</buttonTypes>
</DialogPane>
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextField;
public class LoginController {
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
#FXML
ButtonType loginButton;
#FXML
private void loginButtonAction(){
// How do I do something here
}
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
}
Typically you wouldn't need to do this. You would usually show a DialogPane in a Dialog<ButtonType> calling its showAndWait() method, which returns an Optional<ButtonType> representing the button pressed (if any). So normal usage would be something like
public class LoginController {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public String getDriver() {
return driverTxt.getText();
}
public String getUrl() {
return urlTxt.getText();
}
public String getUser() {
return userTxt.getText();
}
public String getPass() {
return pass.getText();
}
}
and make the following changes to your FXML file:
<buttonTypes>
<LoginController fx:constant="LOGIN" />
<ButtonType fx:constant="CANCEL" />
</buttonTypes>
Then you would use this with:
Dialog<ButtonType> dialog = new Dialog<>();
FXMLLoader dialogLoader = new FXMLLoader(getClass().getResource("Login.fxml"));
dialog.setDialogPane(dialogLoader.load());
LoginController controller = dialogLoader.getController();
dialog.showAndWait().filter(LoginController.LOGIN::equals)
.ifPresent(button -> {
String driver = controller.getDriver();
// etc etc
// process login...
});
As an alternative to exposing the text from the text fields, you could define a processLogin() method in the controller itself that read the text fields and did whatever you need to do:
public class LoginController {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public void processLogin() {
String driver = driverTxt.getText();
// etc...
// process login...
}
}
then just do
// ...
dialog.showAndWait().filter(LoginController.LOGIN::equals)
.ifPresent(button -> controller.processLogin());
If you really need to register an onAction handler with the login button, do it in the initialize() method in the controller:
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
Button login = (Button) loginPane.lookupButton(loginButton);
login.setOnAction(e -> { /* ... */ });
}
but this is really against the intended use of the dialog pane API.
One final alternative would be to override the createButton method in DialogPane. To do this, you'd need a subclass of DialogPane, which would mean using the FXML custom component pattern.
So this would look something like:
public class LoginPane extends DialogPane {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public LoginPane() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LoginPane.fxml"));
loader.setRoot(this);
loader.setController(this);
loader.load();
} catch (IOException exc) {
// bad if you get here...
throw new UncheckedIOException(exc);
}
}
#Override
public Node createButton(ButtonType buttonType) {
Node button = super.createButton(buttonType);
if (buttonType == LOGIN) {
((Button) button).setOnAction(e -> processLogin());
}
return button ;
}
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public void processLogin() {
String driver = driverTxt.getText();
// etc...
// process login...
}
}
and the FXML would then look like
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ButtonType?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<fx:root type="DialogPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<content>
<GridPane hgap="5.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="300.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Driver Name" />
<TextField fx:id="driverTxt" GridPane.columnIndex="1" />
<Label text="URL" GridPane.rowIndex="1" />
<TextField fx:id="urlTxt" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Username" GridPane.rowIndex="2" />
<TextField fx:id="userTxt" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Password" GridPane.rowIndex="3" />
<TextField fx:id="passTxt" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</children>
</GridPane>
</content>
<buttonTypes>
<LoginPane fx:constant="LOGIN" />
<ButtonType fx:constant="CANCEL" />
</buttonTypes>
</fx:root>
You would use this version with
Dialog dialog = new Dialog();
dialog.setDialogPane(new LoginPane());
dialog.showAndWait();
so if you are looking to encapsulate as much as possible into the login pane and fxml, this is probably the cleanest option.
Note that the usage of DialogPane is fairly completely documented in the API docs for Dialog and DialogPane.