I'm trying to set an image as the background of GridPane. I do not use fxml code so plain JavaFX code.
public Login() {
grid = new GridPane();
grid.setAlignment (Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25,25,25,25));
Image img = new Image("/src/application/Images/L.png");
ImageView imgView = new ImageView(getClass().getResource("/src/application/Images/L.png").toExternalForm());
imgView.setImage(img);
grid.getChildren().addAll(imgView);
scene = new Scene (grid, 300, 150);
The exception boils down to this snippet
> Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found
How do I fix this issue?
I removed src from the image path to get:
Image img = new Image("/application/Images/L.png");
and I added:
grid.setBackground(
new Background(
new BackgroundImage(
img,
BackgroundRepeat.REPEAT,
BackgroundRepeat.REPEAT,
BackgroundPosition.DEFAULT,
BackgroundSize.DEFAULT
)
)
);
and it works.
Related
I'm trying to make a card like the bootstrap CSS, but using JavaFX components. I want a rounded border but the background color of the top part (the header) is giving me problems.
The background overflows the border and looks quite ugly. I've googled a bit and found that an overflow:hidden on the background color should solve it. JavaFX css doesn't seem to have that though. Is there another way of solving this?
My solution so far:
As described in the JavaFX CSS Reference Guide, overflow is not supported.
JavaFX CSS does not support CSS layout properties such as float, position, overflow, and width. However, the CSS padding and margins properties are supported on some JavaFX scene graph objects. All other aspects of layout are handled programmatically in JavaFX code. In addition, CSS support for HTML-specific elements such as Tables are not supported since there is no equivalent construct in JavaFX.
However, to solve the rounded-background issue you can use -fx-background-radius along with -fx-border-radius. They should be the same value. You can find it here in the reference guide.
Here's an example of a bootstrap-like card that I think you are trying to make. You would use -fx-background-radius: <top-left> <top-right> <bottom-right> <bottom-left>; which would be -fx-background-radius: 10 10 0 0;
public class Card extends StackPane {
public BorderPane border = new BorderPane();
public StackPane header = new StackPane(), content = new StackPane();
public Card() {
setAlignment(Pos.CENTER);
getChildren().add(border);
border.setTop(header);
border.setCenter(content);
border.setStyle("-fx-border-color: cornflowerblue; -fx-border-radius: 10; ");
header.setStyle("-fx-background-color: derive(cornflowerblue, 70%); -fx-background-radius: 10 10 0 0; ");
header.setMinWidth(100);
header.setMinHeight(80);
content.setMinWidth(100);
content.setMinHeight(100);
}
public BorderPane getCard() {
return border;
}
public StackPane getHeader() {
return header;
}
public StackPane getContent() {
return content;
}
}
public void start(Stage stage) throws Exception {
Card card = new Card();
card.setPadding(new Insets(10,10,10,10));
GridPane grid = new GridPane();
grid.setVgap(10); grid.setHgap(10);
grid.setAlignment(Pos.CENTER);
grid.addRow(0, new Label("Username"), new TextField());
grid.addRow(1, new Label("Password"), new PasswordField());
grid.addRow(2, new Button("Submit"));
card.getContent().getChildren().add(grid);
Label title = new Label("Card Example");
title.setFont(Font.font("Tahoma", FontWeight.SEMI_BOLD, 36));
card.getHeader().getChildren().add(title);
StackPane stack = new StackPane();
stack.setAlignment(Pos.CENTER);
stack.getChildren().add(card);
Scene scene = new Scene(stack, 500, 300);
stage.setTitle("Boostrap-like Card Example");
stage.setScene(scene);
stage.show();
}
I'm trying to teach myself basic JavaFX by following the tutorials provided by Oracle.
In the BorderPane tutorial (https://docs.oracle.com/javafx/2/layout/builtin_layouts.htm) it specifies a background colour.
This is a snippet of my code:
/**
* This Method creates and defines a horizontal box with a button.
*/
public HBox addHorizontalBoxWithButton() {
// set up horizontal box and button
HBox hBox = new HBox();
hBox.setPadding(new Insets(10, 10, 10, 10));
hBox.setSpacing(10);
hBox.setStyle("-fx-background-colour: #FFFFFF;");
hBox.setAlignment(Pos.CENTER);
Button startButton = new Button("CLICK ME");
startButton.setPrefSize(100, 30);
// set up a message
Text message = new Text("Click the button to get started.");
message.setId("message");
hBox.getChildren().add(message);
hBox.getChildren().add(startButton);
return hBox;
}
I have tried various different background colours, none of which work. Am I missing something here?
Also, I am using a .css file but it only adds style to the 'message'.
The only problem with the original code is that you have a "typo" (anglification?) in your style setting. It should be
hBox.setStyle("-fx-background-color: #FFFFFF;");
not
hBox.setStyle("-fx-background-colour: #FFFFFF;");
Using an external style sheet with
#hbox {
-fx-background-color: red ;
}
is a better solution than using inline styles.
Okay I just solved this.
I changed my code like so:
/**
* This Method creates and defines a horizontal box with a button.
*/
public HBox addHorizontalBoxWithButton() {
// set up horizontal box and button
HBox hBox = new HBox();
hBox.setId("hBox");
hBox.setPadding(new Insets(10, 10, 10, 10));
hBox.setSpacing(10);
// hBox.setStyle("-fx-background-colour: #FFFFFF;");
hBox.setAlignment(Pos.CENTER);
Button startButton = new Button("CLICK ME");
startButton.setPrefSize(100, 30);
// set up a message
Text message = new Text("Click the button to get started.");
message.setId("message");
hBox.getChildren().add(message);
hBox.getChildren().add(startButton);
return hBox;
}
And I added this to the .css file:
#hBox {
-fx-background-color: linear-gradient(#04B45F, #81F79F);
}
I have an image which is displayed on my JavaFX application. Given the coordinates, I must display that part on the image using a rectangle. For example, if there is a textfield on the image and I give the coordinates of the textfield, a rectangle should appear over the textfield on the image (Just like highlighting it).
Drawing a rectangle is easy, but I'm having difficulty positioning it on the image. Please help.
You should use a parent component that does not layouts its children automatically. For this you can use Pane:
#Override
public void start( final Stage primaryStage )
{
ImageView imageView = new ImageView( ... );
// Optional: locating the image at iX-iY
// imageView.setX( iX );
// imageView.setY( iY );
Rectangle r = new Rectangle( rX, rY, width, height );
// Add rectangle at the last, so it shows up on the top of other children
Pane pane = new Pane( imageView, r );
final Scene scene = new Scene( pane, 400, 300 );
primaryStage.setScene( scene );
primaryStage.show();
}
You can use a StackPane for this.
StackPane stackPane = new StackPane();
ImageView imageView = ...;
stackPane.getChildren().add(imageView);
Rectangele rectangle = new Rectangle(x, y, width, height);
stackPane.getChildren().add(rectangle);
I have a toolbar with several buttons. I want several of this buttons to load different FXML-files. The way it is done now is by rwiting the fxml file in Java code and inserting it everytime it get's called. It would be a much better choice if I could just call the FXML-file and get the correct scene. This is an example where i load a settings view:
public void showModelSettings(){
clearPane();
GridPane gridPane = new GridPane();
ColumnConstraints cc1 = new ColumnConstraints();
cc1.setPercentWidth(50);
ColumnConstraints cc2 = new ColumnConstraints();
cc2.setPercentWidth(50);
gridPane.getColumnConstraints().addAll(cc1,cc2);
RowConstraints rc1 = new RowConstraints();
rc1.setPercentHeight(30);
RowConstraints rc2 = new RowConstraints();
rc2.setPercentHeight(70);
gridPane.getRowConstraints().addAll(rc1,rc2);
//iwModel.setImage(new Image("C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));
gridPane.setConstraints(cbModel, 0, 0);
gridPane.setConstraints(btnImageChooser, 1, 0);
gridPane.setConstraints(iwModel, 0, 1, 2, 1);
gridPane.getChildren().addAll(cbModel, btnImageChooser,iwModel);
mainPanel.getChildren().add(gridPane);
}
I have used tabpane at an earlier date, the handy thing with this is that it can load "content" which in a way is a actionlistener that can load fxml-files. I want this functionality for my toolbar buttons.
all help will be appreciated greatly!
Thanks :)
I think maybe I solved it, can't check yet because my project has several errors in other packages. But here is the code I believe will work:
private Parent replaceSceneContent(String fxml) throws Exception {
Parent page = (Parent) FXMLLoader.load(InventorySystem.class.getResource("/hist/inventory/gui/fxml/"+fxml), ResourceBundle.getBundle("MessageBundle",localSettings.getLocale()), new JavaFXBuilderFactory());
Scene scene = stage.getScene();
if(scene == null) {
scene = new Scene(page, 340, 280);
scene.getStylesheets().add("hist/inventory/gui/startStyle.css"); //Endre styles?
//stage.setResizable(false); //Må kanskje flyttes
stage.setScene(scene);
Organizer.getWindowFitter().setScene(scene);
} else {
stage.getScene().setRoot(page);
}
stage.sizeToScene();
return page;
}
public void setScene(String scene) throws Exception {
replaceSceneContent(scene);
}
How can I set the background image of a scene?
One of the approaches may be like this:
1) Create a CSS file with name "style.css" and define an id selector in it:
#pane{
-fx-background-image: url("background_image.jpg");
-fx-background-repeat: stretch;
-fx-background-size: 900 506;
-fx-background-position: center center;
-fx-effect: dropshadow(three-pass-box, black, 30, 0.5, 0, 0);
}
2) Set the id of the most top control (or any control) in the scene with value defined in CSS and load this CSS file into the scene:
public class Test extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.setId("pane");
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().addAll(this.getClass().getResource("style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
}
You can also give an id to the control in a FXML file:
<StackPane id="pane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="demo.Sample">
<children>
</children>
</StackPane>
For more info about JavaFX CSS Styling refer to this guide.
I know this is an old Question
But in case you want to do it programmatically or the java way
For Image Backgrounds; you can use BackgroundImage class
BackgroundImage myBI= new BackgroundImage(new Image("my url",32,32,false,true),
BackgroundRepeat.REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
BackgroundSize.DEFAULT);
//then you set to your node
myContainer.setBackground(new Background(myBI));
For Paint or Fill Backgrounds; you can use BackgroundFill class
BackgroundFill myBF = new BackgroundFill(Color.BLUEVIOLET, new CornerRadii(1),
new Insets(0.0,0.0,0.0,0.0));// or null for the padding
//then you set to your node or container or layout
myContainer.setBackground(new Background(myBF));
Keeps your java alive && your css dead..
You can change style directly for scene using .root class:
.root {
-fx-background-image: url("https://www.google.com/images/srpr/logo3w.png");
}
Add this to CSS and load it as "Uluk Biy" described in his answer.
In addition to #Elltz answer, we can use both fill and image for background:
someNode.setBackground(
new Background(
Collections.singletonList(new BackgroundFill(
Color.WHITE,
new CornerRadii(500),
new Insets(10))),
Collections.singletonList(new BackgroundImage(
new Image("image/logo.png", 100, 100, false, true),
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,
BackgroundSize.DEFAULT))));
Use
setBackground(
new Background(
Collections.singletonList(new BackgroundFill(
Color.WHITE,
new CornerRadii(0),
new Insets(0))),
Collections.singletonList(new BackgroundImage(
new Image("file:clouds.jpg", 100, 100, false, true),
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.DEFAULT,
new BackgroundSize(1.0, 1.0, true, true, false, false)
))));
(different last argument) to make the image full-window size.