Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I know the following libraries for drawing charts in an SWT/Eclipse RCP application:
Eclipse BIRT Chart Engine (Links to an article on how to use it)
JFreeChart
Which other libraries are there for drawing pretty charts with SWT? Or charts in Java generally? After all, you can always display an image...
I have not used BIRT or JGraph, however I use JFreeChart in my SWT application. I have found the best way to use JFreeChart in SWT is by making a composite an AWT frame and using the AWT functionality for JFreeChart. The way to do this is by creating a composite
Composite comp = new Composite(parent, SWT.NONE | SWT.EMBEDDED);
Frame frame = SWT_AWT.new_Frame(comp);
JFreeChart chart = createChart();
ChartPanel chartPanel = new ChartPanel(chart);
frame.add(chartPanel);
There are several problems in regards to implementations across different platforms as well as the SWT code in it is very poor (in its defense Mr. Gilbert does not know SWT well and it is made for AWT). My two biggest problems are as AWT events bubble up through SWT there are some erroneous events fired and due to wrapping the AWT frame JFreeChart becomes substantially slower.
#zvikico
The idea of putting the chart into a web page is probably not a great way to go. There are a few problems first being how Eclipse handles integrating the web browser on different platforms is inconsistent. Also from my understanding of a few graphing packages for the web they are server side requiring that setup, also many companies including mine use proxy servers and sometimes this creates issues with the Eclipse web browsing.
SWTChart gives good results for line, scatter, bar, and area charts. The API is straight forward and there are numerous examples on the website. I went from finding it on google to viewing my data in less than an hour.
SWTChart
You might like this one too
It has the ability to plot real time data with your own data provider.
The one I've used are JChart2D and JFreeChart. I did a live plotter application over the summer and used JFreeChart for that. The guy who had started the project had used JChart2D but I found that it doesn't have enough options for tweaking the chart look and feel.
JChart2D is supposed to be very fast so if you need to do live plotting have a look at it, although JFreeChart didn't have any problems doing a plot a few times per second.
There also quite a list of charting libraries on java2s.com
I was also looking for a charting library for an Eclipse RCP app, stumbled on Caleb's post here and can definitely recommend SWTChart now myself. It is a lot faster than JFreeChart for me, plus easily extensible. If I would really have to complain about something, I'd say the javadoc could be a bit more verbose, but this is just to say everything else is great.
There’s also ILOG JViews Charts which looks pretty feature-complete… if you can afford it.
Here is some additional infos on using it with eclipse.
I suggest you try jzy3d, a simple java library for plotting 3d data. It's for java, on AWT, Swing or SWT.
After evaluationg several options I decided to use a JavaScript library for showing plots in my Eclipse Plugin. As zvikico already suggested it is possible to show a html page in a browser. In the html page you can utilize one of the JavaScript libraries to do the actual plotting. If you use Chartist you can save the image as SVG file from the context menu.
Some JavaScript charting libraries:
Chartist: http://gionkunz.github.io/chartist-js
D3js: http://d3js.org
Flot: http://www.flotcharts.org/
Further JavaScript charting frameworks: https://en.wikipedia.org/wiki/Comparison_of_JavaScript_charting_frameworks
Chartist Example image:
Example java code:
package org.treez.results.chartist;
import java.net.URL;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class WebViewSample extends Application {
private Scene scene;
#Override
public void start(Stage stage) {
// create the scene
stage.setTitle("Web View");
Browser browser = new Browser();
scene = new Scene(browser, 750, 500, Color.web("#666970"));
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class Browser extends Region {
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser() {
//add the web view to the scene
getChildren().add(browser);
//add finished listener
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
executeJavaScript();
}
});
// load the web page
URL url = WebViewSample.class.getResource("chartist.html");
String urlPath = url.toExternalForm();
webEngine.load(urlPath);
}
private void executeJavaScript() {
String script = "var chartist = new Chartist.Line(" + "'#chart'," + " " + "{"
+ " labels: [1, 2, 3, 4, 5, 6, 7, 8]," + "series: [" + " [5, 9, 7, 8, 5, 3, 5, 44]" + "]" + "}, " + ""
+ "{" + " low: 0," + " showArea: true" + "}" + "" + ");" + " var get = function(){return chartist};";
webEngine.executeScript(script);
Object resultJs = webEngine.executeScript("get()");
//get line
JSObject line = (JSObject) resultJs;
String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}";
JSObject linekeys = (JSObject) line.eval(getKeys);
JSObject options = (JSObject) line.eval("this.options");
JSObject optionkeys = (JSObject) options.eval(getKeys);
options.eval("this.showLine=false");
}
#Override
protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
layoutInArea(browser, 0, 0, w, h, 0, HPos.CENTER, VPos.CENTER);
}
#Override
protected double computePrefWidth(double height) {
return 750;
}
#Override
protected double computePrefHeight(double width) {
return 500;
}
}
Example html page:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="chartist.min.css">
</head>
<body>
<div class="ct-chart" id="chart"></div>
<script type="text/javascript" src="chartist.js"></script>
</body>
</html>
In order to get this working, chartist.js and chartist.min.css need to be downloaded and put at the same location as the html file. You could also include them from the web. See here for another example:
https://www.snip2code.com/Snippet/233633/Chartist-js-example
Edit
I created a java wrapper for D3.js, see
https://github.com/stefaneidelloth/javafx-d3
There's also JGraph, but I'm not sure if that's only for graphs (i.e. nodes and edges), or if it does charts also.
Here's something different: it's very to embed web pages in SWT views. I recently tried it and it works very well. You can see where this is going: there are plenty of beautiful charting components for HTML, it could be an option. Just make sure the component is client-side only (unless you want to start a server).
I haven't tested Flash, but I'm pretty sure you can get it to work (naturally, this means your software will require Flash plug-in installed).
JCharts is another option. It is similar to JFreeChart but the documentation is free. It does not have direct support for SWT but you can always generate an image and embed it in an SWT frame.
Related
I have an application made with JavaFX 16 which contains a WebView used to show an interactive map using the Leaflet JS library.
I have a problem when I try to transition to JavaFX 17, the interactive map does not work anymore (it cannot be moved nor clicked, but it can be scrolled). I reproduced the bug on a minimal example with the OpenStreetMap website that uses Leaflet :
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load("https://www.openstreetmap.org/");
Scene scene = new Scene(new StackPane(webView), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
The interactive map on the OpenStreetMap website is rendered correctly and can be zoomed in but it cannot be moved.
I am using Gradle to download JavaFX, this is my build.gradle :
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
}
repositories {
mavenCentral()
}
javafx {
version = "17"
modules = [ 'javafx.controls', 'javafx.web']
}
application {
mainClass = 'test.App'
}
I reproduced the bug with versions :
18-ea+5
17.0.1
17
17-ea+2
but the map worked with versions :
16
15
So it seems that version 17 brings the issue.
Also I reproduced the bug on macOS 12 (M1 using x86 JavaFX with Rosetta) and on Ubuntu 20. So it does not seem to be an issue with JavaFX on macOS.
Other interactive maps such as Google map, Apple map and Bing map, worked with the same code as above, and MapBoxGL does not work because WebGL is not supported. So it seems that the issue is related to Leaflet.
So I wonder if it is a known issue, if anyone else has the same issue, or if it is an issue on my side ?
I have entered this into the JDK bug database because there seems to be a more general issue here. See: https://bugs.openjdk.java.net/browse/JDK-8276859 This is also not the only report about such an issue. See also: After Java update to the version 1.8.0_301 JavaFX WebView with Leaflet.Draw.Circle, Leaflet.Edit.Circle does not work as well as OSM is not draggable
It's nice to see that there are more of us looking into this.
I did some deeper investigation and was able to pinpoint the problem which consequently lead me to a workaround/hack which makes dragging of Leaflet map to work fine in WebKit (Java FX 17).
Findings:
This is definitely regression as dragging of Leaflet map works fine with JavaFX releases prior to 17. So as #José pointed out it's most probably related to WebKit 610.2 upgrade (JDK-8259635).
It seems to be related to PointerEvent which seems to not be properly generated in the case of Java FX 17. Following example outputs 1 when dragging with the mouse button down. But it outputs 0 in the case of WebView/WebKit inside Java FX 17. Note that e.buttons value is properly set to 1 in JavaFX WebView/WebKit versions prior to Java FX 17.
<!doctype html>
<body style="height: 200px">
<p>Click and drag & observe the console output</p>
<script>
var onMove = function (e) {
console.log("e.buttons: " + e.buttons);
}
var body = document.getElementsByTagName('body')[0];
document.addEventListener("pointermove", onMove, false);
</script>
</body>
Based on the finding no. 2 I was able to identify the JS code which prevent the Leaflet map from moving (while being dragged). In Leaflet 1.7.1. it's actually this if expression which consequently causes map to not be moved (because PointerEvent.buttons is wrongfully set to 0 by Java FX 17):
https://github.com/Leaflet/Leaflet/blob/bd88f73e8ddb90eb945a28bc1de9eb07f7386118/src/dom/DomEvent.Pointer.js#L104
I've already reported this through the Oracle bug report system (JDK-8278150). The issue was "mistakenly" closed - I've already provided them with the info explained in this answer so they will hopefully re-open it or tackle it under JDK-8276859.
Workaround (Leaflet 1.7.1):
Workaround/hack to make Leaflet map work again:
Comment out the if expressions at:
https://github.com/Leaflet/Leaflet/blob/bd88f73e8ddb90eb945a28bc1de9eb07f7386118/src/dom/DomEvent.Pointer.js#L104
This makes the Leaftlet map to move properly while being dragged in the Java FX 17 WebView - but please consider this more like a hack to make it work again as this was not tested out thoroughly...
Update 1
This issue seems to be gone with the latest master branch of Leaflet despite regression in JavaFX WebView/WebKit remains (can anyone please confirm this?).
Update 2
As stated by #mipa, the underlying issue was fixed in 8u291 and openjfx17. More info available at:
http://bugs.openjdk.java.net/browse/JDK-8278759
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am creating JavaFX application and made a loading scene. In this scene i want to show some text like loading or initializing and add some loading spinner animated image as a visual notification that something is loading.
I generate a loading .gif animation created via https://loading.io/ and also downloaded it like frames of animation (multiple .png files).
I noticed that in the JavaFX Scene Builder 8.5.0 when I set the .gif in ImageView, my GPU in Windows task manager went up to 20%, on NVidia GeForce RTX 2070 graphic card and in my opinion this is a problem. I tested with a javafx desktop application, to rule out that is not a problem generated by the scene builder application and got similar results.
The next step that i tried is to create my custom animation using javafx.animation.Timeline. This is the initializing function that i call from the controller initialize(URL location, ResourceBundle resources) function. This function doesn't use the .gif image, it uses the multiple .png images of the same .gif image as frames.
private void initializeAnimation() {
imgLoading.setCache(true);
imgLoading.setCacheHint(CacheHint.SPEED);
Image[] images = new Image[31];
for(int i = 0; i <= 30; i++){
images[i] = new Image(getClass().getResourceAsStream("/es/main/gui/javafx/images/loading/frame-" + i + ".png"));
}
Timeline timeLine = new Timeline();
Collection<KeyFrame> frames = timeLine.getKeyFrames();
Duration frameGap = Duration.millis(100);
Duration frameTime = Duration.ZERO;
for (Image img : images) {
frameTime = frameTime.add(frameGap);
frames.add(new KeyFrame(frameTime, e -> imgLoading.setImage(img)));
}
timeLine.setCycleCount(Timeline.INDEFINITE);
timeLine.play();
}
In the first version i didn't call .setCache() and .setCacheHint() functions, I added them later while testing different variations of the same code. Also i tried adding
-Dprism.forceGPU=true -Dsun.java2d.opengl=true -Dprism.order=es2,es1,sw,j2d
as VMOption or some variants that I have read on this forum on improving graphic related settings for java. At the end, after all the changes, results in my task manager didn't change drastically. In the current version i use up to 17% of my GPU on this scene.
When the scene ends, in the next scene with no .gif images or Timeline's my GPU drops to almost 0%.
Running configurations:
Processor: i9-9900KF
Graphic card: GeForce RTX 2070
Java version "1.8.0_251"
JavaFX version "8.0.251-b08"
Short summary question: How to display animated .gif images correctly in JavaFX without having drastic overhead on the GPU (or CPU when with integrated graphics).
(Edit) 14.09.2020 - Java naming conventions
First thing I didn't noticed that i was not using the same size on my ImageView, so the first thing i changed for testing is adjusting the ImageView the same size as my .gif image (same width and height on both ImageView and .gif image). With this change the GPU percentage lowered to about %5.
As suggested I also upgrading the Java and JavaFX versions:
Tried using the jdk 1.8.0_261 with JavaFX built in version 8.0.261-b12 and got similar results.
Tried using jdk 14.0.2 with JavaFX version 15+9 (latest openjfx-15) and still got similar results.
Short summary: Upgrading the Java and JavaFX version didn't change anything relating this issue. Using the same size helped, but I think I can improve even better with your help.
My guess is you'd probably see some performance gains if you used one or more RotateTransition rather than key frame animation.
Here's a simple example using multiple transitions in a ParallelTransition:
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 200);
stage.setScene(scene);
Rectangle rect = new Rectangle (100, 40, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
RotateTransition rt = new RotateTransition(Duration.millis(3000));
rt.setByAngle(180);
rt.setAutoReverse(true);
FadeTransition ft = new FadeTransition(Duration.millis(3000));
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.setCycleCount(4);
ft.setAutoReverse(true);
ParallelTransition pt = new ParallelTransition(rect, ft, rt);
pt.play();
root.getChildren().add(rect);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I am new to using java for XPages development, I want to know if its posible to use JOptionPane Dialog in XPages Project? if yes how? or can i display a dialog component with Java. i tried the below code but notting happened
import javax.swing.*;
public class JOptionPaneMultiInput {
public static void main(String[] args) {
JTextField username = new JTextField();
JTextField password = new JPasswordField();
Object[] message = {
"Username test:", username,
"Password:", password
};
int option = JOptionPane.showConfirmDialog(null, message, "Login", JOptionPane.OK_CANCEL_OPTION);
}
}
I would like to use Java to display a dialog and save retured value in a variable
Swing is not compatible with XPages. XPages is built on JSF and I don't believe any JSF framework supports Swing. Swing is not used for web clients, it is only used for thick clients like Windows or Mac. Xpages is made for presenting to a web browser.
Note: JOptionPane is a part of the Swing framework. You can see this in your import which likely looks like this: javax.swing.*;
UPDATE:
You can definitely accomplish what you are asking. XPages is very feature packed and a great way to develop web applications. It does have a fairly steep learning curve, but thankfully there are already many great free resources out there. I would start with these two:
TLCC has a free introductory to XPages http://www.tlcc.com/admin/tlccsite.nsf/pages/free-xpages-training I also recommend their other paid courses which are very well done.
Notes in 9, (http://www.notesin9.com/) which is a series of free how to videos. Start with the hour long Intro to XPages: http://xpages.tv/xtv3.nsf/allEpisodes.xsp# which is where it all started to click with me.
I have been asked by my friend to make an application for Chrome and it requires me to have context-sensitive menus as below:
I have never really made anything for Chrome before and I have a few questions regarding it:
I will have to develop a plug-in, right ?
If so, is there a specific set of rules I have to follow ?
I know I can use GWT to compile Java to JavaScript
3. This context sensitive menu is the same as JPopupMenu ?
The application I want to develop is simple:
Copy some text,
right-click, click on the context sensitive menu
apply simple Caesar's cipher to the text
open a new JFrame with JtextArea in it to display the encrypted text.
What you're creating is called an "extension", not a "plug-in". A browser extension is written using HTML, CSS and Javascript, and got access to APIs for direct interaction with the browser.
Plug-ins, on the other hand, are compiled binaries such as Flash and Java.
Drop the idea of using GWT for Chrome extensions. It makes development of the extension harder, not easier (open issue).
Especially because you'll find plenty of vanilla JavaScript examples and tutorials in the documentation and Stack Overflow.
You just have to know the relevant APIs:
Copy some text,
right-click, click on the context sensitive menu
Use chrome.contextMenus. There's no need to copy, the selected text is available in the callback (examples).
apply simple Caesar's cipher to the text
Create a JavaScript function to achieve this.
open a new JFrame with JtextArea in it to display the encrypted text.
Create a new window using chrome.windows.create. You could include an extra HTML page in your extension, and use the message passing APIs to populate the text field, but since you appear to be a complete newbie, I show a simple copy-paste method to create and populate this window:
function displayText(title, text) {
var escapeHTML = function(s) { return (s+'').replace(/</g, '<'); };
var style = '*{width:100%;height:100%;box-sizing:border-box}';
style += 'html,body{margin:0;padding:0;}';
style += 'textarea{display:block;}';
var html = '<!DOCTYPE html>';
html += '<html><head><title>';
html += escapeHTML(title);
html += '</title>';
html += '<style>' + style + '</style>';
html += '</head><body><textarea>';
html += escapeHTML(text);
html += '</body></html>'
var url = 'data:text/html,' + encodeURIComponent(html);
chrome.windows.create({
url: url,
focused: true
});
}
Don't forget to read Getting started to learn more about the extension's infrastructure.
Check out Google Chrome Extensions Chrome Extensions
The Getting Started will help you Getting Started
You will find a section on how to use Context Menus.
I want to design new Git client with a clean GUI.
Is it possible to use the power of HTML, CSS and JavaScript in a java application?
I would like to use Java + JGit for models, Java for controllers and HTML + CSS + JavaScript for views.
I don't want a client-server model. I would like to integrate Java and HTML nicely. A DOM event would fire events directly to a Java controller. This way it would be possible to create rich offline application.
You can embed web browser component into your Java Swing/JavaFX Desktop application that displays GUI built with HTML5+CSS+JavaScript. You can see an article that describes how to do this at https://jxbrowser-support.teamdev.com/docs/tutorials/cross-desktop-apps.html
One of the Java Swing/JavaFX libraries that allows embedding Chromium into Java applications is JxBrowser. Using JxBrowser API you can load any web page and work with its DOM and JavaScript. You can even call Java methods from JavaScript code and vice versa. For example:
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSFunctionCallback;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent;
import com.teamdev.jxbrowser.chromium.events.LoadAdapter;
public class JavaScriptJavaSample {
public static void main(String[] args) {
Browser browser = new Browser();
browser.addLoadListener(new LoadAdapter() {
#Override
public void onFinishLoadingFrame(FinishLoadingEvent event) {
if (event.isMainFrame()) {
Browser browser = event.getBrowser();
JSObject window = (JSObject)
browser.executeJavaScriptAndReturnValue("window");
window.setProperty("MyFunction", new JSFunctionCallback() {
#Override
public Object invoke(Object... args) {
for (Object arg : args) {
System.out.println("arg = " + arg);
}
return "Hello!";
}
});
JSValue returnValue = browser.executeJavaScriptAndReturnValue(
"MyFunction('Hello JxBrowser!', 1, 2, 3, true);");
System.out.println("return value = " + returnValue);
}
}
});
browser.loadURL("about:blank");
}
}
It's not really feasible. Rich clients in Java are done using Swing or SWT.
If you want to use HTML/CSS for your user interface, you need to use the server/client model. It can be as simple as creating a local server and launching a browser that connects to it, but it would still be that model.
If you absolutely need to have HTML/CSS as your UI framework and can't go to a server/client model, your best bet is probably looking at something like Google Native Client, but that uses C/C++ bindings on the backend. I haven't used Native Client so I can't personally give much more information on that front.
Edit to add:
One option is to embed a native browser into your Swing app using something like: http://djproject.sourceforge.net/ns/
There are some pure Java HTML renderers, however, they most likely won't be fully HTML5/CSS3 compliant, let alone possibly have Javascript bugs as well.
See here for some of those options: Pure Java HTML viewer/renderer for use in a Scrollable pane
Like #Reverand Gonzo says, you will need some form of server/client. But you could easily embed a Jetty server into a Java app and then use GWT for your client code.
You can bring in the power of HTML,CSS,JavaScript into your Swing app using JFXPanel to embed JavaFX WebView. Have a look at the SimpleSwingBrowser demo in this link:https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/swing-fx-interoperability.htm
WebView allows to call JavaScript functions from Java and vice versa. It is also a nice way to enhance your legacy Java app with web technologies.
JavaFX 2.2 brought this functionality to providing a user interface component (GUI) that has web view and full browsing functionality.
For more details, see Adding HTML Content to JavaFX Applications.
Use Angular.js with HTML and rest of the things as same in Java, just use classes for business logic, no need to write code for awt/swing. Angular with spring boot are rapid development in Java for webapp with less code in Java without swing use to create best webapp .