How to create an inner popup in JavaFX styled with FXML - javafx

I have an FXML file that I'm using to allow user input when requested. Right now I just put it in a new stage and do Stage.show(). I would like to not have it appear in a new window and behave more like a ContextMenu.
Looking at ContextMenu class it doesn't appear that I can set the content based off an FXML file. Is there a way to do this either with ContextMenu or Popup or some other class I am unaware of?

Although that library is quite nice, I wanted something simple that didn't require 3rd party downloads. I came up with this:
Popup popup = new Popup();
CustomController controller = new CustomController();
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlfile));
loader.setController(controller);
popup.getContent().add((Parent)loader.load());
The problem was I didn't realize that a Parent could be considered a Node for the method Popup#getContent#add

ControlsFX has a PopOver control you might like. That PopOver can use any Node for its content, so you can simply create a popover, load a node from FXML and set the content of the popover to that node.

Related

javafx deleting contents of an accordion pane

I have an accordion pane which contains three titled panes. I wish to delete these in the java program, however the Accordion object doesn't seem to have a clear or remove method to do this.
I have tried some ways to get around this such as the following:
if (!measureAccordion.getChildrenUnmodifiable().isEmpty()) {
ObservableList<javafx.scene.Node> accordionContent = measureAccordion.getChildrenUnmodifiable();
accordionContent.clear();
}
But this raised an UnsupportedOperationException.
If you check here accordion in javaFX , you will see that the accordion object has a method, getPanes(), which returns an ObservableList of TitledPane. The ObservableList has a lot of methods that you could use such as removeAll. You can see here the documentation for ObservableList.
Accordion is a control that can contain only TitledPane components. So if you want to modify content of Accordion then use Accordion#getPanes method.

JavaFX - How to load a specific AnchorPane's contents from an FXML file?

I'm trying to make an application which switches between scenes back and forth however I need to load a specific AnchorPane's contents into another AnchorPane when the scene switches back. For Example:
In my FXML1, I have a hierarchy that looks like this:
AnchorPane0
----SplitPane
--------AnchorPane1
--------AnchorPane2
In FXML2 the hierarchy is just this:
AnchorPane0
So I load FXML1, then I have a button that switches scenes loading FXML2.AnchorPane0 into FXML1.AnchorPane2. I have a back button in FXML2.AnchorPane0 that needs to load the original scene of FXML1.AnchorPane2 into FXML1.AnchorPane2. Right now my back button loads all 4 containers of FXML1 into FXML1.AnchorPane2. So my questions is, how do I load a specific container's contents preferably without making FXML1.AnchorPane2 its own FXML? Do I need to write a get method for the FXML1.AnchorPane2 to access its contents or is there a way to return an AnchorPane with all of its contents in place already?
I found the solution as shown below:
AnchorPane loader = FXMLLoader.load(getClass().getResource("myFXML.fxml"));
SplitPane spane = (SplitPane) loader.getChildren().get(0);
AnchorPane pane = (AnchorPane) spane.getItems().get(1);
foregroundAnchorPane.getChildren().setAll(pane);

How to create a dialog using JFXDialog of JFoenix in JavaFX

i search for an example for jfoenix jfxdialog anybody has working demo of this
JFXDialog dialog = new JFXDialog();
JFXDialog has three different constructors:
JFXDialog(),
JFXDialog(StackPane dialogContainer, Region content, DialogTransition transitionType) and
JFXDialog(StackPane dialogContainer, Region content, DialogTransition transitionType, boolean overlayClose)
The first one just sets the animationType to Center.
The second one sets the Parent(dialogContainer), the content(content) and the animationType(transitionType).
The third one sets the same as the second one + if the dialog should close if you click on the overlay(overlayClose).
For the parent of the Dialog you need a StackPane.
For the content you can use anything which is a child, grandchild, ... of Region. I would suggest you to use a JFXDialogLayout as it extends StackPane and makes it easier to style you dialog.
For the transitionType you have five different ones:
DialogTransition.TOP
DialogTransition.RIGHT
DialogTransition.BOTTOM
DialogTransition.LEFT
DialogTransition.CENTER
If you want to close it by clicking on the overlay set overlayClose to true, else set it to false
Some usefull methods which JFXDialog has:
setDialogContainer(StackPane dialogContainer) sets the Parent.
setContent(Region content) sets the Content of your Dialog.
setOverlayClose(final boolean overlayClose) you set wheter you want to close the Dialog by clicking on the overlay or not.
show(StackPane dialogContainer) shows the JFXDialog in the given StackPane
show() shows the JFXDialog in its parent
close() closes the JFXDialog
setTransitionType(DialogTransition transition) sets the DialogTransition to one of those mentioned before
setOnDialogClosed(EventHandler<? super JFXDialogEvent> handler) Defines a function to be called when the dialog is closed. It will be triggered after the close animation is finished.
setOnDialogOpened(EventHandler<? super JFXDialogEvent> handler) Defines a function to be called when the dialog is opened. It will be triggered after the show animation is finished.
JFXDialogLayout has just an empty constructor but contains out of a heading, body and actions.
The JFXDialogLayout class provides a setter for all those parts. Those are:
setHeading(Node... titleContent
setBody(Node... body)
setActions(Node... actions)
If you don't know, because of the three dots after Node you can add unlimited Nodes to all three parts. This is a feature called Varargs
For further information take a look at the demo on github at the Java controller JFoenix/Dialog Container and at the FXML file JFoenix/JFXDialog.fxml
Also here is the source code of the controls containing JFXDialog and JFXDialogLayout JFoenix/controls
I would suggest you to write your JavaFX applications seperated in Java, FXML and CSS files. Why Use FXML

What is the justification for JavaFX FXML schema not supporting context menu inside the panes?

It is possible to add a context menu to a scroll pane, but not to other types of panes. Why?
How FXML Works
FXML works by introspecting on the Java API using reflection (or by using specialized builder classes). More information on FXML works can be found in the Introduction to FXML documentation.
Why ContextMenus can't be defined on Panes in JavaFX using FXML Markup
Control has a contextMenu property. A ScrollPane is a Control. Other pane types such as StackPane are not controls. As there is no corresponding property in these other pane types which could be set to contain a reference to a contextMenu, you can't define a contextMenu on these pane types using FXML.
For similar reasons, you can't define a Tooltip on a Pane either.
How to define a ContextMenu for a Panes in an FXML Controller
You can still set a context menu on panes (and any other arbitrary nodes which are not controls) via code, using the contextMenu show API, for example by placing the following code in your FXML controller.
#FXML StackPane stack;
// . . .
public void initialize() {
final ContextMenu contextMenu = new ContextMenu(new MenuItem("xyzzy"));
stack.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
contextMenu.show(
stack,
mouseEvent.getScreenX(),
mouseEvent.getScreenY()
);
}
});
}
Why not add a ContextMenu property
Node could have a contextMenu property, which would allow ContextMenus to be defined on Panes via FXML Markup.
The reason why Node does not have a contextMenu property but Control does is because ContextMenu is itself a Control. Adding a ContextMenu property to node would mean that the core scene graph model code for the JavaFX implementation would have a dependency on the controls module (which would have a dependency on the scene graph module), hence a circular dependency. This would prevent the shipping of a very light Java runtime system which included the core JavaFX scene graph and rendering engine but did not include controls (not that anybody ships such a system today).
How to File Feature Requests
If you think the system should be changed to allow definition of context menus on arbitrary panes using SceneBuilder, then you can file a feature request against the JavaFX issue tracker (if you do so, include a link back to this question in the feature request).
Described method to open popup leads to multiple popups open if every node in the scene graph want to open context menu. Consuming of event is definitely needed.
See also discussion at Using FXML to Create ContextMenu within a Pane It provides working answer to this problem.
BTW, Node.onContextMenuRequested(...) should be used instead, yes?

Make a javafx stage the owner of a JDialog?

Display a swings JDialog containing a JRViewer for Jasper Report, from within a javafx application menu item click. BUT the JDialog is not MODAL even after setModal(true) as it is not owned by javafx stage. How to make a javafx stage the owner of a JDialog? Alternatively how to display a Jasper report inside a javafx stage, scene?
Don't use a JDialog. In JavaFX you use Stages. Put your Jasper report inside a Scene, put the Scene in a Stage. I think you can't put Swing components inside JavaFX components, so you must check this link: Integrating JavaFX into Swing Applications
Code to make a JavaFX dialog:
Stage stage = new Stage();
stage.setTitle("Title");
stage.setResizable(false);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(primaryStage);
stage.initStyle(StageStyle.UTILITY);
(...)
Scene scene = new Scene(...);
stage.setScene(scene);
In the code above the Stage will behave exactly like a dialog.
Also check this:
How to create a JavaFX dialog?
Hello World, JavaFX Style
Back to the first (base) question: It's not possible to make a Stage the owner of a JDialog. But, after setting the content of the SwingNode
swingNode.setContent(xxx);
you can get the parent of xxx (may be the parent of the parent of xxx too...) until you find a (AWT-) Frame or (AWT-) Dialog. In the case of SwingNode it's a JLightweightFrame. This object you can use as the owner to create your JDialog.
But, I think there is a bug in the JavaFX SwingNode mechanism. The JDialog appears functionally modal, if you set it modal (setModal(true)), but it may appear behind the main (JavaFX) window. It's still possible to move the main window, to bring it in front and so on, what should not be possible if there is a modal dialog. But this is another topic.
To view a Jasper Report in javafx ( jdk 1.8> ) stage
JasperPrint jp = JasperFillManager.fillReport(reportsource, params,getCon());
SwingNode swingNode = new SwingNode();
swingNode.setContent(new JRViewer(jp));
AnchorPane anchorPane = new AnchorPane();
AnchorPane.setTopAnchor(swingNode,0.0);
AnchorPane.setBottomAnchor(swingNode,0.0);
AnchorPane.setLeftAnchor(swingNode,0.0);
AnchorPane.setRightAnchor(swingNode,0.0);
anchorPane.getChildren().add(swingNode);
Scene scene = new Scene(anchorPane);
Stage stage = new Stage();
stage.setHeight(550);
stage.setWidth(600);
stage.setAlwaysOnTop(true);
stage.setScene(scene);
stage.showAndWait();
Alternatively how to display a Jasper report inside a javafx stage, scene?
Output HTML from your Jasper report and load the report in a JavaFX WebView.
Make a javafx stage the owner of a JDialog?
I don't think this is possible. What should work instead is to make your application a Swing application and host your JavaFX content inside a JFXPanel inside a Swing JFrame. Then you have no Stage and the owner of the JDialog can be the JFrame hosting the JFXPanel.
now it's possible to do that
what you need now is install jdk 8
because swing content in javafx is introduced in jdk8
#FXML
private SwingNode swingNode;
...
JasperPrint jasperPrint = JasperFillManager.fillReport(FileName, hash, connect);
swingNode.setContent(new JRViewer(jasperPrint));
oracle just add tutorial for this too
for the next you can follow this link
oracle tutorial embed swing in javaFX
I have written a JasperReports print preview stage class in JavaFX 8. It is a pure JavaFX code and there is no need for use of SwingNode class.
In comparison to the JRViewer it does not support links and parts, but print preview window does not need it anyway. On the other side, code is much, much shorter and therefore it is easy to understand and to adopt further to everyone's needs.
Source code for this class is freely available at GitHub repository.

Resources