JavaFX add objects in TilePane horizontally (TilePane inside a ScrollPane) - java

I need help inserting objects in a TilePane (contained within a ScrollPane) horizontally. It inserts horizontally until it reaches the end of the ScrollPane then starts adding to the next row of the ScrollPane. This is what it looks like:
The box is the ScrollPane and the TilePane is what is holding all the images.
Basically, I want the TilePane to keep adding to the right and have the ScrollPane show a horizontal scrollbar.
Here's my code:
private void start()
{
#FXML private ImageView bigImage;
#FXML private ScrollPane scrollPane;
#FXML private TilePane tilePane;
// Setup scrollpane
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
tilePane.setHgap(15);
for(int i = 0; i < 10; i++)
{
ImageView imageView = new ImageView(bigImage.getImage());
imageView.setFitWidth(100);
imageView.setFitHeight(100);
tilePane.getChildren().add(imageView);
}
//scrollPane.setFitToWidth(true);
scrollPane.setContent(tilePane);
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.TilePane?>
<AnchorPane prefHeight="700.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.PhotoController">
<children>
<ImageView fx:id="bigImage" fitHeight="441.0" fitWidth="534.0" layoutX="35.0" layoutY="52.0" pickOnBounds="true">
<image>
<Image url="#../../../../../../Pictures/Wallpaper02.jpg" />
</image>
</ImageView>
<ScrollPane fx:id="scrollPane" layoutX="35.0" layoutY="528.0" prefHeight="140.0" prefWidth="820.0">
<content>
<TilePane fx:id="tilePane" prefHeight="137.0" prefWidth="817.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>
How can I accomplish what I want to do? Any help would be appreciated. Thank you!

you can use the ccs property "repeat" with your background like this, it will do all the work :
-fx-background-image:url("Image.png");
-fx-background-repeat:repeat;
For more modification looks in the Docs with the background properties.

Related

JavaFX Scene width and height not working properly

I have this code, which launches a stage in FX:
public class ApplicationStart extends Application {
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/frames/login.fxml"));
LoginController loginController = new LoginController();
loader.setController(loginController);
Parent root = loader.load();
stage.setTitle("Login");
stage.setScene(new Scene(root, 600, 400));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
In the login.fxml file, the Pane has the width of 600, and height of 400. And in the code above, I set the width and height of the Scene accordingly.
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1">
But when I launch the application, the width and height are totally messed up, they are way bigger, like this. I tried to reduce the width and height in the code above, trying to debug what is happening, to something like Scene(root, 400, 200). Now it looked ok, but when I clicked on the "Register" button, which is the lower most button, the button doesn't respond, like if I would click outside the window (if I have intellij in the background, for example, and i click the button, the intellij window comes first, and the app window goes back). It's like the app window has some visible bounds, and some actual bounds. The visible bounds are something like width + 200 height + 200, and the actual logical bounds are the exact width and height I set. What can I do to solve this? Here's the entire fxml file.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?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/15.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextField layoutX="357.0" layoutY="131.0" />
<PasswordField layoutX="357.0" layoutY="187.0" />
<Label layoutX="310.0" layoutY="136.0" text="Email:" />
<Label layoutX="285.0" layoutY="191.0" text="Password:" />
<Button layoutX="357.0" layoutY="260.0" mnemonicParsing="false" prefHeight="32.0" prefWidth="152.0" style="-fx-background-color: #25b2fd;" text="Log In" />
<ImageView fx:id="logoImageView" fitHeight="230.0" fitWidth="324.0" layoutX="14.0" layoutY="85.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../images/logo.png" />
</image>
</ImageView>
<ImageView fx:id="lockImageView" fitHeight="51.0" fitWidth="53.0" layoutX="408.0" layoutY="60.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../images/lock.png" />
</image>
</ImageView>
<Button layoutX="357.0" layoutY="307.0" mnemonicParsing="false" prefHeight="32.0" prefWidth="152.0" style="-fx-background-color: #25b2fd;" text="Register" />
</children>
</Pane>
And here's the LoginController class, but I doubt it will help, it doesn't have much in it other than initializing the images:
public class LoginController implements Initializable {
#FXML
private ImageView logoImageView = new ImageView();
#FXML
private ImageView lockImageView = new ImageView();
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
File logoFile = new File("images/logo.png");
Image logoImage = new Image(logoFile.toURI().toString());
logoImageView.setImage(logoImage);
File lockFile = new File("images/lock.png");
Image lockImage = new Image(lockFile.toURI().toString());
lockImageView.setImage(lockImage);
}
}

JavaFx Pane in Stack not responding to MouseTransparent or PickOnBounds

I have a SplitPane and a Pane together in a stack. The Pane is underneath the SplitPane in the stack, and the middle SplitPane is a transparent AnchorPane. My intention is for an event to fire which draws a circle on the underlying Pane when I click somewhere within the area of the center pane, but I'm unable to get the event to fire by clicking on the pane.
(EDIT:This mouse event should come from the Pane, not from the anchorpane, because I also need the drawn shapes to respond to clicks.)
I have read posts on here about this and most solutions include MouseTransparent and PickOnBounds. I have tried what feels like every combination of those properties on the central AnchorPane, its label child, and the underlying Pane where the circle needs to be drawn to no avail. Any help is welcome! :)
Here are two images of both the physical layout and the hierarchy in scene builder. The blue showing is the underlying Pane. It is visible because the central AnchorPane is transparent.
Update: You can use setMouseTransparent(true/false) for the foreground split pane when entering/exiting the center anchor pane with the mouse like e. g. this:
Controller Class:
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
public class Controller {
#FXML
private Pane
backgroundPane;
#FXML
private SplitPane
foregroundSplitPane;
#FXML
public void handleBackgroundPaneOnMouseClick() {
// Create and add an ellipse:
Ellipse ellipse = new Ellipse();
ellipse.setRadiusX(50);
ellipse.setRadiusY(50);
ellipse.setFill(Color.BLACK);
ellipse.setLayoutX((backgroundPane.getWidth() / 2));
ellipse.setLayoutY((backgroundPane.getHeight() / 2));
backgroundPane.getChildren().add(ellipse);
}
#FXML
public void handleCenterAnchorPaneOnMouseEntered() {
foregroundSplitPane.setMouseTransparent(true);
}
#FXML
public void handleCenterAnchorPaneOnMouseExited() {
foregroundSplitPane.setMouseTransparent(false);
}
}
FXML File:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>
<StackPane prefHeight="150.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Pane fx:id="backgroundPane" onMousePressed="#handleBackgroundPaneOnMouseClick" style="-fx-background-color: blue;" />
<SplitPane fx:id="foregroundSplitPane" dividerPositions="0.1, 0.9" style="-fx-background-color: rgba(255,255,255,0);">
<items>
<AnchorPane style="-fx-background-color: tomato;" />
<AnchorPane onMouseEntered="#handleCenterAnchorPaneOnMouseEntered" onMouseExited="#handleCenterAnchorPaneOnMouseExited" style="-fx-background-color: rgba(255,255,255,0);" />
<AnchorPane style="-fx-background-color: tomato;" />
</items>
</SplitPane>
</children>
</StackPane>
Preview:

How to align HBox by using BorderPane alignment in FXML?

What am i trying is to align HBox Buttons to center in the Bottom in dialog box.
I want to do this in fxml.However,BorderPane alignment is working in label.
Here is code from my side.I think BorderPane.alignment="BOTTOM_CENTER" must work even if the tag is Bottom.
Class file:
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HBoxDialog extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("HBoxDialog.fxml"));
primaryStage.setScene(new Scene(root, 500, 100));
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">
<top>
<Label text="this is dialogbox" BorderPane.alignment="TOP_CENTER"/>
<font>
<Font size="35"/>
</font>
</top>
<bottom>
<HBox spacing="10">
<Button text="Okay" prefWidth="90" BorderPane.alignment="BOTTOM_CENTER"/>
<Button text="Cancel" prefWidth="90" BorderPane.alignment="BOTTOM_CENTER"/>
<Button text="Help" prefWidth="90" BorderPane.alignment="BASELINE_RIGHT"/>
</HBox>
</bottom>
</BorderPane>
The BorderPane.alignment static property only makes sense for nodes whose parent is a BorderPane. The Buttons defined in your FXML file have an HBox as a parent, so setting the BorderPane.alignment property on the buttons will have no effect.
You can achieve the desired effect by centering the buttons within the HBox, simply by using the alignment property of the HBox (which positions the HBox's child nodes within its bounds):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">
<top>
<Label text="this is dialogbox"
BorderPane.alignment="TOP_CENTER" />
<font>
<Font size="35" />
</font>
</top>
<bottom>
<HBox spacing="10" alignment="CENTER">
<Button text="Okay" prefWidth="90" />
<Button text="Cancel" prefWidth="90" />
<Button text="Help" prefWidth="90" />
</HBox>
</bottom>
</BorderPane>
This gives
The reason that the Label needs BorderPane.alignment="CENTER" but the HBox needs alignment="CENTER" is because they have different resizable ranges, and in particular their max widths are different. The max width of a label, by default, is its preferred width, whereas the max width of an HBox is infinite. You can see this by setting background colors on them both:
<Label text="this is dialogbox"
BorderPane.alignment="TOP_CENTER"
style="-fx-background-color: aquamarine;"/>
<!-- ... -->
<HBox spacing="10" alignment="CENTER"
style="-fx-background-color: lightskyblue;">
The alignment property positions the content of a node within its bounds. Since the label has no extra space within its bounds for the text to be positioned, with the default settings the alignment property will have no effect. On the other hand, the label is less wide than the top region of the border pane, so there is room to position it within that region. The BorderPane.alignment="CENTER" attribute centers the entire label within the top region of the border pane.
By contrast, the HBox itself already fills the entire width of the bottom region of the border pane. So there is no additional space to align it within that region, and so for the HBox, setting BorderPane.alignment="CENTER" will have no effect. On the other hand, there is more space in the HBox itself than is needed for the buttons, so the buttons (the content of the HBox) can be aligned within the HBox itself using the alignment="CENTER" property of the HBox.
If you want, you can change the max widths to achieve the same effect. For example:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.Double?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">
<top>
<Label text="this is dialogbox"
alignment="CENTER"
style="-fx-background-color: aquamarine;">
<maxWidth>
<Double fx:constant="MAX_VALUE"/>
</maxWidth>
</Label>
<font>
<Font size="35" />
</font>
</top>
<bottom>
<HBox spacing="10" alignment="CENTER"
style="-fx-background-color: lightskyblue;">
<Button text="Okay" prefWidth="90" />
<Button text="Cancel" prefWidth="90" />
<Button text="Help" prefWidth="90" />
</HBox>
</bottom>
</BorderPane>
allows the label to grow (like the default for the HBox), so now its alignment property has the desired effect:
or
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Region?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">
<top>
<Label text="this is dialogbox"
BorderPane.alignment="CENTER"
style="-fx-background-color: aquamarine;" />
<font>
<Font size="35" />
</font>
</top>
<bottom>
<HBox spacing="10" BorderPane.alignment="CENTER"
style="-fx-background-color: lightskyblue;">
<maxWidth>
<Region fx:constant="USE_PREF_SIZE" />
</maxWidth>
<Button text="Okay" prefWidth="90" />
<Button text="Cancel" prefWidth="90" />
<Button text="Help" prefWidth="90" />
</HBox>
</bottom>
</BorderPane>
makes the HBox behave like the button, so now its BorderPane.alignment gives the desired effect:

JavaFX FXML: Expand ScrollPane to Fit height of its Content Pane Until it reahces its MaxHeight property

I have the following FXML view:
VBox
ScrollPane
VBox buttonsContainer
Button (Adds a new button to buttonsContainer)
I want the ScrollPane to expand its height to match its child vbox's height, until it reaches a certain height [200px for example] then it stops expanding.
I've been playing around for the past 1 hour with the Min/Pref Viewport Height, and Min/Max/Pref Height properties to achieve this, but nothing worked out.
Is this this possible to do?
Edit: Here's a minimal, complete, and verifiable example :
MainView.fxml
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.VBox?>
<VBox alignment="CENTER" prefHeight="0.0" prefWidth="200.0" spacing="5.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
<ScrollPane maxHeight="200.0" VBox.vgrow="ALWAYS">
<VBox fx:id="_buttonsContainer" />
</ScrollPane>
<Button fx:id="_btnAddButton" mnemonicParsing="false" text="Button" />
</VBox>
MainController.java
public class MainController implements Initializable{
#FXML private Button _btnAddButton;
#FXML private VBox _buttonsContainer;
#Override
public void initialize(URL location, ResourceBundle resources) {
_btnAddButton.setOnAction(e -> {
addButton();
});
}
private void addButton(){
_buttonsContainer.getChildren().add(new Button());
}
}
This seems to work:
<ScrollPane fx:id="scrollPane" maxHeight="200.0" minViewportHeight="0.0" minHeight="0.0">
<VBox fx:id="_buttonsContainer" />
</ScrollPane>
The scroll pane, and its viewport, seem to have some fixed positive minimum height by default.
ScrollPane.prefHeightProperty().bind(VBox.heightProperty());
then add ScrollPane.setMaxHeight(200); try this

JavaFX: Add MapView to VBox

I want to add a MapView from JXMaps to the VBox in JavaFX, i tried to add the MapView to the border panel and then added to the VBox, but i canĀ“t find any solution to this, i hope you can help me, this is my code:
public class ControlerMap
{
#FXML private BorderPane borderPanel;
#FXML private Button butom;
#FXML VBox cosa;
#FXML public void initialize()
{
MapView sample = new MapView();
sample.setMaxHeight(394.0);
sample.setPrefWidth(704.0);
sample.setVisible(true);
borderPanel = new BorderPane(sample);
borderPanel.setVisible(true);
borderPanel.setLayoutX(76.0);
borderPanel.setLayoutY(134.0);
borderPanel.setPrefHeight(200.0);
borderPanel.setPrefWidth(467.0);
cosa.getChildren().add(borderPanel);
}
}
And here is my code from the .FXML file:
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="496.0" prefWidth="757.0"
xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="prueba.web.googleMap.ControlerMap">
<children>
<Button fx:id="butom" layoutX="25.0" layoutY="14.0"
mnemonicParsing="false" text="Button" />
<VBox fx:id="cosa" layoutX="32.0" layoutY="68.0" prefHeight="394.0"
prefWidth="704.0">
<children>
<BorderPane fx:id="borderPanel" prefHeight="400.0"
prefWidth="704.0" />
</children>
</VBox>
</children>
</AnchorPane>
As I can see you created empty MapView.
MapView sample = new MapView();
Maps will be actually drawn only after initialization of its properties (at least zoom and center). You have to set it in following way:
sample.setOnMapReadyHandler(new MapReadyHandler() {
#Override
public void onMapReady(MapStatus status) {
if (status == MapStatus.MAP_STATUS_OK) {
final Map map = mapView.getMap();
map.setCenter(new LatLng(35.91466, 10.312499));
map.setZoom(2.0);
}
}
});

Categories

Resources