I am trying to add close option in tabpane like a browser have it. Could you please tell me how to add closing feature in this tabpane? I tried this line but didn't solve my problem tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS);
I am using javafx jfoenix library for UI.
package tabsDemo;
import java.awt.Color;
import java.awt.Dimension;
import java.math.BigInteger;
import java.security.SecureRandom;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTabPane;
import com.jfoenix.controls.JFXTextField;
public class TabsDemo extends Application {
private String msg = "Tab 0";
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Tabs");
Group root = new Group();
Scene scene = new Scene(root, 800, 600);
JFXButton b1 = new JFXButton();
b1.setId("back");
b1.setGraphic(new ImageView(new Image("/tabsDemo/back.png")));
b1.setMinWidth(20);
b1.setMinHeight(20);
b1.setMaxWidth(20);
b1.setMaxHeight(20);
JFXButton b2 = new JFXButton();
b2.setId("farword");
b2.setGraphic(new ImageView(new Image("/tabsDemo/forward.png")));
b2.setMinWidth(20);
b2.setMinHeight(20);
b2.setMaxWidth(20);
b2.setMaxHeight(20);
JFXButton b3 = new JFXButton();
b3.setId("refresh");
b3.setGraphic(new ImageView(new Image("/tabsDemo/refresh.png")));
b3.setMinWidth(20);
b3.setMinHeight(20);
b3.setMaxWidth(20);
b3.setMaxHeight(20);
JFXTextField t1 = new JFXTextField();
t1.setMinWidth(100);
// t1.setPrefWidth(900);
// t1.setMaxWidth(1000);
t1.setMinHeight(30);
t1.setMaxHeight(30);
GridPane gridPane = new GridPane();
gridPane.setHgap(4);
gridPane.add(b1, 0, 0);
gridPane.add(b2, 1, 0);
gridPane.add(b3, 2, 0);
gridPane.add(t1, 3, 0);
gridPane.setHgrow(t1, Priority.ALWAYS);
BorderPane borderPane = new BorderPane();
borderPane.setTop(gridPane);
JFXTabPane tabPane = new JFXTabPane();
Tab tab1 = new Tab();
tab1.setText("Tab1");
tab1.setContent(borderPane);
VBox vbox = new VBox();
vbox.getChildren().addAll(new JFXButton("B1"), new JFXButton("B2"), new JFXButton("B3"), new JFXButton("B4"));
Tab tab2 = new Tab();
tab2.setText("Tab2");
tab2.setContent(vbox);
tabPane.getTabs().addAll(tab1, tab2);
tabPane.setPrefSize(800, 600);
// I add here the closing option for tab but it's not working
tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS);
SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel();
selectionModel.select(1);
JFXButton button = new JFXButton("Add New Tab");
button.setOnMouseClicked((o) -> {
Tab temp = new Tab();
int count = tabPane.getTabs().size();
temp.setText(msg + count);
temp.setContent(new Label("Tab 0" + count));
tabPane.getTabs().add(temp);
});
borderPane.setRight(button);
tabPane.setMaxSize(800, 600);
/*
* HBox hbox = new HBox(); hbox.getChildren().addAll(button, tabPane);
* hbox.setSpacing(50); hbox.setAlignment(Pos.CENTER);
* hbox.setStyle("-fx-padding:20");
*/
BorderPane rootBorderpane = new BorderPane();
rootBorderpane.setCenter(tabPane);
root.getChildren().addAll(rootBorderpane);
scene.getStylesheets().add(TabsDemo.class.getResource("jfoenix-components.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setTitle("JFX Tabs Demo");
}
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return new BigInteger(50, random).toString(16);
}
}
Thank you!
Your JFXTabPane is a custom component from the JFoenix library, so there's no guarantee that all standard JavaFX settings, such as TabClosingPolicy in your case, are fully implemented.
I checked their GitHub repository and looks like there's an unresolved issue regarding this missing feature. Someone forked the repository, apparently resolved the problem and submitted a pull request, but it's still has an open status. In other words, the changes are not included in the current build, so the bug still exists.
My suggestion is to stick with the standard JavaFX components, which should provide everything you need to create simple applications, including the closeable tabs, which are are working well as presented in the following example.
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("JFX Tabs Demo");
TabPane tabPane = new TabPane();
tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS);
tabPane.getTabs().add(new Tab("Test"));
Scene scene = new Scene(tabPane, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
Related
New to java and JavaFX so please bear with me
I need to do a presentation of 5 3d fruit models that show in a continuous loop, 15 seconds apart: fruit1 for 15 seconds then fruit2 for 15 seconds ad so on and so forth.. until fruit5 for 15 seconds and then back to fruit1 and continues until I hit the ESC key which should close the window.
I also understand that it's ideal to change the root group object that makes up the scene instead of changing the scene, so I changed that in my code
I understand that a timeline is needed in order to change something in the scene as it plays out, but I've tried with something similar to what this answer says but I don't get the logic of how to switch the root of the scene every 15seconds
UPDATE:
I gave up on the timeline option and I found the platform.run option as seen on this article which seems to work as I see the window updates iterating from the first fruit in the scenes array to second one but I'm not sure why it only runs once when I need it to run every 15 seconds which means that my scene switcher: nextSceneIndex() should go back and forth between 1 and 0.
UPDATE2:
I went back to the timeline suggestion and I implemented Sedrick's solution and it worked... I can't be happier :)
Here's my working code!
public void start(Stage stage) throws Exception {
BorderPane[] scenes = new BorderPane[]{createSceneApple(),createSceneCarrot(),createSceneTomato()};
Timeline tl = new Timeline();
tl.setCycleCount(Animation.INDEFINITE);
KeyFrame kf_fruit = new KeyFrame(Duration.seconds(10),
new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
if (index==0){
root.getChildren().setAll(scenes[0]);
index = 1;
}else if(index==1){
root.getChildren().setAll(scenes[1]);
index = 2;
}else if(index==2){
root.getChildren().setAll(scenes[2]);
index = 0;
}
}
});
tl.getKeyFrames().add(kf_fruit);
tl.play();
Scene scene = new Scene(root, windowWidth, windowHeight);
stage.setScene(scene);
stage.show();
}
Maybe you can get some ideas from here. This uses the code from the link I posted above. Timeline is used to loop through a list of Shape and info about that shape.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* JavaFX App
*/
public class App extends Application {
#Override
public void start(Stage stage) {
List<MyShape> shapes = new ArrayList();
shapes.add(new MyShape("Circle", "Shape.Circle", "More Circle Info", new Circle(25, Color.BLUE)));
shapes.add(new MyShape("Rectangle", "Shape.Rectangle", "More Rectangle Info", new Rectangle(100, 50, Color.RED)));
shapes.add(new MyShape("Line", "Shape.Line", "More Line Info", new Line(0, 0, 100, 100)));
TextField tf1 = new TextField();
TextField tf2 = new TextField();
TextArea ta1 = new TextArea();
VBox leftWindow = new VBox(tf1, tf2, ta1);
StackPane rightWindow = new StackPane(shapes.get(1).getShape());
AtomicInteger counter = new AtomicInteger();
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println(counter.get() % shapes.size());
MyShape currentShape = shapes.get(counter.getAndIncrement() % shapes.size());
tf1.setText(currentShape.getName());
tf2.setText(currentShape.getType());
ta1.setText(currentShape.getMoreInfo());
rightWindow.getChildren().set(0, currentShape.getShape());
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
BorderPane root = new BorderPane();
root.setLeft(new StackPane(leftWindow));
root.setRight(rightWindow);
var scene = new Scene(root, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Update:
If you only have two scenes, that simplifies some things. You basically need to set the initial view. You then need to switch out the view currently showing every two seconds. (I used two seconds so that you can see the views before they are switched out). I created my own version of createSceneCarrot and createSceneApple since I don't know your implementation.
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* JavaFX App
*/
public class App extends Application {
#Override
public void start(Stage stage) {
BorderPane[] scenes = new BorderPane[]{createSceneApple(),createSceneCarrot()};
StackPane root = new StackPane(scenes[0]);//Set initial view;
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), (ActionEvent event) -> {
if(root.getChildren().get(0).equals(scenes[0]))//If the first scene is loaded, load the second scene.
{
root.getChildren().set(0, scenes[1]);
}
else
{
root.getChildren().set(0, scenes[0]);
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
var scene = new Scene(root, 640, 640);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
public BorderPane createSceneApple()
{
BorderPane borderPane = new BorderPane();
TextField tf1 = new TextField("Rectangle 1");
TextField tf2 = new TextField("Rectangle Color: Blue");
TextArea ta1 = new TextArea("20x40");
VBox leftWindow = new VBox(tf1, tf2, ta1);
borderPane.setLeft(leftWindow);
StackPane rightWindow = new StackPane(new Rectangle(20, 40, Color.BLUE));
borderPane.setRight(rightWindow);
return borderPane;
}
public BorderPane createSceneCarrot()
{
BorderPane borderPane = new BorderPane();
TextField tf1 = new TextField("Circle 1");
TextField tf2 = new TextField("Circle Color: Blue");
TextArea ta1 = new TextArea("Radius: 50");
VBox leftWindow = new VBox(tf1, tf2, ta1);
borderPane.setLeft(leftWindow);
StackPane rightWindow = new StackPane(new Circle(50, Color.RED));
borderPane.setRight(rightWindow);
return borderPane;
}
}
I'm writing a small game. And i want a pause menu over the blured game menu to be shown when esc is pressed in the middle of the game.
What I do is that i make a new scene which has a stackPane wrapping the past root and the pause menu root and then i set the opacity of the past root 0.4 .
Then when the resume button in the pause menu is clicked i change the opacity back to 1 and set the past scene on stage but then its freezed. does anyone know why? can anyone help me achieve this?
Here is the part i make the new scene and then i put this on stage:
StackPane wrapper = new StackPane();
previousScene = main.getPrimaryStage().getScene();
previousScene.getRoot().setOpacity(.4);
vBox.setId("pausedWrapper");
wrapper.getChildren().add(previousScene.getRoot());
wrapper.getChildren().add(vBox);
scene = new Scene(wrapper, 1200, 700);
return scene;
Here is the part i change it back to where it was:
resumeGame.setOnAction(event -> {
System.out.println("game resumed!");
previousScene.getRoot().setOpacity(1);
main.getPrimaryStage().setScene(previousScene);
});
But then it does not work and the opacity does not change back to normal and the strange thing is when i check the sound on box the music is played but the box does not get checked like everything works but the view is freezed.
A node cannot be part of two different scene graphs. This happens in your code to the root of previousScene, because it is part of both previousScene and the new scene you create in your first block of code. Most likely what is happening is that it is removed from the first scene when you add it to the second (though it is hard to tell from the code you posted).
Consider instead using a Popup to display the pauseMenu on top of the existing window, or just use a modal Stage with undecorated StageStyle, as in the following SSCCE:
import javafx.animation.Animation;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
public class PauseExample extends Application {
#Override
public void start(Stage primaryStage) {
Rectangle rect = new Rectangle(50, 50, 50, 50);
rect.setFill(Color.CORAL);
TranslateTransition animation = createAnimation(rect);
Button pauseButton = new Button("Pause");
Pane pane = new Pane(rect);
pane.setMinSize(600, 150);
BorderPane root = new BorderPane(pane, null, null, pauseButton, new Label("This is\nthe main\nscene"));
pauseButton.setOnAction(e -> {
animation.pause();
root.setEffect(new GaussianBlur());
VBox pauseRoot = new VBox(5);
pauseRoot.getChildren().add(new Label("Paused"));
pauseRoot.setStyle("-fx-background-color: rgba(255, 255, 255, 0.8);");
pauseRoot.setAlignment(Pos.CENTER);
pauseRoot.setPadding(new Insets(20));
Button resume = new Button("Resume");
pauseRoot.getChildren().add(resume);
Stage popupStage = new Stage(StageStyle.TRANSPARENT);
popupStage.initOwner(primaryStage);
popupStage.initModality(Modality.APPLICATION_MODAL);
popupStage.setScene(new Scene(pauseRoot, Color.TRANSPARENT));
resume.setOnAction(event -> {
root.setEffect(null);
animation.play();
popupStage.hide();
});
popupStage.show();
});
BorderPane.setAlignment(pauseButton, Pos.CENTER);
BorderPane.setMargin(pauseButton, new Insets(5));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
private TranslateTransition createAnimation(Rectangle rect) {
TranslateTransition animation = new TranslateTransition(Duration.seconds(1), rect);
animation.setByX(400);
animation.setCycleCount(Animation.INDEFINITE);
animation.setAutoReverse(true);
animation.play();
return animation;
}
public static void main(String[] args) {
launch(args);
}
}
I was wondering how to make the caret visible and/or flash whilst using a TextField or TextArea. The ones I have created in my GUI work as the letters appear when typed but there is no visible caret.
I've looked through the TextField documentation but none are about making it visible or not. I expected to find something along the lines "setCaretVisible(Boolean);"
Do I have to make it visible via CSS? If so, any suggestions would be most welcome!
Please see code that I've quickly put together to illustrate the problem:
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Test extends Application {
public static void main(String[] arguments) { launch(arguments); }
#Override public void start(Stage stage) {
Scene scene = new Scene(new Group());
scene.setRoot(new BuildLayout(stage));
stage.setTitle("Application Name");
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
stage.show();
}
}
final class BuildLayout extends BorderPane {
protected BuildLayout(Stage stage) {
TabPane tabpane = new TabPane();
Tab tab = new Tab();
tab.setGraphic(new Text("Video Browser"));
tab.setClosable(false);
tab.setContent(new Input(1));
tabpane.getTabs().addAll(tab);
setTop(new Toolbar(stage));
setCenter(tabpane);
}
}
final class Input extends VBox {
Input(int id) {
HBox hbox = new HBox();
TextField videoTitle = new TextField("video_title");
TextArea description = new TextArea( "video_description");
Button share = new Button("share");
Button unshare = new Button("unshare");
setPadding(new Insets(5,10,10,5));
setAlignment(Pos.TOP_CENTER);
hbox.getChildren().addAll(videoTitle, new Text(" Creator: " + " Date: " + " Views: " + " "));
if(true) {
videoTitle.setEditable(true);
description.setEditable(true);
if(true) {
hbox.getChildren().add(share);
} else { hbox.getChildren().add(unshare); }
}
getChildren().addAll(hbox, description);
}
}
final class Toolbar extends HBox {
protected Toolbar(Stage stage) {
Button close = new Button("close");
close.setOnAction((ActionEvent e) -> { stage.close(); });
setAlignment(Pos.CENTER_LEFT);
getChildren().addAll(close);
}
}
Many thanks,
This problem only occurs on Mac and not Windows (untested Linux). The fix is to downgrade to a JavaFX 2.2 compliant maximised window as the setMaximized() from JavaFX 8 also isn't Mac compatible.
Modifying the start method with some code found here:
#Override public void start(Stage stage) {
Scene scene = new Scene(new Group());
scene.setRoot(new BuildLayout(stage));
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
stage.setTitle("Application Name");
stage.setScene(scene);
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
stage.show();
}
Produces a fullscreen application with visible and flashing caret.
I'm implementing a TabPane that can be detached from the JavaFX window. When the tab pane is dragged outside of the window where it came from, I would like a new window to be created and the tab to be placed in that window.
I already implemented some methods using drag gestures to drag the tab between existing windows. However, I am not able to receive any mouse events or drag events when the mouse is moved outside of JavaFX scenes. Is this something possible?
You can listen for a mouse released event on the appropriate node (e.g. the tab's graphic). Check the screen coordinates using MouseEvent.getScreenX() and MouseEvent.getScreenY() and see if they lie outside the current window. If they do, create a new window, scene, and tab pane; remove the tab from the current tab pane and place it in the new one.
Here's a basic example with no frills (e.g. no user hints as to the fact that dragging is occuring), but it will give you the idea:
import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.Window;
public class DetachableTabExample extends Application {
private int tabCount = 0 ;
#Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
Button newTabButton = new Button("New Tab");
newTabButton.setOnAction(event -> {
Tab tab = new Tab();
Label tabLabel = new Label("Tab "+(++tabCount));
tab.setGraphic(tabLabel);
tab.setContent(new TextArea());
tabPane.getTabs().add(tab);
tabLabel.setOnMouseReleased(me -> {
Point2D mouseLoc = new Point2D(me.getScreenX(), me.getScreenY());
Window window = tabPane.getScene().getWindow();
Rectangle2D windowBounds
= new Rectangle2D(window.getX(), window.getY(),
window.getWidth(), window.getHeight());
if (! windowBounds.contains(mouseLoc)) {
tabPane.getTabs().remove(tab);
Stage newStage = new Stage();
TabPane newTabPane = new TabPane();
newTabPane.getTabs().add(tab);
Scene scene = new Scene(new BorderPane(newTabPane));
newStage.setScene(scene);
newStage.setX(me.getScreenX());
newStage.setY(me.getScreenY());
newStage.setWidth(window.getWidth());
newStage.setHeight(window.getHeight());
newStage.show();
}
});
});
BorderPane root = new BorderPane(tabPane, newTabButton, null, null, null);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I want to create tabs panel with icons similar to the Firefox configuration panel with JavaFX:
Is there any example which I can use to see how to implement this?
Tabs, like many other elements in JavaFX, have a method called setGraphic(Node value), in which you can put any JavaFX node. Example:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class TabPaneTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Tabs");
Group root = new Group();
Scene scene = new Scene(root, 400, 250, Color.WHITE);
TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
for (int i = 0; i < 5; i++) {
Tab tab = new Tab();
tab.setGraphic(new Circle(0, 0, 10));
HBox hbox = new HBox();
hbox.getChildren().add(new Label("Tab" + i));
hbox.setAlignment(Pos.CENTER);
tab.setContent(hbox);
tabPane.getTabs().add(tab);
}
// bind to take available space
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
borderPane.setCenter(tabPane);
root.getChildren().add(borderPane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Result:
I know its an old thread, but i didnt find a direct answer anywhere. So i thought of posting it some that it will be helpfull for some searching for it.
This is what i did to get a tab like firefox preferences screen.
Add the image to the tab with setGraphics and add the following code to the application css file. My image size was 48x48. So i went for height as 70.
.tab-label {
-fx-content-display: top;
}
.tab-pane {
-fx-tab-min-height: 70;
-fx-tab-max-height: 70;
}
How to add image directly from image url:
Tab tab = new Tab();
tab.setGraphic(buildImage("patch/to/image");
// Helper method to create image from image patch
private static ImageView buildImage(String imgPatch) {
Image i = new Image(imgPatch);
ImageView imageView = new ImageView();
//You can set width and height
imageView.setFitHeight(16);
imageView.setFitWidth(16);
imageView.setImage(i);
return imageView;
}