I want to implement file drag and upload in java webview, however, it keeps crashing JVM when any type of upload is initiated. Tested on latest JDK 8 and 9 on windows 10. I'm lost as to what can be causing this issue.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class DropFileUpload extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(final Stage stage) {
WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
//webEngine.load("https://html5demos.com/dnd-upload/");
webEngine.load("http://www.dropzonejs.com");
VBox root = new VBox();
root.getChildren().add(webView);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
Related
I want to create a tree-based algorithm visualization in JavaFx, and there are many sub scripts and super scripts in the notations. I want to add these notations to shapes like circles.
I have tried using WebView object for doing that, but it just covers up the entire screen.
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Shape Text");
Group circles = new Group();
Circle circle = new Circle(50, Color.web("white", 0.7));
circle.setCenterX(500.0f);
circle.setCenterY(200.0f);
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<h1>B<sub>0</sub></h1>");
StackPane stack = new StackPane();
stack.getChildren().addAll(circles, webView);
Scene scene = new Scene(stack, 1000, 800, Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
The above code replaces the entire view with HTML text. I also tried javafx.scene.text.Text class, but it does not support the HTML content.
Thank you in advance!
There are three things you might want to do:
Size the WebView to the HTML content (or the inner display region of the shape).
Make the background of the WebView pages transparent.
Center the HTML content in the WebView, with the WebView centered in the Shape.
Code below demonstrates some of these tricks:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.StrokeType;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import java.lang.reflect.Field;
public class ShapedHTML extends Application {
#Override
public void start(Stage stage) throws Exception{
stage.setTitle("Shape Text");
Group circles = new Group();
Circle circle = new Circle(50, Color.web("white", 0.7));
circle.setCenterX(500.0f);
circle.setCenterY(200.0f);
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webView.maxWidthProperty().bind(circle.radiusProperty().multiply(2));
webView.maxHeightProperty().bind(circle.radiusProperty().multiply(2));
webEngine.documentProperty().addListener(observable -> {
try {
// Use reflection to retrieve the WebEngine's private 'page' field.
Field f = webEngine.getClass().getDeclaredField("page");
f.setAccessible(true);
com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(webEngine);
page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB());
} catch (Exception e) {
System.out.println("Difficulty to make WebView background transparent");
e.printStackTrace();
}
});
webEngine.loadContent("<h1 id='root' style='background : rgba(0,0,0,0); margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);'>B<sub>0</sub></h1>");
StackPane stack = new StackPane();
stack.getChildren().addAll(circles, webView);
Scene scene = new Scene(stack, 1000, 800, Color.BLACK);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Note on com.sun class usage
The above code uses com.sun classes (which is usually not recommended as it is not publicly supported API). But, it worked for me (on Java 8) and I don't know a better way to accomplish the transparency of the WebView background.
If you are using later versions of Java (e.g. Java 11+), then you will need to provide some VM arguments to allow usage of the relevant com.sun classes to work. See, for instance, the stack overflow question Cannot access JavaFX class "WebPage" in IntelliJ-IDEA for resolving accessibility issues for com.sun.webkit.WebPage in Java 11+. An answer to that question suggests using the following VM arguments (which I haven't tried):
--add-exports javafx.web/com.sun.webkit=projectname
where the last argument is your module name as declared in the module-info.java of your project.
Try setting the maxSize of the WebView.
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class JavaFXTestingGround extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
Circle circle = new Circle(100, Color.web("white", 0.7));
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<h1>B<sub>0</sub></h1>");
webView.setMaxSize(50, 50);
StackPane stack = new StackPane();
stack.getChildren().addAll(circle, webView);
Scene scene = new Scene(stack, 1000, 800, Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
I am just trying to play a mp3 file using JavaFX with JDK 10.
I only have 1 main Java file. The code works with JDK 8 but not JDK 10. When running with JDK 10, I compiled with the --add-modules=javafx.graphics,javafx.media flag and it can run, showing the window but no audio is being played.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.media.Media;
import javafx.scene.Scene;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import java.io.File;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Hello World");
Group root = new Group();
Scene scene = new Scene(root, 300, 275);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
String bip = "bip.mp3";
Media hit = new Media(new File(bip).toURI().toString());
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.setAutoPlay(true);
MediaView mediaView = new MediaView(mediaPlayer);
((Group)scene.getRoot()).getChildren().add(mediaView);
}
public static void main(String[] args) {
launch(args);
}
}
How to make MediaPlayer work with JDK 10? Otherwise, any idea what may be the cause of this issue?
I want my java application such that if user chooses to click on a button the PDF opens using the default PDF reader that is installed in the computer.
The PDF which i want to be opened is present in same package "application".
The code which I am using is
package application;
import java.io.File;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Load PDF");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
File pdfFile = new File("computer_graphics_tutorial.pdf");
getHostServices().showDocument(pdfFile.toURI().toString());
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If the PDF file is in the same package as the caller file (as you state), then
getHostServices().showDocument(getClass()
.getResource("computer_graphics_tutorial.pdf").toString());
should solve the problem.
The getResource method can be used really flexibly to locate files. Here is a small description how to use it: JavaFX resource handling: Load HTML files in WebView.
I tried to run the following code in my Netbeans 7.2 (Java 1.7.u79) and Netbeans 8.0.2 (Java 1.8 u45) and its not working!
package com.main;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class RBrowser extends Application {
#Override
public void start(Stage primaryStage) {
WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
webEngine.load("http://docs.oracle.com/javafx/2/webview/jfxpub-webview.htm");
Button b = new Button("Show Console");
b.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent t) {
webEngine.executeScript("if (!document.getElementById('FirebugLite')){E = document['createElement' + 'NS'] && document.documentElement.namespaceURI;E = E ? document['createElement' + 'NS'](E, 'script') : document['createElement']('script');E['setAttribute']('id', 'FirebugLite');E['setAttribute']('src', 'https://getfirebug.com/' + 'firebug-lite.js' + '#startOpened');E['setAttribute']('FirebugLite', '4');(document['getElementsByTagName']('head')[0] || document['getElementsByTagName']('body')[0]).appendChild(E);E = new Image;E['setAttribute']('src', 'https://getfirebug.com/' + '#startOpened');}");
}
});
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.getChildren().addAll(browser,b);
Scene scene = new Scene(root, 700, 550);
primaryStage.setTitle("Google Map");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I tried to access http://docs.oracle.com/javafx/2/webview/jfxpub-webview.htm in the Google Chrome Browser and it was loaded successfully, WHAT'S WRONG WITH MY CODE?
Which version of JDK have you installed. I am using IDK 8u77 on Windows 8.1 and running on Eclipse Mars2 your code, it worked perfectly. Try latest version from here. Check it works or not.
Here's my snippet:
package javafxdemo;
import org.tbee.javafx.scene.layout.MigPane;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class FXDemo extends Application {
#Override
public void start (Stage stage) throws Exception {
MigPane root = new MigPane();
Scene scene = new Scene(root);
Button b = new Button("Hello");
root.getChildren().add(b);
stage.setScene(scene);
stage.setTitle("FX");
stage.show();
}
public static void main (String[] args) {
launch (args);
}
}
When running the gui doesn't show properly: the frame size is smaller than the button. Why does it happens? In HBox Layout when setting the scene it is automatically resized, so why with MiGLayout it doesn't work?
I'm using MigLayout 4.3
So, I filed an issue and later found out a workaround for this:
just add stage.sizeToScene() after stage.show().