i have application layout:
https://i.stack.imgur.com/YsK5R.png
as a result of writing code I get this
https://i.stack.imgur.com/j2Nym.png
Question: How to remove the top line with closing tabs and leave only as on the layout?
project structure:
-[src]
.....|-[sample]
..............|- Main
..............|- sample.fxml
..............|- SampleController
..............|- Tab1.fxml
..............|- Tab1Controller
..............|- Tab2.fxml
..............|- Tab2Controller
CODE
class Main
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
private Stage primary;
private BorderPane rootLayout;
#Override
public void start(Stage primary) throws Exception{
this.primary = primary;
initRootLayout();
showTab();
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("sample.fxml"));
rootLayout = loader.load();
Scene scene = new Scene(rootLayout);
primary.setScene(scene);
primary.show();
}catch (IOException e){
e.printStackTrace();}
}
private void showTab() {
try {
FXMLLoader loaderTab1 = new FXMLLoader();
loaderTab1.setLocation(Main.class.getResource("Tab1.fxml"));
FXMLLoader loaderTab2 = new FXMLLoader();
loaderTab2.setLocation(Main.class.getResource("Tab2.fxml"));
TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
Tab tab2 = new Tab();
tab1.setContent(loaderTab1.load());
tab2.setContent(loaderTab2.load());
tabPane.getTabs().addAll(tab1,tab2);
rootLayout.setCenter(tabPane);
} catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.SampleController">
<top>
<MenuBar BorderPane.alignment="CENTER">
<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>
</top>
</BorderPane>
Tab1.fxml = Tab2.fxml = ... = Tab{n}.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Tab1Controller">
<tabs>
<Tab text="Tab1">
<content>
<SplitPane dividerPositions="0.29797979797979796" prefHeight="160.0" prefWidth="200.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TableView fixedCellSize="1.0" layoutX="-12.0" layoutY="27.0" prefHeight="371.0" prefWidth="176.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children></AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<Label layoutY="14.0" text="Label" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="14.0" />
<GridPane layoutX="98.0" layoutY="125.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="35.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>
<children>
<Label text="Label" />
<Label text="Label" GridPane.rowIndex="1" />
<Label text="Label" GridPane.rowIndex="2" />
<Label text="Label" GridPane.columnIndex="1" />
<Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
</GridPane>
</children></AnchorPane>
</items>
</SplitPane>
</content></Tab>
</tabs>
</TabPane>
this question is double from this: https://ru.stackoverflow.com/questions/941060/%D0%A3%D0%B1%D1%80%D0%B0%D1%82%D1%8C-%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D1%87%D0%BD%D1%8B%D0%B5-%D0%B2%D0%BA%D0%BB%D0%B0%D0%B4%D0%BA%D0%B8
There are many way to do this depending on the genericity you want to add to your application/layout.
But the most important thing is that you seem to make a mistake by mixing up the TabPane and the Tabs. While the first one is the container, the second(s) one(s) correspond to each tab you could have. Usually you have one TabPane which contain many Tab(s) (even if it is not necessary).
One solution could be to modify your method showTab by doing this (read comment)
private void showTab() {
try {
// Tab 1 loader
FXMLLoader loaderTab1 = new FXMLLoader(Main.class.getResource("Tab1.fxml"));
// Tab 2 loader
FXMLLoader loaderTab2 = new FXMLLoader(Main.class.getResource("Tab2.fxml"));
TabPane tabPane = new TabPane();
// Remove the 4 following lines, Tabs are already declared in FXML
//Tab tab1 = new Tab();
//Tab tab2 = new Tab();
//tab1.setContent(loaderTab1.load());
//tab2.setContent(loaderTab2.load());
Tab tab1 = loaderTab1.load();
Tab tab2 = loaderTab2.load();
tabPane.getTabs().addAll(tab1,tab2);
rootLayout.setCenter(tabPane);
} catch (IOException e){
e.printStackTrace();
}
}
And change your FXML files like the following one (TabPane and tabs tags are removed) :
<Tab xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Tab1Controller" text="Tab1">
<content>
<SplitPane dividerPositions="0.29797979797979796" prefHeight="160.0" prefWidth="200.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TableView fixedCellSize="1.0" layoutX="-12.0" layoutY="27.0" prefHeight="371.0" prefWidth="176.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children></AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<Label layoutY="14.0" text="Label" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="14.0" />
<GridPane layoutX="98.0" layoutY="125.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="35.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>
<children>
<Label text="Label" />
<Label text="Label" GridPane.rowIndex="1" />
<Label text="Label" GridPane.rowIndex="2" />
<Label text="Label" GridPane.columnIndex="1" />
<Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
</GridPane>
</children></AnchorPane>
</items>
</SplitPane>
</content>
</Tab>
Related
I have a vbox which contains a list of cards(Anchor panes). I am trying to make each card draggable so that I can change the order of the list whenever I want. I am using a scene builder.
However, I keep getting the following message after I drag and attempt to drop.
Java Messsge:class javafx.scene.layout.VBox cannot be cast to class javafx.scene.layout.AnchorPane(javafx.scene.layout.VBox and javafx.scene.layout.AnchorPane are in module javafx.graphics of loader 'app')
My code:
minimal code provided only contains two cards, one of which is being used only in my code.
Edit: I no longer get the error message however, I am not getting my desired result as the cards are not changing positions
mport javafx.beans.property.ObjectProperty;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TitledPane;
import javafx.scene.image.WritableImage;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Controller
{
#FXML public AnchorPane card1, card2;
#FXML public AnchorPane current;
#FXML public GridPane gridPane;
#FXML public GridPane column1;
#FXML public AnchorPane col1;
#FXML public Button button1, button2;
#FXML public Button currentButton;
#FXML public VBox v1;
#FXML
public void detect() { //detect card
card1.setOnDragDetected((MouseEvent event) -> { //card1 is the card
Dragboard db = card1.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(card1.getId());
WritableImage snapshot = card1.snapshot(new SnapshotParameters(), null);
db.setDragView(snapshot);
db.setContent(content);
event.consume();
});
}
#FXML
public void accept() { //add to vbox
v1.addEventHandler(DragEvent.DRAG_OVER, (DragEvent event) -> { //v1 is the vbox
if (event.getGestureSource() != v1
&& event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
});
}
#FXML
public void drop() {
v1.addEventHandler(DragEvent.DRAG_DROPPED, (DragEvent event) -> {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
VBox parent = (VBox) card1.getParent();
//int targetIndex = parent.getChildren().indexOf(card1);
List<Node> nodes = new ArrayList<Node>(parent.getChildren());
parent.getChildren().clear();
parent.getChildren().addAll(nodes);
success = true;
}
event.setDropCompleted(success);
event.consume();
});
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="772.0" prefWidth="1295.0" style="-fx-background-color: #C5F5D4;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="KanbanBoard.Controller">
<children>
<AnchorPane layoutY="47.0" prefHeight="687.0" prefWidth="1295.0">
<children>
<AnchorPane fx:id="col1" layoutX="-1.0" prefHeight="724.0" prefWidth="216.0">
<children>
<GridPane fx:id="column1" layoutX="33.0" layoutY="15.0" onMouseDragOver="#accept" prefHeight="724.0" prefWidth="209.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="353.8666748046875" minHeight="10.0" prefHeight="103.20001831054685" vgrow="SOMETIMES" />
<RowConstraints maxHeight="621.5999816894531" minHeight="10.0" prefHeight="621.5999816894531" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<VBox fx:id="v1" onDragDropped="#drop" onDragOver="#accept" prefHeight="200.0" prefWidth="210.0" GridPane.rowIndex="1">
<children>
<AnchorPane fx:id="card1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onDragDetected="#detect" onMouseDragged="#handleLabel" prefHeight="125.0" prefWidth="198.0" style="-fx-background-color: #E5EAE6;">
<children>
<TextField layoutX="5.0" layoutY="3.0" prefHeight="26.0" prefWidth="65.0" promptText="ID" />
<TextField layoutX="72.0" layoutY="3.0" prefHeight="26.0" prefWidth="124.0" promptText="Title" />
<TextArea layoutX="5.0" layoutY="32.0" prefHeight="50.0" prefWidth="190.0" promptText="Description" />
<TextField layoutX="5.0" layoutY="85.0" prefHeight="26.0" prefWidth="124.0" promptText="Story point" />
<Button fx:id="button1" layoutX="164.0" layoutY="85.0" mnemonicParsing="false" onMouseClicked="#removeCard" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="-" />
<Button layoutX="129.0" layoutY="85.0" mnemonicParsing="false" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="+" />
</children>
</AnchorPane>
<AnchorPane fx:id="card2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onDragDetected="#detect" onMouseClicked="#handleLabel" prefHeight="125.0" prefWidth="198.0" style="-fx-background-color: #E5EAE6;">
<children>
<TextField layoutX="5.0" layoutY="3.0" prefHeight="26.0" prefWidth="65.0" promptText="ID" />
<TextField layoutX="72.0" layoutY="3.0" prefHeight="26.0" prefWidth="124.0" promptText="Title" />
<TextArea layoutX="5.0" layoutY="32.0" prefHeight="50.0" prefWidth="190.0" promptText="Description" />
<TextField layoutX="5.0" layoutY="85.0" prefHeight="26.0" prefWidth="124.0" promptText="Story point" />
<Button fx:id="button2" layoutX="164.0" layoutY="85.0" mnemonicParsing="false" onMouseClicked="#removeCard" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="-" />
<Button layoutX="129.0" layoutY="85.0" mnemonicParsing="false" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="+" />
</children>
</AnchorPane>
</children>
</VBox>
<Pane prefHeight="98.0" prefWidth="226.0" style="-fx-background-color: #D1D3D1;">
<children>
<Button layoutX="124.0" layoutY="64.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="26.0" text="-" />
<TextArea layoutY="39.0" prefHeight="50.0" prefWidth="124.0" promptText="Role" />
<TextField layoutX="1.0" layoutY="5.0" prefHeight="26.0" prefWidth="124.0" promptText="Name" />
<Button fx:id="addColumnButton" layoutX="124.0" layoutY="36.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="26.0" text="+" />
</children>
</Pane>
</children>
</GridPane>
</children>
</AnchorPane>
<AnchorPane layoutX="1082.0" prefHeight="726.0" prefWidth="213.0">
<children>
<Pane prefHeight="50.0" prefWidth="214.0" style="-fx-background-color: #8F9691;">
<children>
<Label layoutX="49.0" layoutY="7.0" prefHeight="36.0" prefWidth="46.0" text="Log" textAlignment="CENTER" textOverrun="WORD_ELLIPSIS">
<font>
<Font size="22.0" />
</font>
</Label>
</children>
</Pane>
<Pane layoutY="49.0" prefHeight="676.0" prefWidth="214.0" style="-fx-background-color: #C6C8C6;" />
</children>
</AnchorPane>
<GridPane fx:id="gridPane" layoutX="228.0" onDragDropped="#drop" onDragOver="#accept" prefHeight="726.0" prefWidth="856.0">
<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 hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="627.1999938964843" minHeight="10.0" prefHeight="622.4000061035156" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
</AnchorPane>
<Label layoutX="381.0" layoutY="-4.0" prefHeight="50.0" prefWidth="180.0" text="Kanban Board">
<font>
<Font size="28.0" />
</font>
</Label>
</children>
</AnchorPane>
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.*;
import javafx.stage.Stage;
import java.io.IOException;
public class Kanban extends Application {
//private Button b;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Parent root = null;
try {
root = FXMLLoader.load(getClass().getResource("Kanban.fxml"));
} catch (IOException e) {
throw new RuntimeException(e);
}
Controller controller = new Controller();
FXMLLoader loader = new FXMLLoader();
loader.setController(controller);
//Controller c = loader.getController();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Can someone help me out please.
AnchorPane parent = (AnchorPane) card1.getParent(); (In the drop() method, at the bottom of your code)
card1.getParent() with a type of VBox cannot be cast to AnchorPane
I want to add a listener to a textField in a window that appears when I press a button on a previous window. The problem is that the listener doesn't work at all. It doesn't detect any change.
public class WindowTwoController {
private Stage stage;
#FXML
private TextField imieTF = new TextField();
public void show() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("winTwo.fxml"));
Parent root = loader.load();
stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Sell Art");
stage.setScene(new Scene(root, 500, 500));
imieTF.textProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("textfield changed from " + oldValue + " to " + newValue);
});
stage.showAndWait();
}
I'm changing the value of the textField, but nothing is printed out to the console. The show method is called when a button is pressed on the previous window. Please help me. This is my winTwo.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<GridPane alignment="center" hgap="10" prefHeight="441.0" prefWidth="500.0" vgap="10" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="windowTwo.WindowTwoController">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<VBox prefHeight="354.0" prefWidth="455.0">
<children>
<Label alignment="CENTER" prefHeight="45.0" prefWidth="457.0" text="Sprzedaż dzieła">
<font>
<Font size="30.0" />
</font>
</Label>
<Separator prefWidth="200.0" />
<GridPane prefHeight="139.0" prefWidth="455.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>
<children>
<Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Imię">
<font>
<Font size="28.0" />
</font>
</Label>
<Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Nazwisko" GridPane.rowIndex="1">
<font>
<Font size="28.0" />
</font>
</Label>
<TextField fx:id="imieTF" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="20.0" />
</GridPane.margin></TextField>
<TextField fx:id="nazwiskoTF" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets right="20.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
<Separator prefWidth="200.0" />
<Label alignment="CENTER" prefHeight="17.0" prefWidth="450.0" text="Klient powracający">
<font>
<Font size="22.0" />
</font>
</Label>
<Separator prefWidth="200.0" />
<GridPane prefHeight="126.0" prefWidth="455.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>
<children>
<Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Poziom Zaprzyjaźnienia" textFill="#00000080">
<font>
<Font size="19.0" />
</font>
</Label>
<ComboBox fx:id="cb" opacity="0.5" prefHeight="25.0" prefWidth="207.0" GridPane.columnIndex="1" />
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="175.0" text="Akceptuj" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="25.0" />
</GridPane.margin>
</Button>
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="175.0" text="Anuluj" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="27.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
</children>
</VBox>
</children>
</GridPane>
You should add an anotation to the private member imieTF like so
public class WindowTwoController {
#FXML
private TextField imieTF;
#FXML
private void initialize() {
imieTF.textProperty().addListener((observable, oldValue, newValue) ->
{
System.out.println("textfield changed from " + oldValue + " to " + newValue);
});
}
public static void show() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("winTwo.fxml"));
Parent root = loader.load();
stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Sell Art");
stage.setScene(new Scene(root, 500, 500));
stage.showAndWait();
}
}
This should bind the TextField instance to the controller. But from what I can find out the FXML will create a new instance of WindowTwoController when the window belonging to the fxml file gets created.
Also see https://www.callicoder.com/javafx-fxml-form-gui-tutorial/ for a basic example on how this works.
Note that all manipulations of the textfield should be part of the JavaFX flow and cannot be done in a manual instance of WindowTwoController. Keep in mind that JavaFX will create it's own instance of WindowTwoController during the loader.load(); operation.
I'm trying to create a TabView in JavaFX. I would like to have some of the tabs distanced from the other tabs, since their functions belong to another category.
This is what it looks like now:
And as you can see I want the two last tabs to be moved to the right side without affecting the rest.
Here's 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.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Application.MainController">
<center>
<VBox alignment="BOTTOM_CENTER" prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
<children>a
<TabPane accessibleRole="BUTTON" nodeOrientation="LEFT_TO_RIGHT" prefHeight="651.0" prefWidth="1000.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Courses">
<content>
<TableView prefHeight="665.0" prefWidth="1000.0">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
</TableView>
</content>
</Tab>
<Tab text="Education Matrix">
<content>
<TableView prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn prefWidth="75.0" text="C1" />
<TableColumn prefWidth="75.0" text="C2" />
</columns>
</TableView>
</content>
</Tab>
<Tab text="Employee">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Calendar">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab fx:id="companiesTab" text="Companies">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab fx:id="providerTab" text="Provider">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
<VBox.margin>
<Insets />
</VBox.margin>
</TabPane>
</children>
</VBox>
</center>
<bottom>
<GridPane prefHeight="105.0" prefWidth="1000.0" BorderPane.alignment="CENTER">
<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>
<children>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" style="-fx-background-color: grey;">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
<padding>
<Insets left="20.0" />
</padding>
</HBox>
<HBox alignment="CENTER_RIGHT" prefHeight="100.0" prefWidth="200.0" style="-fx-background-color: grey;" GridPane.columnIndex="2">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets right="20.0" />
</padding>
</HBox>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" style="-fx-background-color: grey;" GridPane.columnIndex="1">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
</HBox>
</children>
</GridPane>
</bottom>
<top>
<GridPane prefHeight="106.0" prefWidth="1000.0" BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="494.0" minWidth="10.0" prefWidth="289.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="711.0" minWidth="10.0" prefWidth="711.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
<children>
<ChoiceBox prefWidth="150.0" />
</children>
<padding>
<Insets left="20.0" />
</padding>
</HBox>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<Label text="Smart Academy Manager">
<font>
<Font name="Arial" size="31.0" />
</font>
</Label>
</children>
</HBox>
</children>
</GridPane>
</top>
</BorderPane>`enter code here`
Original TabPane does not provide tools for custom tab layout. But a similar result can be obtained using some trick.
You can set invisible Tab into required place and bind it's width with width of the TabPane.
First we need to calc splitter's width. This is the width of the TabPane minus the sum of the widths of the Tabs, excluding the splitter. Tab object can be obtained as Node from TabPane using the command .lookup(). We also need to consider the width associated with the styles (padding, spacing). For this example I will set this number by hard (for default theme). After calcs we set size of the splitter using .setStyle():
private void autoSizeSplitter(TabPane tabPane, Tab splitter) {
double width = tabPane.getWidth();
Set<Node> tabs = tabPane.lookupAll(".tab");
for (Node node : tabs) {
if (node.getId() == null || !node.getId().equals(splitter.getId())) {
width = width - node.getBoundsInParent().getWidth();
}
}
double PADDING = 20;
width = width - PADDING;
splitter.setStyle("-fx-background-color:transparent; -fx-pref-width: " + width + ";");
}
Finally we set the listener on the TabPane width property and autosize splitter for first time in initialization:
tabPane.widthProperty().addListener(observable -> autoSizeSplitter(tabPane, splitter));
Platform.runLater(() -> autoSizeSplitter(tabPane, splitter));
Full example:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import java.util.Set;
public class Sample extends Application {
#Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
Tab splitter = new Tab();
splitter.setDisable(true);
splitter.setId("splitter");
tabPane.getTabs().add(new Tab("111"));
tabPane.getTabs().add(new Tab("222"));
tabPane.getTabs().add(splitter);
tabPane.getTabs().add(new Tab("333"));
tabPane.getTabs().add(new Tab("444"));
tabPane.getTabs().add(new Tab("555"));
Scene scene = new Scene(tabPane, 640, 480);
primaryStage.setScene(scene);
primaryStage.show();
tabPane.widthProperty().addListener(observable -> autoSizeSplitter(tabPane, splitter));
Platform.runLater(() -> autoSizeSplitter(tabPane, splitter));
}
private void autoSizeSplitter(TabPane tabPane, Tab splitter) {
double width = tabPane.getWidth();
Set<Node> tabs = tabPane.lookupAll(".tab");
for (Node node : tabs) {
if (node.getId() == null || !node.getId().equals(splitter.getId())) {
width = width - node.getBoundsInParent().getWidth();
}
}
double PADDING = 20;
width = width - PADDING;
splitter.setStyle("-fx-background-color:transparent; -fx-pref-width: " + width + ";");
}
public static void main(String[] args) {
launch(args);
}
}
For a university project I have to create a GUI for an online version of a table game, the player can have some cards which I created by extending JavaFX ImageView and I want to put them inside the interface at runtime.
Therefore I inserted a JavaFX ListView inside a SplitPane but when I run my application the scroll bar doesn't work.
The cards are perfectly displayed and the scroll bar is visible, but when I try to use it, it just seems like a disabled button.
The same happens if I use a ScrollPane containing an HBox.
I tried to not use preferred sizes, I tried ScrollBarPolicies, nothing seems to work, in the end I came to the conclusion that the problem is somewhere inside the SplitPane.
I even thought maybe the JavaFX Application Thread stopped but when the scrollbar doesn't work it is actually running.
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<SplitPane fx:id="mainPlayerRootPane" disable="true" dividerPositions="0.10275689223057644" prefHeight="337.0" styleClass="mainPlayerRootPane" stylesheets="#style.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.view.GUI.MainPlayerPaneController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<GridPane prefHeight="335.0" prefWidth="78.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="116.0" minHeight="10.0" prefHeight="80.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="82.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="138.0" minHeight="10.0" prefHeight="86.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="85.0" minHeight="10.0" prefHeight="85.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane prefHeight="85.0" translateX="4.0">
<children>
<ImageView fitHeight="77.0" fitWidth="73.0" layoutX="5.0" layoutY="1.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../resources/images/VictoryPoints.png" />
</image>
</ImageView>
<Label fx:id="victoryPointsLabel" alignment="TOP_CENTER" contentDisplay="CENTER" opacity="0.9" prefHeight="79.0" prefWidth="70.0" text="99" textAlignment="JUSTIFY" textFill="WHITE">
<font>
<Font name="Trattatello" size="36.0" />
</font>
</Label>
</children>
</Pane>
<Pane prefHeight="85.0" translateX="4.0" GridPane.rowIndex="1">
<children>
<ImageView fitHeight="79.0" fitWidth="71.0" layoutY="4.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../resources/images/Coins.png" />
</image>
</ImageView>
<Label fx:id="coinsLabel" alignment="CENTER" contentDisplay="CENTER" opacity="0.9" prefHeight="82.0" prefWidth="77.0" text="20" textFill="#222020">
<font>
<Font name="Trattatello" size="30.0" />
</font>
</Label>
</children>
</Pane>
<Pane prefHeight="85.0" prefWidth="81.0" translateX="4.0" GridPane.rowIndex="2">
<children>
<ImageView fitHeight="79.0" fitWidth="73.0" layoutX="17.0" layoutY="2.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../resources/images/Servants.png" />
</image>
</ImageView>
<Label fx:id="servantsLabel" alignment="CENTER" contentDisplay="CENTER" opacity="0.9" prefHeight="101.0" prefWidth="70.0" text="10" textFill="#bcc600">
<font>
<Font name="Trattatello" size="24.0" />
</font>
</Label>
</children>
</Pane>
<Pane prefHeight="85.0" translateX="4.0" GridPane.rowIndex="3">
<children>
<ImageView fitHeight="79.0" fitWidth="71.0" layoutX="1.0" layoutY="3.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../resources/images/Emporiums.png" />
</image>
</ImageView>
<Label fx:id="emporiumsLabel" alignment="CENTER" contentDisplay="CENTER" layoutY="8.0" prefHeight="73.0" prefWidth="71.0" text="10">
<font>
<Font name="Trattatello" size="36.0" />
</font>
</Label>
</children>
</Pane>
</children>
</GridPane>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0">
<children>
<SplitPane dividerPositions="0.5345345345345346" orientation="VERTICAL" prefHeight="335.0" styleClass="mainPlayerRootPane" stylesheets="#style.css" 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">
<children>
<SplitPane dividerPositions="0.5" prefHeight="174.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="160.0">
<children>
<ListView fx:id="cardsListView" editable="true" orientation="HORIZONTAL" prefHeight="172.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0">
<children>
<ListView fx:id="permitsListView" orientation="HORIZONTAL" prefHeight="172.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="134.0" prefWidth="710.0" />
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
Its controller class:
package client.view.GUI;
import java.util.List;
import client.model_properties.PlayerProperty;
import javafx.collections.ListChangeListener;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
public class MainPlayerPaneController {
#FXML
private Label victoryPointsLabel;
#FXML
private Label coinsLabel;
#FXML
private Label servantsLabel;
#FXML
private Label emporiumsLabel;
#FXML
private SplitPane mainPlayerRootPane;
#FXML
private ListView<PoliticalCardView> cardsListView;
#FXML
private ListView<PoliticalCardView> permitsListView;
#FXML
private void initialize(){
}
public void initializeMainPlayerPane(PlayerProperty mainPlayer) {
this.victoryPointsLabel.textProperty().bind(mainPlayer.getVictoryPoint().asString());
this.coinsLabel.textProperty().bind(mainPlayer.getCoins().asString());
this.servantsLabel.textProperty().bind(mainPlayer.getnOfServants().asString());
this.emporiumsLabel.textProperty().bind(mainPlayer.getAvailableEmporiums().asString());
this.addToDeckView(mainPlayer.getDeck());
mainPlayer.getDeckProperty().addListener(new DeckListChangeListener());
}
private void addToDeckView(List<? extends String> cards) {
PoliticalCardView auxCard;
for(String n : cards) {
auxCard = new PoliticalCardView(n);
auxCard.initializeCardView();
this.cardsListView.getItems().add(auxCard);
}
}
private class DeckListChangeListener implements ListChangeListener<String> {
#Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends String> c) {
List<? extends String> added = c.getAddedSubList();
List<? extends String> removed = c.getRemoved();
for(String n : removed) {
Node toRemove = cardsListView.getItems().stream()
.filter( r -> ((PoliticalCardView) r).getColor().equals(n))
.findFirst()
.get();
cardsListView.getItems().remove(toRemove);
}
addToDeckView(added);
}
}
}
And the class i created to represent the cards.
package client.view.GUI;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import utility.UserInterfaceUtilities;
public class PoliticalCardView extends ImageView {
private Image cardImage;
private String color;
public PoliticalCardView(String color) {
this.color = color;
}
public void initializeCardView() {
this.cardImage = UserInterfaceUtilities.POLITICAL_COLORS_TO_IMAGES.get(this.color);
this.setImage(cardImage);
this.setFitHeight(150);
this.setFitWidth(100);
}
public String getColor() {
return this.color;
}
}
I would like to know where's the problem since in two days of research I haven't found nothing similar on the internet and also i used other scrollbars which work just fine.
The problem is here:
<SplitPane fx:id="mainPlayerRootPane" disable="true" ..... >
Your SplitPane is disabled.
When you disable a Node by setting its disabledProperty, all of its children become disabled.
Indicates whether or not this Node is disabled. A Node will become
disabled if disable is set to true on either itself or one of its
ancestors in the scene graph.
Remove disable="true" from the FXML declaration to avoid disabling your ListView or ScrollPane.
I create a simple javafx page.I have a tabPane that has tabs. I wrap tabPane in gridPane that when my page resize it resize too. It work correct and tabPane resize but it's tabs not resize(the size of the tab , not size of the tab content). how can i do that???
TabPane.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class TabPane extends Application {
public static void main(String[] args){
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
GridPane ap = (GridPane) FXMLLoader.load(getClass().getResource("gridTest.fxml"));
Scene scene = new Scene(ap);
stage.setScene(scene);
stage.show();
}
}
gridTest.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="50.0" minWidth="50.0" prefHeight="588.0" prefWidth="600.0" stylesheets="#../GridTest.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="190.0" minHeight="10.0" percentHeight="10.0" prefHeight="11.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="381.0" minHeight="10.0" percentHeight="10.0" prefHeight="381.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" percentHeight="84.4" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children><VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: red;" /><TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" GridPane.rowIndex="1">
<tabs>
<Tab styleClass="tb" text="Untitled Tab 1">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab styleClass="tb" text="Untitled Tab 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane><StackPane prefHeight="150.0" prefWidth="200.0" style="-fx-background-color: blue;" GridPane.rowIndex="2" />
</children>
</GridPane>