I've tried stretch height and width out but only width can show text horizontally, not vertically.
Below is what I've tried.
Label label5 = new Label("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
HBox hbox5 = new HBox();
label5.setMinHeight(Region.USE_COMPUTED_SIZE);
hbox5.getChildren().add(label5);
hbox5.setAlignment(Pos.TOP_CENTER);
hbox5.setMinHeight(Region.USE_COMPUTED_SIZE);
but It seems doesn't work.
Please let me know if I missed something Thank you!
you can wrapText(true) and rotate(90.0) your Label and worry less about the rest?
Label l = new Label("some long text goes here - ");
l.setWrapText(true);
l.setRotate(90.0);
The key is making sure you use a Monospaced font.
Code Version:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication42 extends Application {
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Label label = new Label("Hello World");
label.setFont(Font.font("Monospaced"));
label.setWrapText(true);
label.setMinWidth(1);
label.setPrefWidth(1);
label.setMaxWidth(1);
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML Version:
?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="296.0" layoutY="81.0" prefHeight="198.0" prefWidth="0.0" text="HELLO WORLD" wrapText="true" />
</children>
</Pane>
Related
I have a TextArea inside of a ScrollPane. I have set the TextArea nodeOrientation="RIGHT_TO_LEFT". When I do this the scrollbars go on the left side of the window instead of the right side, which I assume is default. How do I force the scrollbars to the right side of the window?
I have tried setting the nodeOrientation of my AnchorPane and ScrollPane to left to right but that did not help
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.mycompany.mycalc.MyCalcHistoryController">
<children>
<ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" prefHeight="242.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<TextArea fx:id="txtHistory" editable="false" nodeOrientation="RIGHT_TO_LEFT" />
</content>
</ScrollPane>
</children>
</AnchorPane>
I used BorderPane instead of AnchorPane and did not use a fxml file. Here is my code and after the code is a screen capture. As you can see, setting the node orientation for the TextArea only does not alter the location of the scroll bar on the ScrollPane.
import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class FxTest00 extends Application {
#Override
public void start(Stage stage) throws Exception {
TextArea txtAr = new TextArea("myxomatosis");
txtAr.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
ScrollPane scrollPane = new ScrollPane(txtAr);
scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS);
BorderPane root = new BorderPane();
root.setCenter(scrollPane);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
EDIT (after Ray_White's initial comment to my answer)
The scrollbar you are referring to (in your comment) is part of TextArea and not related to the ScrollPane parent. In the below code, the TextArea is added directly to the BorderPane, i.e. the below code contains no ScrollPane.
The way I found to remove the TextArea vertical scrollbar is via the TextArea style. I created a CSS file named scrolbar.css. Here is its contents:
.text-area .scroll-pane {
-fx-vbar-policy: never;
}
And here is the modified code, including your suggestion to add text to the TextArea to force scrolling.
import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class FxTest00 extends Application {
#Override
public void start(Stage stage) throws Exception {
TextArea txtAr = new TextArea("myxomatosis");
txtAr.appendText("\n");
txtAr.appendText("One");
txtAr.appendText("\n");
txtAr.appendText("Two");
txtAr.appendText("\n");
txtAr.appendText("Three");
txtAr.appendText("\n");
txtAr.appendText("Four");
txtAr.appendText("\n");
txtAr.appendText("Five");
txtAr.appendText("\n");
txtAr.appendText("Six");
txtAr.appendText("\n");
txtAr.appendText("Seven");
txtAr.appendText("\n");
txtAr.appendText("Eight");
txtAr.appendText("\n");
txtAr.appendText("Nine");
txtAr.appendText("\n");
txtAr.appendText("Ten");
txtAr.appendText("\n");
txtAr.appendText("Eleven");
txtAr.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
BorderPane root = new BorderPane();
root.setCenter(txtAr);
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("scrolbar.css").toString());
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And here is the screen capture of the modified GUI. As you can see, no scrollbar.
I am trying to place my two button directly under my label and have everything centered on my form. Currently everything is just printed on one line.
#Override
public void start(Stage primaryStage) throws Exception{
HBox hb = new HBox();
hb.setSpacing(15);
hb.setPadding(new Insets(15, 20, 5, 10));
hb.setAlignment(Pos.CENTER);
Label label = new Label("Greetings! Would you like to purchase cruise ticket for a family of two?");
hb.getChildren().add(label);
button1 = new Button("Yes");
hb.getChildren().add(button1);
button1.setOnAction(this);
button2 = new Button("No");
hb.getChildren().add(button2);
button2.setOnAction(this);
Scene scene = new Scene(hb, 550, 250);
primaryStage.setTitle("Cruise for two!");
primaryStage.setScene(scene);
primaryStage.show();
}
For more information on the many layout options available in JavaFX, Oracle provides a great tutorial that I recommend you review!
The HBox will always arrange its children in a horizontal row. By adding your Label to the HBox, JavaFX is doing what you're telling it to.
You also have a VBox, which arranges nodes vertically. Within the VBox, add your Label and then your HBox; they will be arranged with the HBox under the Label.
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.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
private Button button1;
private Button button2;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
HBox hb = new HBox();
hb.setSpacing(15);
hb.setPadding(new Insets(15, 20, 5, 10));
hb.setAlignment(Pos.CENTER);
Label label = new Label("Greetings! Would you like to purchase cruise ticket for a family of two?");
root.getChildren().add(label);
button1 = new Button("Yes");
hb.getChildren().add(button1);
button2 = new Button("No");
hb.getChildren().add(button2);
root.getChildren().add(hb);
Scene scene = new Scene(root, 550, 250);
primaryStage.setTitle("Cruise for two!");
primaryStage.setScene(scene);
primaryStage.show();
}
}
RESULT:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<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>
<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity">
<children>
<Label text="Label" />
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity">
<children>
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" text="Button" />
</children>
</HBox>
</children>
</VBox>
</children>
</StackPane>
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);
});
}
}
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>