I am using javafx webview to load a local html page in a jpanel. Executing the code gives me following message:
Outstanding resource locks detected: D3D Vram Pool: 13,810,710 used (5.1%), 13,810,710 managed (5.1%), 268,435,456 total
14 total resources being managed
average resource age is 0.8 frames
0 resources at maximum supported age (0.000000)
3 resources marked permanent (21.400000)
3 resources have had mismatched locks (21.400000)
3 resources locked (21.400000)
5 resources contain interesting data (35.700000)
I am new to java and I don't understand why this message is being generated and how it could be resolved (my html page works fine and so does the swing code - gives me the desired result).I tried looking it up online but was unable to find a solution.
Please let me know if any other information is needed.
Edit:
I'm trying to develop a video annotation tool. The tags to be attached to the video and their handling is all done in java swing. The video itself is a part of the html page I'm loading in a javafx webview. I've placed a semi-transparent canvas on it which I'm using to register mouse-click events to attach the tags to specific content on the video at a certain time. Below the video tag is another canvas which acts as the timeline (shows attached tags at the appropriate time). That's the basic goal for the code.
Here's the code where I add my jfxpanel:
package codingAnnotations;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class JFXContainerPanel extends JPanel {
private final JFXPanel WebViewContainer;
private final JFXPanel TimeLineContainer;
public JFXContainerPanel(){
WebViewContainer = new JFXPanel();
TimeLineContainer = new JFXPanel();
add(WebViewContainer);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(WebViewContainer);
}
});
}
private static void initFX(final JFXPanel fxPanel) {
Group group = new Group();
Scene scene = new Scene(group);
WebView webView = new WebView();
group.getChildren().add(webView);
webView.setMinSize(500, 500);
webView.setMaxSize(800, 600);
final String html = "res/VideoCanvas.html";
final java.net.URI uri = java.nio.file.Paths.get(html).toAbsolutePath().toUri();
System.out.println(uri.toString());
WebEngine webEngine = webView.getEngine();
webEngine.load(uri.toString());
webEngine.setOnAlert(new EventHandler<WebEvent<String>>(){
#Override
public void handle(WebEvent<String> arg0) {
String value = arg0.toString().substring(10, arg0.toString().length() - 1);
System.out.println(value);
}
});
fxPanel.setScene(scene);
}
}
Thanks for your help!
Related
I am trying to start an application based on google maps in Android Studio. I followed the instructions and started an Google Maps activity.
Then I created according to the instructions an API key and enabled the maps SDK android for android and copied the key into the app.
but then when I'm trying to run the app (didnt change a thing) I get this error:
Inconvertible types; cannot cast 'android.support.v4.app.Fragment' to 'com.google.android.gms.maps.SupportMapFragment'
for this line of code:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
and this error: Manifest merger failed : Attribute application#appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:12:5-42:19 to override.
in the event.
Here is the code:
package com.example.android.myfirstmap;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
I looked around to see if there is a solution that fixes also my problem but none of what I tried was the right one.
does anyone knows how to fix it? evreything is updated.
Support Map Fragment extends androidx.fragment.app.Fragment.
You are importing android.support.v4.app.FragmentActivity which uses android.support.v4.app.Fragment. These are two different classes so they are incompatible.
You need to migrate your app to Android X: https://developer.android.com/jetpack/androidx/migrate
Then, in your build.gradle file, replace com.android.support:support-fragment with androidx.fragment:fragment.
Hope that helps!
Trying assertJ-swing for UI testing of java-swing based application.
Situation: Sample application in JavaApp.java (with Main class) works fine when it is invoked from this java file (running it as Java application). But when it is invoked from TestNG with assertj-swing's command:
application(JavaApp.class).start();
the application opens up but closes down immediately.
Question: Is it the only approach? Please suggest resolution or any other approach to launch the application and keep it open so further operations can be performed.
JavaApp:
package jdialogdemo;
import java.awt.*;
import java.awt.event.*;
import javax.lang.model.util.SimpleElementVisitor6;
import javax.swing.*;
public class JavaApp {
public static void main(String[] args) throws Exception {
final JFrame frame = new JFrame("JDialog Demo");
final JButton btnLogin = new JButton("Click to login");
btnLogin.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
LoginDialog loginDlg = new LoginDialog(frame);
loginDlg.setVisible(true);
// if logon successfully
if(loginDlg.isSucceeded()){
btnLogin.setText("Hi " + loginDlg.getUsername() + "!");
}
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 200);
frame.setLocationRelativeTo(null);
frame.setLayout(new FlowLayout());
frame.getContentPane().add(btnLogin);
frame.setVisible(true);
}
}
AssertJ-Swing verifies that you only do access swing components on the EDT (as required because Swing is not thread safe, see Concurrency in Swing - Initial threads).
Your main method violates this (by constructing the UI from the main thread) and therefore AssertJ-Swing fails with an exception.
To correct the problem your main method should look like this:
public class JavaApp {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(() -> {
final JFrame frame = new JFrame("JDialog Demo");
final JButton btnLogin = new JButton("Click to login");
//...
});
}
}
I am using chrriis.dj.nativeswing.swtimpl.components.JWebBrowser in my swing application to open web page of a jupyter-notebook. Now my problem is when I click New->Python 3 button JWebBrowser to new a file, it always return the 404 page.
New a notebook in DJNativeSwing JWebBrowser
DJNativeSwing JWebBrowser got the 404 page
I think maybe it did not execute the javascript api in jupyter-notebook, can anyone help me make the DJNativeSwing JWebBrowser work under jupyter notebook?
The code I used:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import chrriis.common.UIUtils;
import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowserWindow;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserNavigationEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowFactory;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowWillOpenEvent;
/**
* #author Christopher Deckers
*/
public class NavigationControl extends JPanel {
protected static final String LS = System.getProperty("line.separator");
public NavigationControl() {
super(new BorderLayout());
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
final JWebBrowser webBrowser = new JWebBrowser();
webBrowser.setBarsVisible(false);
webBrowser.setStatusBarVisible(true);
webBrowser.navigate("https://try.jupyter.org/");
tabbedPane.addTab("Controled Browser", webBrowser);
add(tabbedPane, BorderLayout.CENTER);
}
/* Standard main method to try that test as a standalone application. */
public static void main(String[] args) {
UIUtils.setPreferredLookAndFeel();
NativeInterface.open();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("DJ Native Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new NavigationControl(), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
NativeInterface.runEventPump();
}
}
Thanks Thomas K. I changed the engine of jwebbrowser to Xulrunner-24.0.en-US and the problem disappeared.
Is there a simple (uniform) way to recursively descend a JavaFX widget tree starting from a defined node (possibly from the Scene itself)?
The following code:
static class Visitor {
public void visit(Node node){
...
}
}
protected void walkWidgets(Node n, Visitor cb) {
if (n instanceof Parent) {
Parent p = (Parent) n;
for (Node c : p.getChildrenUnmodifiable()) {
walkWidgets(c, cb);
}
}
cb.visit(n);
}
... does not work because the "children" of some containers (e.g.: SplitPane, BorderPane, etc.) are not listed in their children Property.
To overcome this I should specialize the code to allow for all the quirks of all different widgets. This is particularly annoying when You start using widget libs beyond the "standard" provision.
Am I missing something? (I surely hope so!)
This seems to work fine: it gets all the child nodes in the BorderPane, SplitPane and TabPane.
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class WalkComponentTree extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
root.setTop(new Label("Title"));
SplitPane splitPane = new SplitPane();
root.setCenter(splitPane);
ListView<String> list = new ListView<>();
list.getItems().addAll("One", "Two", "Three");
TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
tab1.setContent(new TextArea());
Tab tab2 = new Tab();
tab2.setContent(new Label("Tab 2"));
tabPane.getTabs().addAll(tab1, tab2);
splitPane.getItems().addAll(tabPane, list);
Button button = new Button("Walk tree");
button.setOnAction(event -> walkTree(root, node ->
System.out.println(node.getClass())));
root.setBottom(button);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void walkTree(Node node, Consumer<Node> visitor) {
visitor.accept(node);
if (node instanceof Parent) {
((Parent) node).getChildrenUnmodifiable()
.forEach(n -> walkTree(n, visitor));
}
}
public static void main(String[] args) {
launch(args);
}
}
Note you can also use node.lookupAll("*");, though this is less robust as it only works once css has been applied to the node.
In my opinion you are correct to say that there is no "standard" way to walk through the JavaFX scene graph.
One reason is, that Tab is not derived from Node, so you will not get a List of Tabs from Parent.getChildrenUnmodifiable(). Another reason is, that ScrollPane and TitledPane do not publish their content node in Parent.getChildrenUnmodifiable(). Some other Panes like Accordion, SplitPane and Toolbar also don't publish their children with Parent.getChildrenUnmodifiable(). So you need to handle this yourself.
For more Information please see:
Walking the JavaFX Scene Graph
I am trying to utilise RTMPGW as part of my app, which usually works great in Linux. I am trying to use the Vitamio bundle to play back the stream. Here is the main code, taken from the Vitamio Demo:
package io.vov.vitamio.demo;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.app.Activity;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
public class VideoViewDemo extends Activity {
private VideoView mVideoView;
/* (non-Javadoc)
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVideoView.setVideoURI(Uri.parse("http://172.16.1.182:8902/?r=rtmp://live.dtv.cubecdn.net:80/kdmobil/KanalD1&W=http://www.kanald.com.tr/Content/swf/Canliplayer6.swf?config=/Content/swf/Config.xml%26debug=false&p=http://www.kanald.com.tr&c=80"));
mVideoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
if (mVideoView != null)
mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
super.onConfigurationChanged(newConfig);
}
}
When I run this, RTMPGW (which I am running from the terminal in Linux) displays this error:
processTCPrequest, Range request not supported
..and sits there idly, doing nothing.
However, when I use regular Android VideoView with this code (in a different project):
package com.sample.videoviewexample;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;
public class MainActivity extends Activity {
private VideoView mVideoView;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVideoView.setVideoURI(Uri.parse("http://172.16.1.182:8902/?r=rtmp://live.dtv.cubecdn.net:80/kdmobil/KanalD1&W=http://www.kanald.com.tr/Content/swf/Canliplayer6.swf?config=/Content/swf/Config.xml%26debug=false&p=http://www.kanald.com.tr&c=80"));
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
}
}
It connects to the RTMPGW server and starts streaming like so...
Streaming on http://0.0.0.0:8902
processTCPrequest, Range request not supported
Connecting ... port: 80, app: kdmobil/KanalD1
1094.914 KB / 16.90 sec
But, of course, as Android MediaPlayer doesn't support Flash natively it won't play back the video.
Why does the VideoView connect with RTMPGW's server but Vitamio doesn't?
Thanks for your help,
Dan