I want to know how can you insert different elements in the same column of a tableView
in my view (FXML) I have a combobox which contains "person", a textfield to enter the person's number and a button and add these elements in a Table View
FXML file
<SplitPane dividerPositions="0.3002754820936639" focusTraversable="true" prefHeight="160.0" prefWidth="200.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TableView fx:id="personnes" minWidth="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="200.0" text="Peronnes" fx:id="column">
<cellValueFactory>
<PropertyValueFactory property="nom" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ComboBox fx:id="listPeronnes" layoutX="25.0" layoutY="40.0" prefWidth="148.0">
</ComboBox>
<TextField fx:id="num" layoutX="25.0" layoutY="95.0" prefWidth="149.0" />
<Label layoutX="25.0" layoutY="78.0" prefWidth="66.0" text="numero" />
<Label layoutX="25.0" layoutY="14.0" prefWidth="66.0" text="Personnes" />
<Button onAction="#handleAdd" layoutX="25.0" layoutY="121.0" mnemonicParsing="false" text="Ajouter" />
</children>
</AnchorPane>
</items>
</SplitPane>
So what I'm trying to do is, when the user launches the application. He entered a number in the textfield, i have to insert this number in tableview, then if user want to insert another persone, but by using combobox, he chose a person in combobox and add the name of this persone into tableView (so my Table View will contains Numbers and names (both string )
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class SampleController implements Initializable {
private Stage stage;
#FXML
protected ComboBox<Personnes> listPeronnes;
#FXML
protected TableView personnes;
#FXML
protected TableColumn column;
#FXML
protected TextField num;
ObservableList<Personnes> liste =
FXCollections.observableArrayList(new Personnes("personne 1", 1),new Personnes("Personne 2",2));
protected ListProperty<String> prs=new SimpleListProperty<>(FXCollections.<String>observableArrayList());
#FXML
protected void handleAdd()
{ prs.add(num.getText());
prs.add(listPeronnes.getSelectionModel().getSelectedItem().getNom());
personnes.getItems().setAll(prs);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
listPeronnes.getItems().setAll(liste);
}
}
Related
I'm working on a desktop application using javaFX, I'm using scene builder version 11 to create my interface that contains TextFields and ChoiceBox, my inputs are supposed to be set in Arabic. The problem is when I retrieve the text from the TextFiled or the ChoiceBox and print it in the console it shows characters like that "بننلنلن" and it also generates a problem to store the inputs in database, this is the SQLException:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'بننلنلن,نبلنبنلب,2021-06-30,أمر جزائي,تم التبليغ
When I tried another project without scene builder I got the Arabic outputs correctly, could scene bulider be the problem's origin?
here is my fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane id="AnchorIns" prefHeight="529.0" prefWidth="523.0" stylesheets="#newinsc.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="newInsc.NewInscController">
<children>
<VBox fx:id="boxContainer" layoutX="139.0" layoutY="99.0" prefHeight="273.0" prefWidth="245.0">
<children>
<HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="245.0">
<children>
<TextField fx:id="firstNameTxtField" alignment="CENTER_RIGHT" />
<Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="71.0" stylesheets="#newinsc.css" text="الاسم" />
</children>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="245.0">
<children>
<TextField fx:id="lastNameTxtField" alignment="CENTER_RIGHT" />
<Label prefHeight="17.0" prefWidth="71.0" text="اللقب" />
</children>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="245.0">
<children>
<ChoiceBox fx:id="docTypeChoice" prefWidth="150.0" />
<Label prefHeight="17.0" prefWidth="71.0" text="نوع التبليغ" />
</children>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="245.0">
<children>
<DatePicker fx:id="dateField" prefHeight="25.0" prefWidth="149.0" />
<Label prefHeight="17.0" prefWidth="71.0" text="التاريخ" />
</children>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="245.0">
<children>
<ChoiceBox fx:id="tablighCase" prefWidth="150.0" />
<Label prefHeight="17.0" prefWidth="71.0" text="حالة التبليغ" />
</children>
</HBox>
<HBox alignment="CENTER" onMouseClicked="#cancelBtnClicked" prefHeight="46.0" prefWidth="245.0">
<children>
<Button fx:id="cancleBtn" mnemonicParsing="false" onMouseClicked="#cancelBtnClicked" text="الغاء">
<HBox.margin>
<Insets right="16.0" />
</HBox.margin>
</Button>
<Button fx:id="saveInscBtn" mnemonicParsing="false" onMouseClicked="#registerBtnClicked" text="تسجيل" />
</children>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
and this here is my controller file:
package newInsc;
import DB.dbConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* #author asus
*/
public class NewInscController implements Initializable {
#FXML
private ChoiceBox<String> docTypeChoice;
#FXML
private ChoiceBox<String> tablighCase;
#FXML
private DatePicker dateField;
#FXML
private Button saveInscBtn;
#FXML
private TextField firstNameTxtField;
#FXML
private TextField lastNameTxtField;
#FXML
private Button cancleBtn;
private Connection c;
private Statement s;
#FXML
private VBox boxContainer;
#Override
public void initialize(URL url, ResourceBundle rb) {
docTypeChoice.getItems().add("أمر جزائي");
docTypeChoice.getItems().add("حكم جزائي" );
docTypeChoice.getItems().add("تكليف بالحضور" );
docTypeChoice.getItems().add("قرار جزائي" );
tablighCase.getItems().add("تم التبليغ");
tablighCase.getItems().add("ترك اشعار");
tablighCase.getItems().add("عدم التمكن من التبليغ");
}
#FXML
private void cancelBtnClicked(MouseEvent event) {
Stage s = (Stage) cancleBtn.getScene().getWindow();
}
#FXML
private void registerBtnClicked(MouseEvent event) {
try {
String query;
String fname = firstNameTxtField.getText();
String lname = lastNameTxtField.getText();
LocalDate date = dateField.getValue();
String docType = docTypeChoice.getValue();
String state = tablighCase.getValue();
query = "insert into infotable values " + fname + "," + lname + "," + date+ ","+ docType+"," +state ;
dbConnection dbc = new dbConnection();
s = dbc.createConnection().createStatement();
s.execute(query);
s.close();
} catch (SQLException ex) {
Logger.getLogger(NewInscController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I could find a solution, before I run the program I first compile it with F9 key then I run it with a key combination SHIFT + F6
The image is pretty self explanatory. The TableView doesn't auto resize when I resize the window. In C#, I used to do this by using Anchor/Dock properties. How am I supposed to do it in JavaFX? I can't find information about it, probably because Java uses different terms.
table.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<DialogPane prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.TableController">
<header>
<AnchorPane minHeight="50.0" minWidth="0.0" prefHeight="80.0" prefWidth="400.0">
<children>
<HBox alignment="TOP_CENTER" prefHeight="100.0" prefWidth="400.0">
<children>
<Label fx:id="descriptionLabel" alignment="CENTER" contentDisplay="CENTER" prefWidth="400.0" text="Text:" textAlignment="JUSTIFY">
<font>
<Font size="22.0" />
</font>
</Label>
</children>
</HBox>
</children>
</AnchorPane>
</header>
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="400.0">
<children>
<TableView fx:id="tableView" layoutY="-31.0" prefHeight="252.0" prefWidth="400.0">
<columns>
</columns>
</TableView>
</children>
</AnchorPane>
</content>
</DialogPane>
TableController.java
package gui;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.util.Callback;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TableController {
#FXML
private Label descriptionLabel;
#FXML
private TableView tableView;
public void setTableResultset(String label, ResultSet resultSet) throws SQLException {
ObservableList<ObservableList> data = FXCollections.observableArrayList();
// Columns
for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
final int j = i;
TableColumn col = new TableColumn(resultSet.getMetaData().getColumnName(i + 1));
col.setCellValueFactory((Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>) param -> {
return new SimpleStringProperty(param.getValue().get(j).toString());
});
tableView.getColumns().add(col);
}
// Add records
while (resultSet.next()) {
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
row.add(resultSet.getString(i));
}
data.add(row);
}
tableView.setItems(data);
// Set label text
descriptionLabel.setText(label);
}
}
You need to set AnchorPane's top, bottom, right and left anchors:
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="200.0" prefWidth="400.0">
<children>
<TableView fx:id="tableView" layoutY="-31.0" prefHeight="252.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
</columns>
</TableView>
</children>
</AnchorPane>
I am trying to solve an issue with a calculator project I am working on with javafx 11 and java11 using Scene Builder. I am trying to figure out a way to make the buttons on the calculator change color when typing the corresponding value from the keyboard. Is there a method, or onKeyPressed etc type solution to this issue?
I was able to make the button change colors when the a user clicks on it with a mouse (changes to green). This was accomplished in my css style sheet. I tried to add a method to my onKeyReleased method in my controller class, and could change the background that way, but could not determine a way to have the color change back in a timely manner without causing a lag on the UI. I want the UI to change colors similar to most calculators such as the standard windows calculator. This is where a user holds the key down and it changes color, and when releasing the key it changes back.
//main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Parent root =
FXMLLoader.load(getClass().getResource("calculator.fxml"));
primaryStage.getIcons().add(new Image("CALC.png"));
primaryStage.setTitle(" TS Calculator");
primaryStage.setScene(new Scene(root, 250, 375));
primaryStage.setResizable(true);
primaryStage.setMinHeight(375);
primaryStage.setMinWidth(250);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
/CSS
Button{
-fx-background-color: black;
-fx-text-align: center;
-fx-text-fill: white;
-fx-border-color: green;
-fx-font-size: 1em;
-fx-border-radius: 10 10 10 10;
-fx-background-radius: 10 10 10 10;
}
Button:pressed{
-fx-background-color: green;
}
TextField{
-fx-font-size: 1.5em;
}
//FXML (Only showing 1 button)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="306.00" minWidth="204.0"
prefHeight="288.0" prefWidth="208.0" style="-fx-background-color:
DARKSLATEGREY; -fx-border-color: green;"
stylesheets="#styles.css" xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.trevorsmith.Controller"
onKeyReleased="#acceptKeyboardInput">
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnSpan="4"
GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"
onKeyPressed="#acceptKeyboardInput">
<children>
<TextField fx:id="textFieldDisplay" editable="false"
alignment="CENTER_RIGHT" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefWidth="196.0"
AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0"
AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0"
GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS">
<children>
<Button maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" text="0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0" />
</children>
I am unable to make the background color change on click, and when I release my key it change back.
You'll want to register a couple of listeners on your Scene to listen to the pressed keys.
Once you have the key, you can use JavaFX's PseudoClass selectors to update the pressed style of each Button.
There could be a more streamlined way to do this, but this is my implementation. Here is a complete sample you can try out to see it in action.
Note that I did not implement the actual functionality of the calculator.
Final result/screenshot at the end.
Main.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainLayout.fxml"));
Scene scene = new Scene(loader.load());
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.setTitle("Calculator");
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainLayout.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" spacing="10.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="UI.BaseApps.Calculator.MainController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<children>
<TextField fx:id="txtDisplay" disable="true" alignment="CENTER_RIGHT" editable="false" minHeight="-Infinity"
prefHeight="50.0" text="0"/>
<GridPane hgap="10.0" vgap="10.0" VBox.vgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="NEVER" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<Button fx:id="btn7" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="7"/>
<Button fx:id="btn8" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="8" GridPane.columnIndex="1"/>
<Button fx:id="btn9" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="9" GridPane.columnIndex="2"/>
<Separator orientation="VERTICAL" prefHeight="200.0" GridPane.columnIndex="3" GridPane.rowSpan="4"/>
<Button fx:id="btnDivide" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="÷" GridPane.columnIndex="4"/>
<Button fx:id="btnClear" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="C" GridPane.columnIndex="5"/>
<Button fx:id="btn4" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="4" GridPane.rowIndex="1"/>
<Button fx:id="btn5" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="5" GridPane.columnIndex="1"
GridPane.rowIndex="1"/>
<Button fx:id="btn6" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="6" GridPane.columnIndex="2"
GridPane.rowIndex="1"/>
<Button fx:id="btnMultiply" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="x" GridPane.columnIndex="4"
GridPane.rowIndex="1"/>
<Button fx:id="btn1" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="1" GridPane.rowIndex="2"/>
<Button fx:id="btn2" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="2" GridPane.columnIndex="1"
GridPane.rowIndex="2"/>
<Button fx:id="btn3" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="3" GridPane.columnIndex="2"
GridPane.rowIndex="2"/>
<Button fx:id="btn0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" text="0" GridPane.columnSpan="2"
GridPane.rowIndex="3"/>
<Button fx:id="btnDecimal" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="." GridPane.columnIndex="2"
GridPane.rowIndex="3"/>
<Button fx:id="btnSubtract" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="-" GridPane.columnIndex="4"
GridPane.rowIndex="2"/>
<Button fx:id="btnAdd" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="+" GridPane.columnIndex="4"
GridPane.rowIndex="3"/>
<Button fx:id="btnEquals" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="="
GridPane.columnIndex="5" GridPane.rowIndex="2" GridPane.rowSpan="2"/>
<Button fx:id="btnBackspace" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
mnemonicParsing="false" prefHeight="50.0" prefWidth="50.0" text="←" GridPane.columnIndex="5"
GridPane.rowIndex="1"/>
</children>
</GridPane>
</children>
</VBox>
MainController.java:
import javafx.application.Platform;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
public class MainController {
// Here we'll define our PseudoClass needed to set the style for each pressed Button
private static final PseudoClass PRESSED = PseudoClass.getPseudoClass("pressed");
// Define FXML controls
#FXML
private TextField txtDisplay;
#FXML
private Button btn7, btn8, btn9;
#FXML
private Button btn4, btn5, btn6;
#FXML
private Button btn1, btn2, btn3;
#FXML
private Button btn0, btnDecimal;
#FXML
private Button btnMultiply, btnSubtract, btnAdd, btnDivide;
#FXML
private Button btnClear, btnEquals, btnBackspace;
#FXML
private void initialize() {
// We need access to the Scene to register our key listeners, so we need to wrap the code in a Platform.runLater(). If we try to do this without Platform.runLater(), we'll get a NullPointerException because txtDisplay hasn't been rendered yet.
Platform.runLater(() -> {
Scene scene = txtDisplay.getScene();
// Add a listener to capture any key that is pressed. We add this to the entire scene and we can then change the style of the corresponding button accordingly.
scene.setOnKeyPressed(event -> {
// We need to know which Button we're working with
Button button = getButton(event.getCode());
// Add our "pressed" style to the Button
if (button != null) button.pseudoClassStateChanged(PRESSED, true);
});
// Once the user releases the key, remove our custom style and trigger whatever onAction() code has been applied to the corresponding Button.
scene.setOnKeyReleased(event -> {
Button button = getButton(event.getCode());
if (button != null) {
button.pseudoClassStateChanged(PRESSED, false);
// Fire the button's onAction()
button.fire();
}
});
});
}
// Helper method to get the Button that corresponds to the pressed key. The Scene.setOnKeyPressed() listener provides the KeyCode for the pressed key. We can use that to determine which of our Buttons to trigger.
private Button getButton(KeyCode keyCode) {
switch (keyCode) {
case NUMPAD0: return btn0;
case NUMPAD1: return btn1;
case NUMPAD2: return btn2;
case NUMPAD3: return btn3;
case NUMPAD4: return btn4;
case NUMPAD5: return btn5;
case NUMPAD6: return btn6;
case NUMPAD7: return btn7;
case NUMPAD8: return btn8;
case NUMPAD9: return btn9;
case DECIMAL: return btnDecimal;
case DIVIDE: return btnDivide;
case ADD: return btnAdd;
case MULTIPLY: return btnMultiply;
case SUBTRACT: return btnSubtract;
case ENTER: return btnEquals;
case BACK_SPACE: return btnBackspace;
case ESCAPE: return btnClear;
}
return null;
}
}
style.css:
.text-field {
-fx-opacity: 1.0;
-fx-font-family: Consolas;
-fx-font-size: 200%;
}
.button {
-fx-font-family: Consolas;
-fx-font-size: 150%;
-fx-background-radius: 25px;
-fx-border-radius: 25px;
/* Remove focus highlighting */
-fx-focus-traversable: false;
}
.button:pressed {
-fx-background-color: lightgreen;
-fx-border-color: green;
}
And here is the result:
I am new to JavaFx and I am trying to create a tableview and fxml is created using scene builder. If I run the program, the table is not getting the values. I found that this question is somehow matching with my requirement (javaFX 2.2 - Not able to populate table from Controller), but my code is matching with that too. But still I am not able to get the values in the table.
I have referenced the following video : http://www.youtube.com/watch?v=HiZ-glk9_LE
My code is as follows,
MainView.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package controller;
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 {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
try {
AnchorPane page = FXMLLoader.load(MainView.class.getResource("MainView.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Sample Window");
primaryStage.setResizable(false);
primaryStage.show();
} catch (Exception e) {
}
}
}
MainView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="controller.MainViewController">
<children>
<SplitPane dividerPositions="0.535175879396985" focusTraversable="true" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TableView fx:id="tableID" prefHeight="210.0" prefWidth="598.0" tableMenuButtonVisible="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn minWidth="20.0" prefWidth="40.0" text="ID" fx:id="tID" />
<TableColumn prefWidth="100.0" text="Date" fx:id="tDate" />
<TableColumn prefWidth="200.0" text="Name" fx:id="tName" />
<TableColumn prefWidth="75.0" text="Price" fx:id="tPrice" />
</columns>
</TableView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" />
</items>
</SplitPane>
</children>
</AnchorPane>
MainViewController.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import model.Table;
/**
* FXML Controller class
*
*/
public class MainViewController implements Initializable {
/**
* Initializes the controller class.
*/
#FXML
TableView<Table> tableID;
#FXML
TableColumn<Table, Integer> tID;
#FXML
TableColumn<Table, String> tName;
#FXML
TableColumn<Table, String> tDate;
#FXML
TableColumn<Table, String> tPrice;
int iNumber = 1;
ObservableList<Table> data =
FXCollections.observableArrayList(
new Table(iNumber++, "Dinesh", "12/02/2013", "20"),
new Table(iNumber++, "Vignesh", "2/02/2013", "40"),
new Table(iNumber++, "Satheesh", "1/02/2013", "100"),
new Table(iNumber++, "Dinesh", "12/02/2013", "16"));
#Override
public void initialize(URL url, ResourceBundle rb) {
// System.out.println("called");
tID.setCellValueFactory(new PropertyValueFactory<Table, Integer>("rID"));
tName.setCellValueFactory(new PropertyValueFactory<Table, String>("rName"));
tDate.setCellValueFactory(new PropertyValueFactory<Table, String>("rDate"));
tPrice.setCellValueFactory(new PropertyValueFactory<Table, String>("rPrice"));
tableID.setItems(data);
}
}
Table.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package model;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Table {
SimpleIntegerProperty rID;
SimpleStringProperty rName;
SimpleStringProperty rDate;
SimpleStringProperty rPrice;
public Table(int rID, String rName, String rDate, String rPrice) {
this.rID = new SimpleIntegerProperty(rID);
this.rName = new SimpleStringProperty(rName);
this.rDate = new SimpleStringProperty(rDate);
this.rPrice = new SimpleStringProperty(rPrice);
System.out.println(rID);
System.out.println(rName);
System.out.println(rDate);
System.out.println(rPrice);
}
public Integer getrID() {
return rID.get();
}
public void setrID(Integer v) {
this.rID.set(v);
}
public String getrDate() {
return rDate.get();
}
public void setrDate(String d) {
this.rDate.set(d);
}
public String getrName() {
return rName.get();
}
public void setrName(String n) {
this.rDate.set(n);
}
public String getrPrice() {
return rPrice.get();
}
public void setrPrice(String p) {
this.rPrice.set(p);
}
}
Thanks in advance.
In a Table.java change all getters and setters names,
change getr* to getR*
change setr* to setR*
Thanks to #Uluk Biy. Whatever he mentioned, that needs to be changed and I found that I missed the <cellValueFactory> and <PropertyValueFactory> tags under the <TableColumn> tag for each columns in the FXML file which is as follows,
<TableColumn minWidth="20.0" prefWidth="40.0" text="ID" fx:id="tID" >
<cellValueFactory>
<PropertyValueFactory property="tID" />
</cellValueFactory>
</TableColumn>
Similar to this, all columns need to be updated like this.
After this change, the code is working fine. I am able to add the values into the row. :)
I'm completely new to JavaFX and Scene Builder.
My program is designed as below picture, with 4 Buttons on the right and a TabPane on the left. The problem is I don't know how to design the TabPane for each button on the right. For example, if user click on Button 1, it shows 2 tabs Option 1 - A and Option 1 - B. If clicking on Button 2, it shows Option 2 - A and Option 2 - B and so on.
How can I achieve this? It it possible to add 4 TabPane designs in 1 scene (switch between them by show hide elements like working with html and javascript) or I need to make 4 copies of the first scene and change the TabPane for each of them?
Sample app: This app has a mainview that consist of an anchorpane and two buttons. This app also has two other views. When the top button is pressed in the mainview, it loads viewOne into mainview's anchorpane. When the bottom button is pressed in the mainview, it loads viewTwo into mainview's anchorpane.
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication63 extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
BaseView Controller
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
/**
*
* #author blj0011
*/
public class FXMLDocumentController implements Initializable
{
#FXML AnchorPane apMain;
#FXML
private void handleButtonAction(ActionEvent event)
{
try
{
Pane newLoadedPane;
Button tempButton = (Button)event.getSource();
switch(tempButton.getId())
{
case "btnOne":
newLoadedPane = FXMLLoader.load(getClass().getResource("viewOne.fxml"));
apMain.getChildren().add(newLoadedPane);
break;
case "btnTwo":
newLoadedPane = FXMLLoader.load(getClass().getResource("viewTwo.fxml"));
apMain.getChildren().add(newLoadedPane);
break;
}
}
catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
}
}
Baseview FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication63.FXMLDocumentController">
<children>
<Button fx:id="btnOne" layoutX="241.0" layoutY="24.0" onAction="#handleButtonAction" text="Click Me!" />
<Button fx:id="btnTwo" layoutX="241.0" layoutY="56.0" onAction="#handleButtonAction" text="Click Me!" />
<AnchorPane fx:id="apMain" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="120.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
ViewOne Controller
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
/**
* FXML Controller class
*
* #author blj0011
*/
public class ViewOneController implements Initializable
{
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
}
}
ViewOne FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="apOption2" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication63.ViewOneController">
<children>
<TabPane layoutX="125.0" layoutY="83.0" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="1 - A">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="1 - B">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
ViewTwo Controller
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
/**
* FXML Controller class
*
* #author blj0011
*/
public class ViewTwoController implements Initializable
{
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
}
}
ViewTwo FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="apOption2" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication63.ViewTwoController">
<children>
<TabPane layoutX="24.0" layoutY="-14.0" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab text="2 - A">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="2 - B">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
In this app, no initial view is loaded into the main anchorpane when the app starts. You might want to load a view as soon as the app starts.