Drag and drop multiple files into javaFX - javafx

I'm pretty new to Java. I'm building a samll app to help in my normal work, basically to process several files text files and add up the number of text symbols contained by those files. I would like to understand how to drop multiple files into a javaFX scene, since handle(DragEvent event) accepts only one file.

You can clearly accept multiple files in a DragEvent.
The following example displays the file names dropped to the scene:
#Override
public void start(Stage primaryStage) {
Text text = new Text();
StackPane root = new StackPane(text);
root.setOnDragOver(evt -> {
if (evt.getDragboard().hasFiles()) {
evt.acceptTransferModes(TransferMode.LINK);
}
});
root.setOnDragDropped(evt -> {
text.setText(evt.getDragboard().getFiles().stream().map(File::getAbsolutePath).collect(Collectors.joining("\n")));
evt.setDropCompleted(true);
});
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}

Related

Add JavaFX Label - (Using Only Java / JavaFX Code) - To Existing GUI Created With Scenebuilder / FXML

I Created a complete GUI using ONLY Scenebuilder FXML Techniques
Something Like This :-
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
Parent root=FXMLLoader.load(getClass().getResource("backupmenu.fxml"));
primaryStage.setTitle("Backup Affected Files And Folders Only");
primaryStage.setScene(new Scene( root, 800, 400));
primaryStage.show();
}
}
However I want to add a label to that SAME EXISTING GUI but this time using ONLY Java Code / JavaFX Label Techniques ?
I.E Using Traditional Methods such as this Example Below :-
// launch the application
public void start(Stage s)
{
// set title for the stage
s.setTitle("creating label");
// create a label
Label b = new Label("This is a label");
// create a Stack pane
StackPane rootpane = new StackPane();
// add password field
rootpane.getChildren().add(b);
// create a scene
Scene sc = new Scene(rootpane, 200, 200);
// set the scene
s.setScene(sc);
s.show();
}
public static void main(String args[])
{
// launch the application
launch(args);
}
}
I cannot find a web search result that even comes close to matching my very specific question .
Can i combine the 2 techniques - Is it Possible ?
Yes, this is possible.
You need a reference to the Parent (some kind of container Pane or Node) you want to add the Label to in your controller class.
For example, suppose your FXML defines a VBox with an id of "root":
<VBox fx:id="root">
In your controller, define a reference to that VBox:
#FXML
private VBox root;
Then you can add anything you want to the VBox:
root.getChildren().add(new Label("Hi, I'm a new Label!"));

multiple Scenes in single Stage

facing Difficulties to create multiple scenes in a single stage.
this is the init method where i've loaded two images.
public void init() {
Rotate rotate=new Rotate();
rotate.setAngle(0.0);
rotate.setPivotX(1000/2);
rotate.setPivotY(1020/2);
Image img=new Image("file:///C:/Users/Avi/Desktop/test.jpg");
ImageView view=new ImageView(img);
Image back=new Image("file:///C:/Users/Avi/Desktop/background.jpg");
ImageView backview=new ImageView(back);
view.setOpacity(0.25);
view.setX(1000/2);
view.setY(1020/2);
sp_mainlayout = new StackPane();
backlay=new StackPane();
cc_custom = new CustomControl();
sp_mainlayout.getChildren().add(backview);
sp_mainlayout.getChildren().add(view);
sp_mainlayout.getChildren().add(cc_custom);
backlay.getChildren().add(backview);
}
Now in the start method the stage is single but i want to show one image at the background at a large size and the other one in front of it in a smaller size. But two scenes aren't working together. Need some modification for the code.(the sizes of the scenes will be different)
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Chess game");
Scene scene1 =new Scene(sp_mainlayout,800,600);
primaryStage.setScene(scene1);
primaryStage.show();
Scene scene =new Scene(backlay,800,600);
primaryStage.setScene(scene);
primaryStage.setMinWidth(300);
primaryStage.setMinHeight(300);
primaryStage.setResizable(false);
primaryStage.show();
}

Allow clicks to go through application GUI

I have a JavaFx application that loads a transparent stage with some text on it.
I want any click on the application to be completely ignored and the background application (if any) to receive that click.
My code at this stage is as follows:
public void start(final Stage primaryStage) {
primaryStage.setAlwaysOnTop(true);
final StackPane layout = new StackPane();
final Text mainText = new Text();
layout.getChildren().add(mainText);
mainText.setText("|||||||||||||||||||||||||||");
final Scene mainScene = new Scene(layout);
mainScene.setFill(null);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(mainScene);
primaryStage.show();
layout.setMouseTransparent(true);
mainText.setMouseTransparent(true);
}
I was not able to achieve the requirement. setMouseTransparent() just prevented the text from triggering events, it still captured the mouse clicks.
Is it possible to achieve this in JavaFx ? Even if it is a per-OS solution.
A way of doing this action in Windows is through user32.dll and Java Native Access (JNA). We used GetWindowLong to get the current configuration of the window and SetWindowLong to update the bit field that is controlling the ability of the window be transparent to the mouse.
Following is a working example that demonstrates this functionality:
#Override
public void start(final Stage primaryStage) {
primaryStage.setAlwaysOnTop(true);
final StackPane layout = new StackPane();
final Text mainText = new Text();
layout.getChildren().add(mainText);
mainText.setText("|||||||||||||||||||||||||||");
final Scene mainScene = new Scene(layout);
mainScene.setFill(null);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(mainScene);
primaryStage.setTitle(sTitle);
primaryStage.show();
sUser32.EnumWindows(
(hWnd, data) -> {
final byte[] windowText = new byte[512];
sUser32.GetWindowTextA(hWnd, windowText, 512);
final String wText = Native.toString(windowText);
if (!wText.isEmpty() && wText.equals(sTitle)) {
final int initialStyle = com.sun.jna.platform.win32.User32.INSTANCE.GetWindowLong(hWnd, WinUser.GWL_EXSTYLE);
com.sun.jna.platform.win32.User32.INSTANCE.SetWindowLong(hWnd, WinUser.GWL_EXSTYLE, initialStyle | WinUser.WS_EX_TRANSPARENT );
return false;
}
return true;
}, null);
}

JavaFX translateZ for a non-root node causes it to disappear

I'm trying to use the translateZ property on a VBox to move the panel "into the screen".
If I use setTranslateZ() on the root node this works fine. However if I change root.setTranslateZ(200); to panel.setTranslateZ(200); the window is blank.
public class Demo01HelloWorld3D extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("Press me");
VBox panel = new VBox(button);
panel.setAlignment(Pos.CENTER);
panel.setDepthTest(DepthTest.ENABLE);
VBox root = new VBox(panel);
root.setAlignment(Pos.CENTER);
root.setDepthTest(DepthTest.ENABLE);
root.setTranslateZ(200);
// panel.setTranslateZ(200); <== I want this to work
Scene scene = new Scene(root, 320, 240, true);
primaryStage.setScene(scene);
scene.setCamera(new PerspectiveCamera(false));
primaryStage.show();
}
}
Setting translateZ on the root node
Setting translateZ on the panel node
Things I've tried
Setting depthTest attribute to enable - although I don't think this is necessary as it defaults to DepthTest.INHERIT
Lots of searching for similar questions!
Checking SCENE3D is enabled - yes it is
Checking the javadoc for translateZProperty
checked Z value is less than camera clippingFar property
Looked at Oracle JavaFX 3D tutorial - this does not specifically address 3D with standard controls and containers etc.
With panel.setTranslateZ(200); you're pushing the panel behind the root, so the root obscures it.
Add root.setStyle("-fx-background-color: transparent;"); and it works:
#Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("Press me");
VBox panel = new VBox(button);
panel.setAlignment(Pos.CENTER);
panel.setDepthTest(DepthTest.ENABLE);
VBox root = new VBox(panel);
root.setAlignment(Pos.CENTER);
root.setDepthTest(DepthTest.ENABLE);
root.setStyle("-fx-background-color: transparent;");
panel.setTranslateZ(200);
Scene scene = new Scene(root, 320, 240, true);
primaryStage.setScene(scene);
scene.setCamera(new PerspectiveCamera(false));
primaryStage.show();
}

How to create a modal window in JavaFX 2.1

I can't figure out how to create a modal window in JavaFX. Basically I have file chooser and I want to ask the user a question when they select a file. I need this information in order to parse the file, so the execution needs to wait for the answer.
I've seen this question but I've not been able to find out how to implement this behavior.
In my opinion this is not good solution, because parent window is all time active.
For example if You want open window as modal after click button...
private void clickShow(ActionEvent event) {
Stage stage = new Stage();
Parent root = FXMLLoader.load(
YourClassController.class.getResource("YourClass.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("My modal window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(
((Node)event.getSource()).getScene().getWindow() );
stage.show();
}
Now Your new window is REALY modal - parent is block.
also You can use
Modality.APPLICATION_MODAL
Here is link to a solution I created earlier for modal dialogs in JavaFX 2.1
The solution creates a modal stage on top of the current stage and takes action on the dialog results via event handlers for the dialog controls.
JavaFX 8+
The prior linked solution uses a dated event handler approach to take action after a dialog was dismissed. That approach was valid for pre-JavaFX 2.2 implementations. For JavaFX 8+ there is no need for event handers, instead, use the new Stage showAndWait() method. For example:
Stage dialog = new Stage();
// populate dialog with controls.
...
dialog.initOwner(parentStage);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.showAndWait();
// process result of dialog operation.
...
Note that, in order for things to work as expected, it is important to initialize the owner of the Stage and to initialize the modality of the Stage to either WINDOW_MODAL or APPLICATION_MODAL.
There are some high quality standard UI dialogs in JavaFX 8 and ControlsFX, if they fit your requirements, I advise using those rather than developing your own. Those in-built JavaFX Dialog and Alert classes also have initOwner and initModality and showAndWait methods, so that you can set the modality for them as you wish (note that, by default, the in-built dialogs are application modal).
You can create application like my sample. This is only single file JavaFX application.
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage stage;
stage = new Stage();
final SwingNode swingNode = new SwingNode();
createSwingContent(swingNode);
StackPane pane = new StackPane();
pane.getChildren().add(swingNode);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Swing in JavaFX");
stage.setScene(new Scene(pane, 250, 150));
stage.show();
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void createSwingContent(final SwingNode swingNode) {
SwingUtilities.invokeLater(() -> {
try {
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
JasperDesign jasperDesign = JRXmlLoader.load(s + "/src/reports/report1.jrxml");
String query = "SELECT * FROM `accounttype`";
JRDesignQuery jrquery = new JRDesignQuery();
jrquery.setText(query);
jasperDesign.setQuery(jrquery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint JasperPrint = JasperFillManager.fillReport(jasperReport, null, c);
//JRViewer viewer = new JRViewer(JasperPrint);
swingNode.setContent(new JRViewer(JasperPrint));
} catch (JRException ex) {
Logger.getLogger(AccountTypeController.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

Resources