I am building a javaFX application.
The example program which is online working well: http://www.java2s.com/Tutorials/Java/JavaFX/1010__JavaFX_Timeline_Animation.htm
I changed it a bit:
I want to have these nice moving circles in the background. That's why I made these tricks:
Main.java:
#Override
public void start(Stage primaryStage) {
try {
// load the FXML resource
FXMLLoader loader = new FXMLLoader(getClass().getResource("Dashboard.fxml"));
// store the root element so that the controllers can use it
StackPane root = new StackPane();
Pane bgRoot = new Pane();
GridPane userRoot = (GridPane) loader.load();
// create and style a scene
Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
BackgroundScene bgScene = new BackgroundScene(root, bgRoot, primaryScreenBounds.getWidth(),
primaryScreenBounds.getHeight(), Color.BLACK);
// TODO CSS load:
// bgScene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
// create the stage with the given title and the previously created
// scene
primaryStage.setFullScreen(true);
primaryStage.setMaximized(true);
primaryStage.setResizable(false);
primaryStage.setMinWidth(primaryScreenBounds.getWidth());
primaryStage.setMinHeight(primaryScreenBounds.getHeight());
primaryStage.setScene(bgScene);
root.getChildren().add(bgRoot);
root.getChildren().add(userRoot);
// show the GUI
primaryStage.show();
userRoot.setPrefHeight(root.getHeight());
userRoot.setPrefWidth(root.getWidth());
} catch (Exception e) {
e.printStackTrace();
}
}
In the above code:
I have a stage with a stack pane.
There is a Pane on the StackPane with the Circles
On that there is a GridPane for controllers.
I made my own Scene as BackgroundScene:
public class BackgroundScene extends Scene {
private Pane bgRoot;
public BackgroundScene(Parent root, Pane bgRoot, double width, double height, Color color) {
super(root, width, height, color);
this.bgRoot = bgRoot;
makeGreenCircleAnimation();
}
public void makeGreenCircleAnimation() {
Group circles = new Group();
for (int i = 0; i < 30; i++) {
Circle circle = new Circle(Math.random() * this.getWidth(), Math.random() * this.getHeight(),
150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
circles.setEffect(new BoxBlur(10, 10, 3));
Rectangle colors = new Rectangle(this.getWidth(), this.getHeight(),
new LinearGradient(0f, 1f, 1f, 0f, true, CycleMethod.NO_CYCLE,
new Stop[] { new Stop(0, Color.web("#00ff00")), new Stop(0.14, Color.web("#11ee11")),
new Stop(0.28, Color.web("#22dd22")), new Stop(0.43, Color.web("#33cc33")),
new Stop(0.57, Color.web("#44bb44")), new Stop(0.71, Color.web("#55aa55")),
new Stop(0.85, Color.web("#669966")), new Stop(1, Color.web("#778877")), }));
Group blendModeGroup = new Group(
new Group(new Rectangle(this.getWidth(), this.getHeight(), Color.DARKGREEN), circles), colors);
colors.setBlendMode(BlendMode.OVERLAY);
bgRoot.getChildren().add(blendModeGroup);
Timeline timeline = new Timeline();
makeAnimation(circles, timeline);
timeline.play();
timeline.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
makeAnimation(circles, timeline);
timeline.play();
}
});
}
void makeAnimation(Group group, Timeline timeline) {
timeline.getKeyFrames().clear();
for (Node node : group.getChildren()) {
timeline.getKeyFrames()
.addAll(new KeyFrame(Duration.ZERO, // set start
// position at 0
new KeyValue(node.translateXProperty(), node.getLayoutX() + node.getTranslateX()),
new KeyValue(node.translateYProperty(), node.getLayoutY() + node.getTranslateY())),
new KeyFrame(new Duration(4000), // set end position at
// 40s
new KeyValue(node.translateXProperty(), Math.random() * this.getWidth()),
new KeyValue(node.translateYProperty(), Math.random() * this.getHeight())));
}
}
}
It contains the code from the tutorial (with minor changes).
I add the circles and everything to the Pane not to a Group (as in
the online example)
The problem is that it is seams to be moving:
The circles are moving to the right (always)
If I change something in the code:
Main.java (instantiating my scene):
BackgroundScene bgScene = new BackgroundScene(root, root, primaryScreenBounds.getWidth(),
primaryScreenBounds.getHeight(), Color.BLACK);
(so giving the circles to the StackPane)
This happens:
You can download the eclipse project:
https://www.dropbox.com/s/dovae0hxdtsnsdo/Test.7z?dl=0
Do you know what is the problem?
Or can you suggest something how I can put the circles nicely behind the button?
Related
I've been trying to code this Javafx gui program, however when ever Try to use the getValue() method it ends up saying "it can't find that symbol". Even if I try demos of using the method. How can i get this method to work, is there any other way I can get code to run when the user chooses a choice from the combobox?
not showing my imports, as they are a lot.
public class LogoMaster3000 extends Application {
BorderPane border;
HBox hbox;
Canvas can;
AnchorPane ap;
Scene scene;
Button shapesComboBox;
// Desktop desktop = Desktop.getDesktop();
TextField tx;
#Override
public void start(Stage primaryStage) {
border = new BorderPane();
hbox = addHBox();
border.setTop(hbox);
border.setLeft(addVBox());
addStackPane(hbox); // Add stack to HBox in top region
can = new Canvas();
can.setStyle("-fx-background-color: #E8EACD");
AnchorPane wrapperPane = new AnchorPane();
border.setCenter(wrapperPane);
scene = new Scene(border, 1000, 600);
primaryStage.setTitle("LogoMaker 3000");
primaryStage.setScene(scene);
primaryStage.show();
shapesComboBox.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if (shapesComboBox.getValue == "Square"){
Rectangle square = new Rectangle(50, 50);
square.setFill(Color.BLACK);
DragResizeMod.makeResizable(square, null);
wrapperPane.getChildren().add(square);
}
if (shapesComboBox.getValue == "Rectangle"){
Rectangle rectangle = new Rectangle(50, 50);
rectangle.setFill(Color.BLACK);
DragResizeMod.makeResizable(rectangle, null);
wrapperPane.getChildren().add(rectangle);
}
if (shapesComboBox.getValue == "Triangle"){
Polygon polygon = new Polygon();
polygon.getPoints().addAll(new Double[]{
75, 0,
50, 50,
100, 100
})
polygon.setFill(Color.BLACK);
DragResizeMod.makeResizable(polygon, null);
wrapperPane.getChildren().add(polygon);
}
if (shapesComboBox.getValue == "Circle"){
Circle circle = new Circle(100,100,50);
circle.setFill(Color.BLACK);
DragResizeMod.makeResizable(circle, null)
wrapperPane.getChildren().add(circle);
}
}
}
);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
public void addStackPane(HBox hb) {
StackPane stack = new StackPane();
Rectangle helpIcon = new Rectangle(30.0, 25.0);
helpIcon.setFill(new LinearGradient(0,0,0,1, true, CycleMethod.NO_CYCLE,
new Stop[]{
new Stop(0,Color.web("#4977A3")),
new Stop(0.5, Color.web("#B0C6DA")),
new Stop(1,Color.web("#9CB6CF")),}));
helpIcon.setStroke(Color.web("#D0E6FA"));
helpIcon.setArcHeight(3.5);
helpIcon.setArcWidth(3.5);
Text helpText = new Text("?");
helpText.setFont(Font.font("Verdana", FontWeight.BOLD, 18));
helpText.setFill(Color.WHITE);
helpText.setStroke(Color.web("#7080A0"));
stack.getChildren().addAll(helpIcon, helpText);
stack.setAlignment(Pos.CENTER_RIGHT); // Right-justify nodes in stack
StackPane.setMargin(helpText, new Insets(0, 10, 0, 0)); // Center "?"
hb.getChildren().add(stack); // Add to HBox from Example 1-2
HBox.setHgrow(stack, Priority.ALWAYS); // Give stack any extra space
}
public VBox addVBox() {
VBox vbox = new VBox();
vbox.setPadding(new Insets(10));
vbox.setSpacing(8);
Text title = new Text("Logo Maker");
title.setFont(Font.font("Arial", FontWeight.BOLD, 14));
vbox.getChildren().add(title);
final ComboBox shapesComboBox = new ComboBox();
shapesComboBox.getItems().addAll(
"Square",
"Rectangle",
"Triangle",
"Circle",
"Pyramid",
"Cube",
"Sphere"
);
shapesComboBox.setPromptText("Shapes");
shapesComboBox.setMaxWidth(Double.MAX_VALUE);
vbox.getChildren().add(shapesComboBox);
return vbox;
}
}
In below code, I have a box added in scene. I am printing the mouse event coordinate. Coordinates are fine when I am not clicking on the box but as soon as I click on the box I get some different set of coordinate relative to some different node. I am trying to get the normalized coordinate, relative to scene only, even if I click on the box. I cant use me.getSceneX()/Y() and cant set box as mouse transparent. So how to carry out this transformation. Thanks.
public class PointConversion extends Application
{
private final static Group worldRoot = new Group();
private final PerspectiveCamera camera = new PerspectiveCamera(true);
private final static Scene scene = new Scene(worldRoot, 1100, 800);
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage primaryStage)
{
camera.setNearClip(1.0);
camera.setTranslateZ(-6000);
camera.setFarClip(100000.0);
worldRoot.getChildren().add(camera);
scene.setCamera(camera);
primaryStage.setScene(scene);
primaryStage.show();
scene.setOnMousePressed(me ->
{
Point2D mousePoint = new Point2D(me.getX(), me.getY());
if(!(me.getTarget() instanceof Scene))
{
PickResult pickResult = me.getPickResult();
mousePoint = pickResult.getIntersectedNode().localToScene(mousePoint);
}
System.out.println("me.getSource() : " + me.getTarget() + " mousePoint:" + mousePoint);
});
final PhongMaterial blueMaterial = new PhongMaterial();
blueMaterial.setDiffuseColor(Color.web(Color.CRIMSON.toString(), 0.25));
blueMaterial.setSpecularColor(Color.web(Color.CRIMSON.toString(), 0.25));
Box cubiod = new Box(500, 500, 500);
cubiod.setMaterial(blueMaterial);
worldRoot.getChildren().add(cubiod);
}
}
Is it possible to do a simple background "flash" effect with a gradual fade on an arbitrary Node/Region/Pane?
I just want to show a subtle/brief red/white "flash" effect on a VBox (containing a label) to draw attention to it when the label's value changes.
Edit: All examples of this nature I've found so far seem to use a "Shape" (which is a Node), but of course a VBox or a Pane aren't a Shape - so that doesn't help me too much. Calling getShape() on the VBox just returns a null, so that's no help (I guess layout code hasn't been executed yet).
Edit 2:
This ALMOST works, but this dang effect seems to be completely overwriting (I think) everything in the VBox, including the text Label.
ColorInput effect = new ColorInput(0, 0, 900, 25, Paint.valueOf("#FFDDDD"));
Timeline flash = new Timeline(
new KeyFrame(Duration.seconds(0.4), new KeyValue(effect.paintProperty(), Paint.valueOf("#EED9D9"))),
new KeyFrame(Duration.seconds(0.8), new KeyValue(effect.paintProperty(), Paint.valueOf("#E0DDDD"))),
new KeyFrame(Duration.seconds(1.0), new KeyValue(effect.paintProperty(), Paint.valueOf("#DDDDDD"))));
vbox.setEffect(effect);
flash.setOnFinished(e -> vbox.setEffect(null));
flash.play();
Best way would be to provide a custom animation, like this (elaborating on fabian's answer):
#Override
public void start(Stage primaryStage) {
Label label = new Label("Bla bla bla bla");
Button btn = new Button("flash");
VBox box = new VBox(10, label, btn);
box.setPadding(new Insets(10));
btn.setOnAction((ActionEvent event) -> {
//**************************
//this animation changes the background color
//of the VBox from red with opacity=1
//to red with opacity=0
//**************************
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(1000));
setInterpolator(Interpolator.EASE_OUT);
}
#Override
protected void interpolate(double frac) {
Color vColor = new Color(1, 0, 0, 1 - frac);
box.setBackground(new Background(new BackgroundFill(vColor, CornerRadii.EMPTY, Insets.EMPTY)));
}
};
animation.play();
});
Scene scene = new Scene(box, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
You could animate a effect, e.g. DropShadow:
#Override
public void start(Stage primaryStage) {
Label label = new Label("Bla bla bla bla");
DropShadow shadow = new DropShadow();
shadow.setColor(Color.RED);
shadow.setSpread(0.75);
Timeline shadowAnimation = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(shadow.radiusProperty(), 0d)),
new KeyFrame(Duration.seconds(0.15), new KeyValue(shadow.radiusProperty(), 20d)));
shadowAnimation.setAutoReverse(true);
shadowAnimation.setCycleCount(2);
Button btn = new Button("flash");
btn.setOnAction((ActionEvent event) -> {
Node target = label;
target.setEffect(shadow);
shadowAnimation.setOnFinished(evt -> target.setEffect(null));
shadowAnimation.play();
});
VBox box = new VBox(10, label, btn);
box.setPadding(new Insets(10));
Scene scene = new Scene(box, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
You can create a fake shape and use the FillTransition Interpolator to apply the shape's fill to the control background.
public static void AnimateBackgroundColor(Control control, Color fromColor,Color toColor,int duration)
{
Rectangle rect = new Rectangle();
rect.setFill(fromColor);
FillTransition tr = new FillTransition();
tr.setShape(rect);
tr.setDuration(Duration.millis(duration));
tr.setFromValue(fromColor);
tr.setToValue(toColor);
tr.setInterpolator(new Interpolator() {
#Override
protected double curve(double t) {
control.setBackground(new Background(new BackgroundFill(rect.getFill(), CornerRadii.EMPTY, Insets.EMPTY)));
return t;
}
});
tr.play();
}
I'm using this to make a iOS-themed JavaFX2 (Java7) application with a frosted glass effect. The problem is that this code uses its effect on an ImageView. I'd like it to use its effect on whatever's behind the window, like this:
Is there anyway to do that? I'd also like that small drop-shadow effect you see around the above image.
To be clear, I don't want that slider or anything, just the effect of being able to see through the window and having that slight shadow around the edges. I want to use this iOS7-ish effect instead of aero, though.
This might be important: I'm using a modified version of Undecorator.
import javafx.animation.*;
import javafx.application.*;
import javafx.beans.property.*;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.effect.*;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.image.*;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
public class FrostyTech extends Application {
private static final double BLUR_AMOUNT = 10;
private static final Effect frostEffect =
new BoxBlur(BLUR_AMOUNT, BLUR_AMOUNT, 3);
private static final ImageView background = new ImageView();
private static final StackPane layout = new StackPane();
#Override public void start(Stage stage) {
layout.getChildren().setAll(background, createContent());
layout.setStyle("-fx-background-color: null");
Scene scene = new Scene(
layout,
200, 300,
Color.TRANSPARENT
);
Platform.setImplicitExit(false);
scene.setOnMouseClicked(event -> {
if (event.getClickCount() == 2) Platform.exit();
});
makeSmoke(stage);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
background.setImage(copyBackground(stage));
background.setEffect(frostEffect);
makeDraggable(stage, layout);
}
// copy a background node to be frozen over.
private Image copyBackground(Stage stage) {
final int X = (int) stage.getX();
final int Y = (int) stage.getY();
final int W = (int) stage.getWidth();
final int H = (int) stage.getHeight();
try {
java.awt.Robot robot = new java.awt.Robot();
java.awt.image.BufferedImage image = robot.createScreenCapture(new java.awt.Rectangle(X, Y, W, H));
return SwingFXUtils.toFXImage(image, null);
} catch (java.awt.AWTException e) {
System.out.println("The robot of doom strikes!");
e.printStackTrace();
return null;
}
}
// create some content to be displayed on top of the frozen glass panel.
private Label createContent() {
Label label = new Label("Create a new question for drop shadow effects.\n\nDrag to move\n\nDouble click to close");
label.setPadding(new Insets(10));
label.setStyle("-fx-font-size: 15px; -fx-text-fill: green;");
label.setMaxWidth(250);
label.setWrapText(true);
return label;
}
// makes a stage draggable using a given node.
public void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(mouseEvent -> {
// record a delta distance for the drag and drop operation.
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
byNode.setCursor(Cursor.MOVE);
});
final BooleanProperty inDrag = new SimpleBooleanProperty(false);
byNode.setOnMouseReleased(mouseEvent -> {
byNode.setCursor(Cursor.HAND);
if (inDrag.get()) {
stage.hide();
Timeline pause = new Timeline(new KeyFrame(Duration.millis(50), event -> {
background.setImage(copyBackground(stage));
layout.getChildren().set(
0,
background
);
stage.show();
}));
pause.play();
}
inDrag.set(false);
});
byNode.setOnMouseDragged(mouseEvent -> {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
layout.getChildren().set(
0,
makeSmoke(stage)
);
inDrag.set(true);
});
byNode.setOnMouseEntered(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.HAND);
}
});
byNode.setOnMouseExited(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.DEFAULT);
}
});
}
private javafx.scene.shape.Rectangle makeSmoke(Stage stage) {
return new javafx.scene.shape.Rectangle(
stage.getWidth(),
stage.getHeight(),
Color.WHITESMOKE.deriveColor(
0, 1, 1, 0.08
)
);
}
/** records relative x and y co-ordinates. */
private static class Delta {
double x, y;
}
public static void main(String[] args) {
launch(args);
}
}
Related Questions
Frosted Glass Effect in JavaFX?
How do I create a JavaFX transparent stage with shadows on only the border?
The visual effect that you want for OS dependent window decoration, can only be achieved through the APIs that OS provides. And thus was eliminated by StageStyle.TRANSPARENT below.
For JavaFX content itself, you can control the visuals of the stage > scene > root pane hierarchy. Stage and scene do not (and not aimed to) support advanced stylings so were eliminated by setting as transparent below.
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.setStyle("-fx-background-color: null;");
root.setPadding(new Insets(10));
DoubleProperty doubleProperty = new SimpleDoubleProperty(0);
Region region = new Region();
region.styleProperty().bind(Bindings
.concat("-fx-background-radius:20; -fx-background-color: rgba(56, 176, 209, ")
.concat(doubleProperty)
.concat(");"));
region.setEffect(new DropShadow(10, Color.GREY));
Slider slider = new Slider(0, 1, .3);
doubleProperty.bind(slider.valueProperty());
root.getChildren().addAll(region, slider);
primaryStage.initStyle(StageStyle.TRANSPARENT);
Scene scene = new Scene(root, 300, 250);
scene.setFill(Color.TRANSPARENT);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
However the drop shadow effect does not play well with alpha value of the background color. You can observe it by changing the shadow's color to another contrast one.
Output:
To expand on Jewlsea's answer .. And using the above example with JavaFX ONLY ..
While the classes are not public API, it does avoid the AWT stack completely.
Here is a non public example :
// copy a background node to be frozen over.
private Image copyBackground(Stage stage) {
final int X = (int) stage.getX();
final int Y = (int) stage.getY();
final int W = (int) stage.getWidth();
final int H = (int) stage.getHeight();
final Screen screen = Screen.getPrimary();
try {
Robot rbt = com.sun.glass.ui.Application.GetApplication().createRobot();
Pixels p = rbt.getScreenCapture(
(int)screen.getBounds().getMinX(),
(int)screen.getBounds().getMinY(),
(int)screen.getBounds().getWidth(),
(int)screen.getBounds().getHeight(),
true
);
WritableImage dskTop = new WritableImage((int)screen.getBounds().getWidth(), (int)screen.getBounds().getHeight());
dskTop.getPixelWriter().setPixels(
(int)screen.getBounds().getMinX(),
(int)screen.getBounds().getMinY(),
(int)screen.getBounds().getWidth(),
(int)screen.getBounds().getHeight(),
PixelFormat.getByteBgraPreInstance(),
p.asByteBuffer(),
(int)(screen.getBounds().getWidth() * 4)
);
WritableImage image = new WritableImage(W,H);
image.getPixelWriter().setPixels(0, 0, W, H, dskTop.getPixelReader(), X, Y);
return image;
} catch (Exception e) {
System.out.println("The robot of doom strikes!");
e.printStackTrace();
return null;
}
}
Results with a small dropshadow added:
DropShadow shdw = new DropShadow();
shdw.setBlurType(BlurType.GAUSSIAN);
shdw.setColor(Color.GAINSBORO);
shdw.setRadius(10);
shdw.setSpread(0.12);
shdw.setHeight(10);
shdw.setWidth(10);
layout.setEffect(shdw);
The opacity is a property of Node, which is the parent class in JavaFX for things that show up on the screen. http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#opacityProperty
So you can just set the opacity on the object that you want to have fade away. You then have to add some sort of way to change the opacity on the desired object. Using the slider from your image is one way, but there are others.
Drop shadows can be done using the DropShadow effect... http://docs.oracle.com/javafx/2/api/javafx/scene/effect/DropShadow.html. I have never used it. This is a little high level but if there are follow up questions in the comments I can help answer them.
I have this simple example with JavaFX tabs:
public class test extends Application
{
private BorderPane root;
// Navigation Utilization
private ActionTabs actiontabs;
#Override
public void start(Stage primaryStage)
{
// Set Main Window Label
primaryStage.setTitle("Desktop Client");
Image iv = new Image(getClass().getResource("/images/internet-icon.png").toExternalForm());
primaryStage.getIcons().add(iv);
root = new BorderPane();
root.setLeft(getLeftHBox(primaryStage, root));
Scene scene = new Scene(root, 1000, 1000, Color.WHITESMOKE); // Set main Stage color
primaryStage.setScene(scene);
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
// Set Stage boundaries to visible bounds of the main screen
primaryStage.setX(primaryScreenBounds.getMinX());
primaryStage.setY(primaryScreenBounds.getMinY());
primaryStage.setWidth(primaryScreenBounds.getWidth()); // Maximum width of the display
primaryStage.setHeight(primaryScreenBounds.getHeight()); // Maximum height of the display
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
private HBox getLeftHBox(Stage primaryStage, BorderPane root)
{
HBox hbox = new HBox();
TabPane tabPane = new TabPane();
BorderPane mainPane = new BorderPane();
tabPane.setStyle("-fx-font-size: 12pt;"); // Set global size for the font
// Create Tabs
Tab tabA = new Tab();
tabA.setText("Main Component");
tabA.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
tabA.setClosable(false);
// Add something in Tab
StackPane tabA_stack = new StackPane();
tabA_stack.setAlignment(Pos.CENTER);
tabA_stack.getChildren().add(new Label("Label#Tab A"));
tabA.setContent(tabA_stack);
tabPane.getTabs().add(tabA);
Tab tabB = new Tab();
tabB.setText("Second Component");
tabB.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
tabB.setClosable(false);
// Add something in Tab
StackPane tabB_stack = new StackPane();
tabB_stack.setAlignment(Pos.CENTER);
tabB_stack.getChildren().add(new Label("Label#Tab B"));
tabB.setContent(tabB_stack);
tabPane.getTabs().add(tabB);
Tab tabC = new Tab();
tabC.setText("Last Component");
tabC.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name
tabC.setClosable(false); // da se mahne opciqta da se zatvarq tab
// Add something in Tab
StackPane tabC_vBox = new StackPane();
tabC_vBox.setAlignment(Pos.CENTER);
tabC_vBox.getChildren().add(new Label("Label#Tab C"));
tabC.setContent(tabC_vBox);
tabPane.getTabs().add(tabC);
mainPane.setCenter(tabPane);
mainPane.setPrefSize(300, 500);
//mainPane.setLayoutX(5); // Horizontal Position
mainPane.setLayoutY(32); // Vertical Position
hbox.getChildren().addAll(mainPane);
return hbox;
}
}
I want when I double click on a tab name to maximize the size of the body of the tab and make it the same width and height as the size of the application. Similar for example to Eclipse IDE tabs. Is this possible with JavaFX?
EDIT
This is the code that I have tested.
public BorderPane initNavigation(Stage primaryStage)
{
VBox stackedTitledPanes = createStackedTitledPanes();
ScrollPane scroll = makeScrollable(stackedTitledPanes);
final TabPane tabPane = new TabPane();
final BorderPane mainPane = new BorderPane();
final Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
tabPane.setStyle("-fx-font-size: 12pt;"); // Set global size for the font
// Create Tabs
Tab tabA = new Tab();
tabPane.setOnMouseClicked(new EventHandler<MouseEvent>()
{
private double sizeX, sizeY;
private boolean first = true;
#Override
public void handle(MouseEvent me)
{
if (first)
{
sizeX = mainPane.getWidth();
sizeY = mainPane.getHeight();
first = false;
}
if (me.getButton().equals(MouseButton.PRIMARY) && me.getClickCount() % 2 == 0)
{
if (sizeX != mainPane.getWidth() || sizeY != mainPane.getHeight())
{
mainPane.setPrefSize(sizeX, sizeY);
}
else
{
mainPane.setPrefSize(primaryScreenBounds.getWidth(), primaryScreenBounds.getHeight());
//mainPane.toFront();
}
}
}
});
tabA.setText("Main Component");
tabA.setContextMenu(makeTabContextMenu(tabA, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabA_stack = new StackPane();
tabA_stack.setAlignment(Pos.CENTER);
tabA_stack.getChildren().add(scroll);
tabA.setContent(tabA_stack);
tabPane.getTabs().add(tabA);
Tab tabB = new Tab();
tabB.setText("Second Component");
tabB.setContextMenu(makeTabContextMenu(tabB, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabB_stack = new StackPane();
tabB_stack.setAlignment(Pos.CENTER);
tabB_stack.getChildren().add(new Label("Label#Tab B"));
tabB.setContent(tabB_stack);
tabPane.getTabs().add(tabB);
Tab tabC = new Tab();
tabC.setText("Last Component");
tabC.setContextMenu(makeTabContextMenu(tabC, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabC_vBox = new StackPane();
tabC_vBox.setAlignment(Pos.CENTER);
tabC_vBox.getChildren().add(new Label("Label#Tab C"));
tabC.setContent(tabC_vBox);
tabPane.getTabs().add(tabC);
mainPane.setCenter(tabPane);
mainPane.setPrefSize(300, 500);
//mainPane.setLayoutX(5); // Horizontal Position
mainPane.setLayoutY(32); // Vertical Position
scroll.setPrefSize(395, 580);
scroll.setLayoutX(5);
scroll.setLayoutY(32);
return mainPane;
}
The problem is how I can cover the stage with the tab code when I double click on the tab name?
You required to add few lines to your code, here is a sample for you,
.....
Tab tabA = new Tab();
Label tabALabel = new Label("Main Component");
tabA.setGraphic(tabALabel);
tabALabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
if (mouseEvent.getClickCount() == 2) {
mainPane.setPrefSize(500, 500); //Your required size
}
}
}
});
....
Try this, and tell if there's any difficulty.
You could create another BorderPane which contains your root = new BorderPane();
in Center, and replace it with the Tabpanel on doubleclick.
Resulting in:
rootRoot = new BorderPane();
BorderPane root = new BorderPane();
root.setLeft(getLeftHBox(primaryStage, root));
rootRoot.setCenter(root);
Scene scene = new Scene(rootRoot, 1000, 1000, Color.WHITESMOKE); // Set main Stage color
with "rootRoot" being the new root (great Name, i know ^^), and
Label tabALabel=new Label("Label#Tab A");
tabALabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
if (mouseEvent.getClickCount() == 2) {
//mainPane.setPrefSize(500, 500); //Your required size
rootRoot.setCenter(mainPane);
}
}
}
});
for maximizing.