I have a Pane Object where users can drag and drop various ImageViews. For this, I used
pane.getChildren(imageViewObject)
method
Now, after replacing Pane with ScrollPane, it does not have this method. So I don't know how to get arrount this issue.
Thank you in advance
you can specify only one node with ScrollPane. To create a scroll view with more than one component, use layout containers or the Group class.
Pane pane = ...;
ScrollPane sp = new ScrollPane();
sp.setContent(pane);
Example:
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* #author kachna
*/
public class Test extends Application {
#Override
public void start(Stage stage) throws Exception {
VBox root = new VBox();
root.getChildren().addAll(new Button("button1"), new Button("button2"), new Button("button3"));
root.setSpacing(10);
root.setPadding(new Insets(10));
ScrollPane sp = new ScrollPane();
sp.setContent(root);
sp.setPannable(true); // it means that the user should be able to pan the viewport by using the mouse.
Scene scene = new Scene(sp, 100, 100);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
I'm creating an app with javafx and I want to separate ui files.
Like: Tabs in separate file and just import and create new Tab in main app.
I have tried it, but when I try to set it on main app like borderPane.setCenter(tabPane); it says that The method setCenter(Node) in the type BorderPane is not applicable for the arguments (Tabs)
Main.java app code
import javafx.application.Application;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.*;
import javafx.stage.Stage;
import utils.Tabs;
public class Main extends Application {
#Override
public void start(Stage window) throws Exception {
Group root = new Group();
Scene scene = new Scene(root, 400, 250, Color.WHITE);
BorderPane borderPane = new BorderPane();
Tabs tabs = new Tabs();
// bind to take available space
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
borderPane.setCenter(tabs);
root.getChildren().add(borderPane);
window.setTitle("Computer Security — Demos");
window.setScene(scene);
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
Tabs.java
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.HBox;
public class Tabs extends TabPane {
public Tabs() {
TabPane tabPane = new TabPane();
Tab tab = new Tab("Tab: ");
HBox hbox = new HBox();
hbox.getChildren().add(new Label("Tab"));
hbox.setAlignment(Pos.CENTER);
tab.setContent(hbox);
tabPane.getTabs().add(tab);
}
}
I created a set of JavaFX components in a Scene which I'd like to display in a resizable modal dialog in a swing applications. The JavaFX components include ImageViews for scanned images which can get quite big dependening on the zoom level, so precise layouting in an issue. My options are afaik
displaying a JavaFX Dialog with showAndWait in a Platform.runLater and stop the Swing EDT with an invisible JDialog. That apparently causes deadlocks and is quite unelegant.
put the JavaFX components in a JFXPanel and display it in a JDialog. That works in terms of modality, but I have no idea how to layout components in the JFXPanel since in a GroupLayout the panel simply grows infinitely (JavaFX ScrollPane don't have any effect).
For example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class NewMain1 extends Application {
private final ImageView imageView;
public NewMain1() {
this.imageView = new ImageView(NewMain.class.getResource("/File_CC-BY-SA_3_icon_88x31.png").toString());
}
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
BorderPane borderPane = new BorderPane();
Button bottomButton = new Button("Some button");
ScrollPane imageViewScrollPane = new ScrollPane(imageView);
borderPane.setCenter(imageViewScrollPane);
borderPane.setBottom(bottomButton);
imageView.setSmooth(true);
imageView.setFitHeight(400);
StackPane root = new StackPane();
root.getChildren().add(borderPane);
stage.setScene(new Scene(root, 800, 600));
stage.show();
}
}
shows a well working ScrollPane for the ImageView whereas in a JFXPanel in a JDialog the scrolling/layout doesn't work:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class NewMain extends JFrame {
private static final long serialVersionUID = 1L;
private final JFXPanel mainPanel = new JFXPanel();
private final ImageView imageView;
private final JButton closeButton = new JButton("Close");
public NewMain() throws HeadlessException {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(0, 0, 800, 600);
setPreferredSize(new Dimension(800, 600));
GroupLayout layout = new GroupLayout(this.getContentPane());
this.getContentPane().setLayout(layout);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
this.imageView = new ImageView(NewMain.class.getResource("/File_CC-BY-SA_3_icon_88x31.png").toString());
Platform.runLater(() -> {
BorderPane borderPane = new BorderPane();
Button bottomButton = new Button("Some button");
ScrollPane imageViewScrollPane = new ScrollPane(imageView);
borderPane.setCenter(imageViewScrollPane);
borderPane.setBottom(bottomButton);
imageView.setSmooth(true);
imageView.setFitHeight(400);
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
root.getChildren().add(borderPane);
mainPanel.setScene(scene);
});
closeButton.addActionListener((event) -> {
setVisible(false);
});
layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(mainPanel)
.addComponent(closeButton));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mainPanel)
.addComponent(closeButton));
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new NewMain().setVisible(true);
});
}
}
Don't make the root of the Scene a Group, Groups are not resizable.
Just remove the group and use a resizable layout for the scene root (you already have a resizable layout in your sample code, it's the BorderPane, so you can just use that).
Instead of:
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
root.getChildren().add(borderPane);
Write:
Scene scene = new Scene(borderPane, Color.ALICEBLUE);
ScrollPane inside a JavaFX scene inside a JFXPanel inside a Swing JFrame.
Note, that in your pure JavaFX NewMain1 application, you use are already using a resizable pane as a root (a StackPane), so that is the reason for the discrepancy that you observed between the pure JavaFX version and the Swing embedded version.
When I run the following program
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;
public class Test1 extends Application {
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Pane topPane = new Pane();
Scene scene = new Scene(topPane, 600, 400);
StackPane sp = new StackPane();
Label l1 = new Label("1 2");
Ellipse e1 = new Ellipse(100, 50);
e1.setOpacity(0.5);
sp.getChildren().addAll(l1, e1);
e1.radiusXProperty().bind(l1.widthProperty());
e1.radiusYProperty().bind(l1.heightProperty());
topPane.getChildren().add(sp);
sp.relocate(200, 100);
sp.setStyle("-fx-border-color: RED;");
Platform.runLater(() -> {
//l1.setText("123");
//l1.setText("1 2");
});
stage.setScene(scene);
stage.show();
}
}
I get a red box surrounding the text label only, but when I uncomment the two lines inside the Platform.runLater() block above, I get a red box surrounding the outer ellipse, which is what I want.
So it seems to me the layout bounds of the stack pane is not set correctly from the model description, since the bounds are determined only from the label control. But when I force an invalidation in Platform.runLater() the layout bounds are where they should be.
Why is this happening and how do I prevent it? I would like to be able to just specify my model/graph and then it should render correctly on the first show, or?
add this sp.requestLayout(); after stage.Show();
HiEveryone,
I'm new in JavaFx and my TextField shows at the middle of the frame but not at the top's position. Where am i suppose to be wrong? pls help..
Have a look into this screenshot..
But i want to set that TextField at the top ..
Here is Source code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.control.TextField;
public class Main extends Application {
#Override
public void start (Stage primaryStage){
primaryStage.setTitle("Modern web browser.");
WebView wv = new WebView();
WebEngine we = wv.getEngine();
we.load("http://www.google.com/");
TextField tf = new TextField("http://www.google.com/");
tf.setMaxHeight(Double.MIN_VALUE);
GridPane sp = new GridPane();
sp.getChildren().add(wv);
sp.getChildren().add(tf);
Scene scene = new Scene(sp, 600, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Please help.. Thanks in Advanced!
EDITED
As #Nagesh Kumar answered me after using VBox getting this error:
Change your layout to VBox from GridPane as follows
VBox vbox = new VBox();
Now first add your TextField first so that it will be on top as follows
vbox.getChildren().add(tf);
then a WebView as follows
vbox.getChildren().add(wv);
Edit:
Yes you can try this
VBox vbox = new VBox(5);
5 pixel space between controls put in VBox
HiEveryone,
I'm new Javafx and trying to change the float of this button as to Right side from the current Left side.. How to do that?
I'm using simply Pane as a container at the moment.
Have a look into this screenshot:
How to do that? ..pls help
Thanks in advance!
EDITED
Source code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
public class Main extends Application {
#Override
public void start (Stage primaryStage){
primaryStage.setTitle("Modern web browser made by Rajendra arora.");
WebView wv = new WebView();
wv.setLayoutX(0.0);
wv.setLayoutY(40.0);
wv.setPrefHeight(Double.MAX_EXPONENT);
wv.setPrefWidth(Double.MAX_EXPONENT);
WebEngine we = wv.getEngine();
we.load("http://www.google.com/");
Button btn=new Button("Go");
TextField tf = new TextField("http://www.google.com/");
tf.setLayoutX(1.0);
tf.setPrefWidth(Double.MAX_EXPONENT);
tf.setPrefHeight(25.0);
Pane sp = new Pane();
sp.getChildren().add(tf);
sp.getChildren().add(btn);
sp.getChildren().add(wv);
Scene scene = new Scene(sp, 600, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Use a HBox to hold the textfield and button, later add it to the Pane
HBox hbox = new HBox();
hbox.getChildren().addAll(tf, btn);
Pane sp = new Pane();
sp.getChildren().add(hbox);
sp.getChildren().add(wv);