JavaFX blur underneath area from pane - javafx

Is there any way to add a blur effect only to a part of an image defined by the area of a Pane? If you blur the pane over the image only the pane get blurred, but is there a way to blur the picture part underneath?
Here's an example of what I mean: It's simply just an image overlayed with a pane which has backgrouud and opacity set. Now I want to blur the part the pane lays on.
Main.java:
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
GridPane root = (GridPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root,500,500);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Sample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<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>
<children>
<ImageView fitHeight="495.0" fitWidth="535.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
<image>
<Image url="#../../../../Downloads/ZGEX2eX.jpg" />
</image>
</ImageView>
<Pane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #012E56; -fx-opacity: 0.666;" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER" />
</children>
</GridPane>

You can use the Clip of an ImageView to apply an effect only to a specific area of your image:
public class BlurredImageTest extends Application {
private DoubleProperty effectHeight = new SimpleDoubleProperty(80);
#Override
public void start(Stage primaryStage) {
Image image = new Image("yourImage.jpg");
ImageView img = new ImageView(image);
Rectangle clip = new Rectangle();
clip.widthProperty().bind(image.widthProperty());
clip.heightProperty().bind(image.heightProperty().subtract(effectHeight));
img.setClip(clip);
ImageView imgEffect = new ImageView(image);
Rectangle clipEffect = new Rectangle();
clipEffect.widthProperty().bind(image.widthProperty());
clipEffect.heightProperty().bind(effectHeight);
clipEffect.translateYProperty().bind(image.heightProperty().subtract(effectHeight));
imgEffect.setClip(clipEffect);
imgEffect.setEffect(new GaussianBlur());
StackPane root = new StackPane(img, imgEffect);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public final void setEffectHeight(double value) {
effectHeight.set(value);
}
public static void main(String[] args) {
launch(args);
}
}

Related

Is there a concept of growth priority in javafx?

How does JavaFX renderer decides which component grows when pref sizes sum of 2 components is lower than the overall scene size ?
Is there any way to decide which component should grow first and how more than the other component as flexbox does in regular css ?
here is a css code that describes what i want to do in my javafx app :
.my-container {
display: flex;
width: 1400px;
}
.my-component-1 {
/*pref width is 800*/
flex: 2;
}
.my-component-2 {
/*pref width is 300*/
flex: 1;
}
for example, in the above case, component 1 will grow up to 1000px and component 2 up to 400px.
what is the javafx equivalent to the flex property ?
Here is a small example how a GridPane layout with "Percent Width" works:
Preview:
Controller Class:
package sample;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class WidthController implements Initializable {
#FXML
private Pane
redPane,
bluePane;
#FXML
private Label
stageWidthLabel,
redPaneWidthLabel,
bluePaneWidthLabel;
private DoubleProperty
stageWidth = new SimpleDoubleProperty(),
redPaneWidth = new SimpleDoubleProperty(),
bluePaneWidth = new SimpleDoubleProperty();
#Override
public void initialize(URL location, ResourceBundle resources) {
stageWidthLabel.textProperty().bind(stageWidth.asString());
redPaneWidthLabel.textProperty().bind(redPaneWidth.asString());
bluePaneWidthLabel.textProperty().bind(bluePaneWidth.asString());
redPaneWidth.bind(redPane.widthProperty());
bluePaneWidth.bind(bluePane.widthProperty());
}
public void setStage(Stage stage) {
stageWidth.bind(stage.widthProperty());
}
}
FXML File:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane prefHeight="400.0" prefWidth="1100.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.WidthController">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="72.73" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="27.27" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints vgrow="NEVER" />
</rowConstraints>
<children>
<Pane fx:id="bluePane" style="-fx-background-color: blue;" />
<Pane fx:id="redPane" style="-fx-background-color: red;" GridPane.columnIndex="1" />
<GridPane hgap="3.0" vgap="3.0" GridPane.columnSpan="2" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints fillWidth="false" halignment="RIGHT" hgrow="NEVER" />
<ColumnConstraints fillWidth="false" halignment="LEFT" hgrow="NEVER" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints fillHeight="false" valignment="CENTER" vgrow="NEVER" />
<RowConstraints fillHeight="false" valignment="CENTER" vgrow="NEVER" />
<RowConstraints fillHeight="false" valignment="CENTER" vgrow="NEVER" />
<RowConstraints fillHeight="false" valignment="CENTER" vgrow="NEVER" />
</rowConstraints>
<children>
<Label text="Width information" underline="true" />
<Label text="Stage:" GridPane.rowIndex="1" />
<Label text="Blue Pane:" GridPane.rowIndex="2" />
<Label text="Red Pane:" GridPane.rowIndex="3" />
<Label fx:id="stageWidthLabel" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label fx:id="bluePaneWidthLabel" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label fx:id="redPaneWidthLabel" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</children>
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
</GridPane>
</children>
</GridPane>
Application Class:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("width.fxml"));
Parent root = null;
try {
root = loader.load();
} catch (IOException ex) {
ex.printStackTrace();
}
if (root == null) return;
WidthController controller = loader.getController();
primaryStage.setScene(new Scene(root));
primaryStage.show();
controller.setStage(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}

How do I get a grid to be static in a VBOX using Scene Builder?

I've just recently dipped into UI based applications and I'm having trouble getting the generated GridPane to not expand with the window. Ideally, I'd like to be able to hit the small button, have it generate a static grid, and then resize the root stage/scene to compensate for different dungeon sizes. The code below only implements the small button and then draws the grid under it.
This is a screenshot after I hit the small button.(and after I manually resized the window)
Controller Class
package Window;
import Data.Area;
import Model.Grid;
import Model.TileSet;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class Controller {
public GridPane gridmane;
public void genSmall(ActionEvent actionEvent) throws IOException {
Grid grid = new Grid(new Area(40, 40));
grid.getPathfinder().shufflePartitions();
grid.getPathfinder().fillPartitions();
grid.getPathfinder().generateHallways();
importGrid(gridmane, grid);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setOpacity(1);
stage.setTitle("My New Stage Title");
stage.setScene(new Scene(gridmane, 340, 400));
stage.show();
}
private void importGrid(GridPane gridPane, Grid grid) {
for (int i = 0; i < grid.getSize().height; i++) {
for (int j = 0; j < grid.getSize().width; j++) {
if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
changeSquare(gridPane, i, j, Color.WHITE);
} else {
changeSquare(gridPane, i, j, Color.GRAY);
}
}
}
}
private void changeSquare(GridPane gridPane, int xCoordinate, int yCoordinate, Color color) {
Rectangle rect = new Rectangle();
rect.setStroke(Color.BLACK);
rect.setFill(color);
rect.setWidth(10);
rect.setHeight(10);
gridPane.add(rect, xCoordinate, yCoordinate);
}
}
Main Class
package Window;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
Stage stage = new Stage();
int val = 40;
#Override
public void start(Stage primaryStage) throws Exception {
this.stage = primaryStage;
setVal(val);
}
public static void main(String[] args) {
launch(args);
}
public void setVal(int i) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/view.fxml"));
stage.setTitle("Dungeon Generator");
stage.setScene(new Scene(root, 450, 450));
//primaryStage.setResizable(false);
stage.sizeToScene();
stage.show();
}
}
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="332.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Window.Controller">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Button alignment="CENTER" mnemonicParsing="false" onAction="#genSmall" prefHeight="27.0" prefWidth="64.0" text="Small" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
<Button alignment="CENTER" mnemonicParsing="false" text="Medium" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
<Button alignment="CENTER" mnemonicParsing="false" prefHeight="27.0" prefWidth="66.0" text="Large" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<GridPane fx:id="gridmane" VBox.vgrow="NEVER">
<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>
</GridPane>
</children>
</VBox>
You need to get rid of those constraints of your GridPane rows/columns. For centering you could wrap the grid in a StackPane and prevent it's size from growing by using Region.USE_PREF_SIZE (=-Infinity) as max size constraints.
<StackPane VBox.vgrow="ALWAYS" >
<children>
<GridPane fx:id="gridmane" VBox.vgrow="NEVER" maxWidth="-Infinity" maxHeight="-Infinity" />
</children>
</StackPane>
public void genSmall(ActionEvent actionEvent) throws IOException {
Grid grid = new Grid(new Area(40, 40));
grid.getPathfinder().shufflePartitions();
grid.getPathfinder().fillPartitions();
grid.getPathfinder().generateHallways();
importGrid(gridmane, grid);
gridmane.getScene().getWindow().sizeToScene(); // resize window
}
private void importGrid(GridPane gridPane, Grid grid) {
gridPane.getChildren().clear(); // remove old children
for (int i = 0; i < grid.getSize().height; i++) {
for (int j = 0; j < grid.getSize().width; j++) {
if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
changeSquare(gridPane, i, j, Color.WHITE);
} else {
changeSquare(gridPane, i, j, Color.GRAY);
}
}
}
}

JavaFX how I Can Get value form TableView to textfield

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

FXML Set ButtonType onAction

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.

Getting size of FXML generated nodes

I want to get the size of a node, after it has been sized properly, which I understand is done after the stage is shown. however, i cannot do it in start() method, because the node is not initialized yet, because its loaded it from an FXML file.
If I implement Initializable Interface and try to get the size in initialize() method, it returns 0.0
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="musicPlayer.Test">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TableView fx:id="testNode">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
</TableView>
</children>
</GridPane>
just an arbitrary node in a grid pane generated with scene builder
public class Test extends Application implements Initializable {
#FXML
private TableView testNode;
public void initialize(URL location, ResourceBundle resources) {
//System.out.println(testNode.getWidth()); is always 0.0
}
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("test.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
//System.out.println(testNode.getWidth()); throws Nullpointer Exception
}
public static void main(String[] args) {
launch(args);
}
}
I've also tried adding a listener to the stage, but i still get a nullpointer exception.
Is there a way of getting the size, without using a sleeping thread?

Resources