I am trying to re-size an image so it fits (scaled) in the space allotted by a SplitPane (for workaround suggestions: this image will change when running the program, it should be generated from the text). The ImageView I'm using currently changes the location of the SplitPane Divider. The divider can never cause the ImageView to decrease past the size of the image.
Two images showing this behavior.
Linking the ImageView fitWidthProperty to a VBox has not given me the resize behavior I expected. Increasing the ImageView's size does work (where it is fixed without the binding), but the image never grows, it just gets borders around it.
My MWE:
sample.fxml:
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<SplitPane orientation="HORIZONTAL" xmlns:fx="http://javafx.com/fxml">
<TextArea fx:id="textArea"/>
<VBox fx:id="vBox" alignment="CENTER">
<HBox fx:id="hBox" alignment="CENTER">
<ImageView fx:id="imageView"/>
</HBox>
</VBox>
</SplitPane>
Controller.java:
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class Controller {
#FXML
private TextArea textArea = new TextArea();
#FXML
private VBox vBox = new VBox();
#FXML
private HBox hBox = new HBox();
#FXML
private ImageView imageView = new ImageView();
public Controller() {
imageView.fitWidthProperty().bind(vBox.widthProperty());
imageView.fitHeightProperty().bind(hBox.heightProperty());
}
public void start() {
textArea.setText("text");
Image image = new Image("https://www.google.nl/images/srpr/logo11w.png");
imageView.setImage(image);
}
}
and Main.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(final Stage primaryStage) throws Exception {
final Controller controller = new Controller();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
fxmlLoader.setController(controller);
final Parent root = fxmlLoader.load();
primaryStage.setTitle("MWE");
final Scene scene = new Scene(root, 640, 480);
primaryStage.setScene(scene);
primaryStage.show();
controller.start();
}
public static void main(String[] args) {
launch(args);
}
}
You can try binding the ImageView's fitWidthProperty() to the SplitPane's divider position property.
A binding similar to this should work :
imageView.fitWidthProperty().bind(Bindings.subtract(1,
splitPane.getDividers().get(0).positionProperty())
.multiply(splitPane.widthProperty());
this is my sample for you!
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<StackPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center">
<SplitPane fx:id="splitpane">
<VBox fx:id="left" prefWidth="300" prefHeight="200" style="-fx-background-color: antiquewhite">
<ImageView fx:id="image1" preserveRatio="true" pickOnBounds="true">
<image>
<Image url="#/sample/test.jpg"/>
</image>
</ImageView>
</VBox>
<VBox fx:id="right" prefWidth="300" prefHeight="300" style="-fx-background-color: aquamarine">
<ImageView fx:id="image2" preserveRatio="true" pickOnBounds="true">
<image>
<Image url="#/sample/test.jpg"/>
</image>
</ImageView>
</VBox>
</SplitPane>
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.SplitPane;
import javafx.scene.image.ImageView;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML
ImageView image1;
#FXML
ImageView image2;
#FXML
SplitPane splitpane;
#Override
public void initialize(URL location, ResourceBundle resources) {
splitpane.getDividers().get(0).positionProperty().addListener((observable, oldValue, newValue) -> {
System.out.println(newValue);
int w = 600;
double w1 = w * newValue.doubleValue();
double w2 = w - w1;
image1.setFitWidth(w1);
image2.setFitWidth(w2);
});
}
}
Related
I'm worked with java for a year and am pretty new to javaFX and have been have been following a basic tutorial so far using scenebuilder. I've tried to apply a translatetransition to my button so far but it doesn't seem to move at all. When I run the program the scene with its background is displayed, but the button just stays in its defined start position in scenebuilder and won't move. After checking other similar questions on this site I've made sure that I implemented Initializable and adding #Override before my initialize function, and I've made sure my transition is played. I've tried the translatetransition on a rectangle too and it won't move. Might just be that I'm using eclipse and not netbeans
Driver Class:
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
//import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent myroot = FXMLLoader.load(getClass().getClassLoader().getResource("MyFxml.fxml"));
//BorderPane root = new BorderPane();
Scene scene = new Scene(myroot);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
FXML
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="413.0" fitWidth="638.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../Downloads/campusmap.png" />
</image>
</ImageView>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Rectangle fx:id="myrectangle" arcHeight="5.0" arcWidth="5.0" fill="#128cff" height="200.0" layoutX="14.0" layoutY="64.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
<Button fx:id="startbutton" layoutX="202.0" layoutY="232.0" mnemonicParsing="false" prefHeight="64.0" prefWidth="197.0" style="-fx-background-color: #FFC0CB; -fx-background-radius: 100;" text="Start Program">
<font>
<Font name="Comic Sans MS" size="12.0" />
</font></Button>
</children>
</AnchorPane>
</children>
</StackPane>
FXML Controller
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import javafx.animation.TranslateTransition;
public class MyFxmlController implements Initializable{
#FXML
private Button startbutton;
#FXML
private Rectangle myrectangle;
#Override
public void initialize(URL url, ResourceBundle rb) {
TranslateTransition transition = new TranslateTransition();
transition.setDuration(Duration.seconds(4));
transition.setNode(startbutton);
transition.setToX(-200);
transition.setToY(-200);
transition.play();
}
}
You are not "linking" your controller to the FXML document. So when you display the FXML layout, the Transition code is never executed.
You have a couple of options to do this. In SceneBuilder, you can specify the controller class here:
This will add the fx:controller attribute to your FXML file:
fx:controller="temp.translate.MyFxmlController"
Obviously, you'll need to use your own package paths here.
The other option is to specify the controller in your Java code by updating your loading of the FXML document.
In order to do so, you'll need to get a reference to the FXMLLoader and set the controller there. You can change your start() method like this:
#Override
public void start(Stage primaryStage) {
try {
// Create a new FXMLLoader and set the FXML path
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyFxml.fxml"));
// Set the controller for this FXML document
loader.setController(new MyFxmlController());
// Load the FXML into your Parent node
Parent myRoot = loader.load();
//BorderPane root = new BorderPane();
Scene scene = new Scene(myRoot);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
Note: If you've specified the controller in your FXML via fx:controller, you cannot also specify it in your Java code, and vice versa. You may only define the controller in one place or the other, so it's really personal preference and depends on your needs.
I have an ImageView which I have configured so that it is resized to fit its parent AnchorPane with the two following lines of code (both the AnchorPane and the image are square).
preview.fitWidthProperty().bind(previewPane.maxWidthProperty());
preview.fitHeightProperty().bind(previewPane.maxWidthProperty());
I have also set a fitWidth of 450 px in an fxml file that injects all nodes. When I create an instance of this object however it opens the preview with a width equal to that of the loaded image (2000 px) and not 450 px. The resizing functionality works as expected and it is possible to shrink it down to 450 px. I was wondering however if it is possible to make sure it opens up with a default size different from that of the width of the image but also making sure so that it grows and shrinks with its parent.
I have tried setting loads of different default widths in both java code and fxml but the only thing that seems to work is unbinding the fitWidth which I don't want.
Do you have any suggestions as to how I might solve this?
Main:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainTest extends Application {
#FXML private AnchorPane previewPane;
#FXML private ImageView preview;
#Override
public void start(Stage primaryStage) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Test.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setClassLoader(getClass().getClassLoader());
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
preview.fitWidthProperty().bind(previewPane.maxWidthProperty());
preview.fitHeightProperty().bind(previewPane.maxWidthProperty());
Scene scene = new Scene(previewPane);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="previewPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fx:id="preview" fitHeight="450.0" fitWidth="450.0" layoutX="55.0" layoutY="36.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<image>
<Image url="#Blue%20Eyes%20White%20Dragon.png" />
</image>
</ImageView>
</children>
</AnchorPane>
EDIT: Here is a MCVE of my problem.
The structure of your project is wrong. Also, to fix the problem you are having, you need to set the Scene size.
Code to get the ImageView from the Controller
//Code in the Main
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
Parent root = loader.load();
FXMLDocumentController fXMLDocumentController = loader.getController();
ImageView preView = fXMLDocumentController.getPreview();
//Code in the Controller
public ImageView getPreview()
{
return preview;
}
Code to set the Scene's size
stage.setWidth(450);
stage.setHeight(450);
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication213 extends Application
{
#Override
public void start(Stage stage) throws Exception
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
Parent root = loader.load();
FXMLDocumentController fXMLDocumentController = loader.getController();
ImageView preView = fXMLDocumentController.getPreview();
Scene scene = new Scene(root);
stage.setWidth(450);
stage.setHeight(450);
stage.setScene(scene);
stage.show();
preView.fitHeightProperty().bind(stage.heightProperty());
preView.fitWidthProperty().bind(stage.widthProperty());
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
Controller
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;
/**
*
* #author blj0011
*/
public class FXMLDocumentController implements Initializable
{
#FXML
private ImageView preview;
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
}
public ImageView getPreview()
{
return preview;
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="previewPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication213.FXMLDocumentController">
<children>
<ImageView fx:id="preview" fitHeight="450.0" fitWidth="450.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<image>
<Image url="#Blue%20Eyes%20White%20Dragon.png" />
</image>
</ImageView>
</children>
</AnchorPane>
Finally, you need to uncheck Preserve Ratio. The FXML should already have this unchecked. I am pointing this out because it's important.
I created a javaFX fxml application in NetBeans and want to display an image using a filechooser opened in a handleButtonAction event.
If I drag an ImageView into the panel using the gui builder I see no way to get it's object generated in code.
If I add an Imageview manually to the main class, I do not have the button handler method available, and if I add it to the controller class, I do not have the main panel available to attach the Imageview to. I think I am not understanding how to elements from the ui builder generated into code.
The generated NetBeans projects starts with a hello button that also has no visible object in the source files, so it seems clear that I am missing something about how the ui builder sets the proper xml data to have those elements available to the controller, but there doesn't appear to me to be any way add these to the controller from the ui builder. Is it just that the UI builder is unreliable?
Any help would be appreciated.
The main application class looks like:
package javafxapplication2;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class JavaFXApplication2 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
And the Controller:
package javafxapplication2;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
//import javafx.scene.image.Image;
//import javafx.scene.image.ImageView;
//import javafx.stage.FileChooser;
//import javax.imageio.ImageIO;
//import java.io.File;
//import java.io.IOException;
public class FXMLDocumentController implements Initializable {
// private ImageView imgview = new ImageView();
// private FileChooser filechooser = new FileChooser();
#FXML
private void handleButtonAction(ActionEvent event) {
//commented out because it displays nothing
// try {
// File infile = filechooser.showOpenDialog(null);
// Image img = SwingFXUtils.toFXImage(ImageIO.read(infile), null);
// imgview.setImage(img);
// } catch (IOException ex) {
// Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
// }
System.out.println("button clicked");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
And the XML:
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="355.0" prefWidth="411.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication2.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="14.0" layoutY="312.0" onAction="#handleButtonAction" text="open file" />
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="84.0" layoutY="73.0" pickOnBounds="true" preserveRatio="true" />
<Button layoutX="212.0" layoutY="310.0" mnemonicParsing="false" text="Button" />
</children>
</AnchorPane>
You aren't using the ImageView that you have created in the FXML, inside your controller.
You should assign the ImageView a fx:id and then inject it in the controller. This way the same ImageView will be used while setting the Image in the ImageView.
In FXML:
<ImageView fx:id="imgview" fitHeight="150.0" fitWidth="200.0"
layoutX="84.0" layoutY="73.0" pickOnBounds="true" preserveRatio="true" />
In Controller:
public class FXMLDocumentController implements Initializable {
#FXML
private ImageView imgview;
...
}
MCVE
FXML
<?import javafx.scene.control.Button?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="355.0" prefWidth="411.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="14.0" layoutY="312.0" onAction="#handleButtonAction" text="open file" />
<ImageView fx:id="imageView" fitHeight="150.0" fitWidth="200.0" layoutX="84.0" layoutY="73.0" pickOnBounds="true" preserveRatio="true" />
<Button layoutX="212.0" layoutY="310.0" mnemonicParsing="false" text="Button" />
</children>
</AnchorPane>
Controller
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.FileChooser;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FXMLDocumentController implements Initializable {
#FXML
private ImageView imageView;
private FileChooser filechooser = new FileChooser();
#FXML
private void handleButtonAction(ActionEvent event) {
try {
File infile = filechooser.showOpenDialog(null);
Image img = SwingFXUtils.toFXImage(ImageIO.read(infile), null);
imageView.setImage(img);
} catch (IOException ex) {
Logger.getLogger(TestController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I am aware that there are already answers for this question but somehow, it was not able to solve my problem.
When I click the textfield in IMAGE1, I want the keyboard FXML(IMAGE2) to appear as is in IMAGE3. But the thing is, I can't seem to find the solution. How do I do this?
I need your help please.
IMAGE1
IMAGE2
IMAGE3
I am experimenting with something similar, here is what I came up with (one of many possible solutions):
You need to wrap your main layout (IMAGE1) in a StackPane. Its usage is to overlay what needs be overlaid (the keyboard in your case). The keyboard is placed in another pane (a VBox in the following example). The VBox:
is placed in the StackPane after the main layout to sit on top of it
is given a maximum height, so that it doesn't fill the entire window
is given a translateY equal to the height
and bottom alignment
The relevant code n FXML:
<VBox fx:id="statusContainer" maxHeight="100.0" prefHeight="100.0"
translateY="100.0" StackPane.alignment="BOTTOM_LEFT" />
This will always be outside of the view. Toggling the keyboard requires 2 TranslateTransitions (can it be done with 1, I wonder?), one to move the keyboard up, one down.
The example code:
1) Java:
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Test1 extends Application
{
#FXML private VBox statusContainer;
private TranslateTransition showStatus;
private TranslateTransition hideStatus;
boolean showsStatus = false;
#Override
public void start(Stage primaryStage) {
try {
StackPane page = (StackPane) FXMLLoader.load(this.getClass().getResource("test1.fxml"));
Scene scene = new Scene(page);
primaryStage.setTitle(this.getClass().getName());
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
catch (IOException e) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
}
}
#FXML void initialize() {
showStatus = new TranslateTransition(Duration.millis(250), statusContainer);
showStatus.setByY(-100.0);
showStatus.setOnFinished(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
showsStatus = true;
}
});
hideStatus = new TranslateTransition(Duration.millis(250), statusContainer);
hideStatus.setByY(100.0);
hideStatus.setOnFinished(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
showsStatus = false;
}
});
}
public void toggleStatus() {
if( showsStatus ) {
showStatus.stop();
hideStatus.play();
}
else {
hideStatus.stop();
showStatus.play();
}
}
public static void main(String[] args) {
launch(args);
}
}
2) FXML (call it test1.fxml to match the code):
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="fancymsg.FancyMsg1">
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Button mnemonicParsing="false" onAction="#toggleStatus" text="Status" AnchorPane.leftAnchor="50.0" AnchorPane.topAnchor="100.0" />
</children>
</AnchorPane>
<VBox fx:id="statusContainer" maxHeight="100.0" prefHeight="100.0" translateY="100.0" StackPane.alignment="BOTTOM_LEFT" />
</children>
<stylesheets>
<URL value="#test1.css" />
</stylesheets>
</StackPane>
3) The CSS for the VBox to stand out (call it test1.css):
#statusContainer {
-fx-background-color: -fx-color;
}
An mcve version of this answer
can be found here
Is it possible to define the TabBar to place the tabs at bottom instead of top?
To set the side of the tabs use following snippet:
TabPane tabPane = new TabPane();
Tab tab1 = new Tab("Tab 1");
tab1.setContent(new Label("Tab1 content"))
tabPane.getTabs().add(tab1);
tabPane.setSide(Side.BOTTOM)
Now the content is above the tabs.
Also as full FXML example:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.web.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="example.MainViewController">
<bottom>
<HBox>
<children>
<Button fx:id="btnNewTab" mnemonicParsing="false" text="Add New Tab" onAction="#btnNewTabAction" />
</children>
</HBox>
</bottom>
<center>
<TabPane fx:id="tabPane" side="BOTTOM">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<AnchorPane id="Content">
<Label>Content 1</Label>
</AnchorPane>
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<AnchorPane id="Content">
<Label>Content 2</Label>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</center>
<top>
<Label text="TabPane Example" />
</top>
</BorderPane>
The main class:
package example;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class ExampleMain extends Application {
/**
* #param args
*/
public static void main(String[] args) {
Application.launch(ExampleMain.class, args);
}
#Override
public void start(Stage primaryStage) throws Exception {
URL location = ExampleMain.class.getResource("MainView.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
Parent root = (Parent) fxmlLoader.load(location.openStream());
// in case you need access to the controller
MainViewController mainViewController = fxmlLoader.getController();
primaryStage.setScene(new Scene(root, 1024, 768));
Scene s = primaryStage.getScene();
s.setRoot(root);
primaryStage.sizeToScene();
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the controller:
package example;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class MainViewController {
private static int counter = 0;
#FXML
private TabPane tabPane;
#FXML
public void btnNewTabAction() {
Tab tab = new Tab();
tab.setText("new Tab " + ++counter);
tab.setContent(new Label("Content of new tab " + counter));
tabPane.getTabs().add(tab);
}
}
as you can see in the example, fxml is an xml representation of the Java classes. If the class has an property side (getSide, setSide) then the class has in fxml an attribute side. So you can read the api documentation to find out which attributes are available in fxml as well.
Hope this helps.
Don't define the TabBar! Use a proper layout pane e.g. javafx.scene.layout.BorderPane.
Find attached examples for JavaFX 2.0 API and FXML:
JAVAFX 2.0 API
package tabtest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TabTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 300, 250);
TabPane tabPane = new TabPane();
Tab tab1 = new Tab("Tab 1");
tabPane.getTabs().add(tab1);
root.setBottom(tabPane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
For further information have a look at http://download.oracle.com/javafx/2.0/layout/jfxpub-layout.htm
FXML
package fxmltest;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FxmlTest extends Application {
public static void main(String[] args) {
Application.launch(FxmlTest.class, args);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
}
Sample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane>
<bottom>
<TabPane>
<tabs>
<Tab text="Tab 1" />
</tabs>
</TabPane>
</bottom>
</BorderPane>