For a JavaFX2 Application I have to show different types of Charts.I am using jfreeChart for Charts creation and code given below:
public static JFreeChart generatePieChart() {
DefaultPieDataset dataSet = new DefaultPieDataset();
dataSet.setValue("China", 25);
dataSet.setValue("India", 25);
dataSet.setValue("United States", 50);
JFreeChart chart = ChartFactory.createPieChart(
"World Population by countries", dataSet, true, true, false);
return chart;
}
This returns me a chart object. How can I integrate this with my JavaFx Node like HBox etc.?
This answer discusses a few different approaches for chart integration in JavaFX.
Using the FXGraphics2D bridge to paint JFreeChart
David Gilbert (JFreeChart creator) created a bridge which allows a JFreeChart to be painted using JavaFX primitives. The project is FXGraphics2D:
FXGraphics2D is a free implementation of the Graphics2D API that targets the JavaFX Canvas. The code has been developed for the use of Orson Charts and JFreeChart, but will be generally useful for any code that uses the Graphics2D API.
FXGraphics2D requires JDK 1.8.0 or later and is licensed under the terms of a (three clause) BSD-style license.
See the FXGraphics2D site and the answer to Interoperability between Graphics2D and GraphicsContext for more information.
David notes in a comment on another answer:
FXGraphics2D is now integrated directly in JFreeChart (at version 1.0.18) so JavaFX support is now included (requires JDK/JRE 1.8).
Solution Embedding JFreeChart in JavaFX
Use a SwingNode from Java 8 to embed Swing based content such as JFreeChart in JavaFX applications.
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.*;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.jfree.chart.*;
import org.jfree.data.general.DefaultPieDataset;
public class JFreeChartSwingNodePopulationPieChart extends Application {
#Override public void start(Stage stage) {
final SwingNode chartSwingNode = new SwingNode();
chartSwingNode.setContent(
new ChartPanel(
generatePieChart()
)
);
stage.setScene(
new Scene(
new StackPane(
chartSwingNode
)
)
);
stage.show();
}
private JFreeChart generatePieChart() {
DefaultPieDataset dataSet = new DefaultPieDataset();
dataSet.setValue("China", 1344.0);
dataSet.setValue("India", 1241.0);
dataSet.setValue("United States", 310.5);
return ChartFactory.createPieChart(
"Population 2011", dataSet, true, true, false
);
}
public static void main(String[] args) { launch(args); }
}
Alternative Solution Using JavaFX Charts
Use JavaFX's own charting framework.
JavaFX charts do not cover exactly the same functionality as JFreeChart, but are excellent for many applications.
The default pie chart code posted in the question can trivially be replicated in JavaFX using JavaFX charts, eliminating the need to use an external library for such charts.
import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.*;
import javafx.scene.chart.*;
import javafx.stage.Stage;
public class JavaFXPopulationPieChart extends Application {
#Override public void start(Stage stage) {
final PieChart chart = new PieChart(
FXCollections.observableArrayList(
new PieChart.Data("China", 1344.0),
new PieChart.Data("India", 1241.0),
new PieChart.Data("United States", 310.5)
)
);
chart.setTitle("Population 2011");
stage.setScene(new Scene(chart));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
On JavaFX and JFreeChart Functional Comparisons
If only there were support for error bars. Without them, the charting framework has much less value for science apps.
The JavaFX Advanced Candlestick Chart from Oracle's Ensemble Sample Application demonstrates how to use JavaFX to build a candlestick chart. Even though error bars are different from candlesticks, I think the implementation of a custom error bar chart would be quite possible using the existing JavaFX charting library and the code would end up similar in many ways to the Ensemble candlestick chart sample.
But sure, the point is still valid, some things such as error bars are currently going to be easier to achieve leveraging a mature library such as JFreeChart.
As Alexander points out, if there is required functionality missing from the standard JavaFX charting framework which looks like it would be applicable to a wide range of users, then it is best to file a feature request to get the functionality embedded into the standard library. Though some kinds of advanced chart features are probably best handled by a 3rd party extension library for JavaFX charting (of which there are none currently available that I know of).
It is now possible to display a JFreeChart instance on a JavaFX Canvas using FXGraphics2D, a free implementation of the Graphics2D API for JavaFX.
JFreeChart is Swing-oriented - while the JFreeChart class itself is not a Swing component, it is typically displayed on a org.jfree.chart.ChartPanel, which is a subclass of javax.swing.JPanel. It uses a ava.awt.Graphics2D object to draw itself.
I suppose that you could use the createBufferedImage() method of JFreeChart to get a BufferedImage, and then use SwingFXUtils to convert it to a javafx.scene.image.WritableImage, but then you'd lose the interactive nature of the chart.
Unfortunately, at the moment, there doesn't seem to be any way to embed a Swing component in JavaFX
making this:
chartSwingNode.setContent(
new ChartPanel(
generatePieChart()
)
);
brings this error only when running (the code compiles):
>
Exception in thread "AWT-EventQueue-0" java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key Save_as
at java.util.ResourceBundle.getObject(ResourceBundle.java:450)
at java.util.ResourceBundle.getString(ResourceBundle.java:407)
at org.jfree.chart.ChartPanel.createPopupMenu(ChartPanel.java:2785)
at org.jfree.chart.ChartPanel.(ChartPanel.java:577)
at org.jfree.chart.ChartPanel.(ChartPanel.java:523)
at org.jfree.chart.ChartPanel.(ChartPanel.java:426)
Related
I'm trying to implement an Editor with hint text functionality for a Xamarin.Forms project. This is trivial in Android, because the underlying EntryEditText control has a Hint property. In iOS, the implementation is a bit more complex because the UITextView class does not implement hint text.
I don't like the technique, "set text to the placeholder, clear it if typing starts, return it if typing ends and the text is blank". It means I have to do extra work to tell if the control's blank, and there's a lot of fiddling with the text color involved. But I've been having so much trouble I'm going to have to resort to it. Maybe someone can help me with this.
I started with the answer to Placeholder in UITextView. I started a new Xamarin iOS project and stumbled through a rough Obj-C to C# conversion, and it worked great with a minor change: the Font property of the UITextView isn't initialized yet in the constructor, so I had to override AwakeFromNib() to set the placeholder label's font. I tested it and it worked, so I brought that file into a Xamarin Forms project, and things started getting a little nutty.
The first problem is it turns out apparently MonoTouch has some slight API differences in Xamarin Forms, such as using some types like RectangleF instead of CGRect. This was obvious, if not unexpected. I've been wrestling with some other differences for the past few days, and can't seem to overcome them in a way that makes me happy. Here's my file, trimmed down significantly because I've been trying all kinds of debugging things:
using System;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using MonoTouch.CoreGraphics;
using System.Drawing;
namespace TestCustomRenderer.iOS {
public class PlaceholderTextView : UITextView {
private UILabel _placeholderLabel;
private NSObject _notificationToken;
private const double UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
private string _placeholder;
public string Placeholder {
get {
return _placeholder;
}
set {
_placeholder = value;
if (_placeholderLabel != null) {
_placeholderLabel.Text = _placeholder;
}
}
}
public PlaceholderTextView() : base(RectangleF.Empty) {
Initialize();
}
private void Initialize() {
_notificationToken = NSNotificationCenter.DefaultCenter.AddObserver(TextDidChangeNotification, HandleTextChanged);
_placeholderLabel = new UILabel(new RectangleF(8, 8, this.Bounds.Size.Width - 16, 25)) {
LineBreakMode = UILineBreakMode.WordWrap,
Lines = 1,
BackgroundColor = UIColor.Green,
TextColor = UIColor.Gray,
Alpha = 1.0f,
Text = Placeholder
};
AddSubview(_placeholderLabel);
_placeholderLabel.SizeToFit();
SendSubviewToBack(_placeholderLabel);
}
public override void DrawRect(RectangleF area, UIViewPrintFormatter formatter) {
base.DrawRect(area, formatter);
if (Text.Length == 0 && Placeholder.Length > 0) {
_placeholderLabel.Alpha = 1;
}
}
private void HandleTextChanged(NSNotification notification) {
if (Placeholder.Length == 0) {
return;
}
UIView.Animate(UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION, () => {
if (Text.Length == 0) {
_placeholderLabel.Alpha = 1;
} else {
_placeholderLabel.Alpha = 0;
}
});
}
public override void AwakeFromNib() {
base.AwakeFromNib();
_placeholderLabel.Font = this.Font;
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (disposing) {
NSNotificationCenter.DefaultCenter.RemoveObserver(_notificationToken);
_placeholderLabel.Dispose();
}
}
}
}
A notable change here is relocation of the label's initialization from DrawRect() to the constructor. As far as I can tell, Xamarin never lets DrawRect() be called. You'll also note I'm not setting the Font property. It turned out in the iOS MonoTouch project, sometimes the parent's font was null and it's illegal to set the label's font to null as well. It seems at some point after construction Xamarin sets the font, so it's safe to set that property in AwakeFromNib().
I wrote a quick Editor-derived class and a custom renderer so Xamarin Forms could render the control, the Renderer is slightly of note because I derived from NativeRenderer instead of EditorRenderer. I needed to call SetNativeControl() from an overridden OnModelSet(), but peeking at the assembly viewer showed that EditorRenderer makes some private calls I'll have to re-implement in mine. Boo. Not posted because this is already huge, but I can edit it in if needed.
The code above is notable because the placeholder isn't visible at all. It looks like in iOS-oriented MonoTouch, you typically initialize a control with a frame, and resizing is a rare enough circumstance you can assume it doesn't happen. In Xamarin Forms, layout is performed by layout containers, so a constructor-provided frame is irrelevant. However, the size of the label is intended to be set in the constructor, so it ends up having negative width. Whoops.
I assumed this could be solved by moving instantiation of the label into AwakeFromNib(), or at least sizing it there. This is when I discovered that for some reason, AwakeFromNib() isn't called in the control. Welp. I tried to find an equivalent callback/event that happened late enough for the bounds to be set, but couldn't find anything on the iOS side. After trying many, many things, I noticed the custom renderer received property change events for the Xamarin Forms Model side of this mess. So, if I listen for Height/Width change events, I can then call a method on the label to give it a reasonable size based on the current control. That exposed another problem.
I cannot find a way to set the label's font to match the UITextView's font. In the constructor, the Font property is null. This is true in both the iOS and Xamarin Forms project. In the iOS project, by the time AwakeFromNib() is called, the property is initialized and all is well. In the XF project, it's never called, and even when I pull stunts like invoking a method from a 5-second delayed Task (to ensure the control is displayed), the property remains null.
Logic and iOS documentation dictates the default value for the font should be 17-point Helvetica. This is true for the placeholder label if I fudge the size so it's visible. It is not true for the UITextView control, though since it reports its font as null I'm unable to see what the font actually is. If I manually set it all is well, of course, but I'd like to be able to handle the default case. This seems like a bug; the box seems to be lying about its font. I have a feeling it's related to whatever reason the Xamarin.Forms.Editor class doesn't have a Font property.
So I'm looking for the answer to two questions:
If I'm extending an iOS control in XF to add a subview, what is the best way to handle sizing that subview? I've found Height/Width changes raise events in the renderer, is this the only available way?
When the property has not been set by a user, is the Font of a UITextView in Xamarin Forms ever set to a non-null value? I can live with a requirement that this control requires the font to be explicitly set, but it's yucky and I'd like to avoid it.
I'm hoping I've missed something obvious because I started barking up the wrong trees.
If I'm extending an iOS control in XF to add a subview, what is the
best way to handle sizing that subview? I've found Height/Width
changes raise events in the renderer, is this the only available way?
This is the only way I know of since the exposed elements of the renderer are so limited.
When the property has not been set by a user, is the Font of a
UITextView in Xamarin Forms ever set to a non-null value? I can live
with a requirement that this control requires the font to be
explicitly set, but it's yucky and I'd like to avoid it.
No, the Font is not assigned a default non-null value.
I have a button on an XPage where I want to connect to a remote OpenOffice instance. OpenOffice is started and is listening for a socket connection.
The onclick event of the button runs following SSJS:
oo = new com.test.OpenOffice();
oo.init("host=127.0.0.1,port=8107");
oo.openFile("C:\\TEMP\\Test.odt");
The code raises an excepction jva.lang.IlleagalStateException: NotesContext not initialized for the thread
The exception is raised within the method initof the class OpenOffice.
The relevant parts of the class OpenOffice is the following code:
public class DHOpenOffice implements Serializable {
private static final long serialVersionUID = -7443191805456329135L;
private XComponentContext xRemoteContext;
private XMultiComponentFactory xMCF;
private XTextDocument oTextDocument;
public DHOpenOffice() {
xRemoteContext = null;
xMCF = null;
oTextDocument = null;
}
public void init(String hostAdr) throws java.lang.Exception {
xRemoteContext = null;
XComponentContext xLocalContext = Bootstrap.createInitialComponentContext(null);
XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext);
String sConnect = "uno:socket," + hostAdr + ",tcpNoDelay=0;urp;StarOffice.ServiceManager";
Object context = xUrlResolver.resolve(sConnect);
xRemoteContext = UnoRuntime.queryInterface(XComponentContext.class, context);
xMCF = xRemoteContext.getServiceManager();
}
The code line Object context = xUrlResolver.resolve(sConnect); is the one that raises the exception.
Why is this happing? What is the reason for this exception and how can I resolve the situation?
N.B.: The class code runs smoothly in a standalone application. The error occurs only when the code is started by a SSJS code.
It looks like a threading issue. There are a number of things you can go and try:
Wrap the whole interaction into a custom class and use it from a managed bean instead of calling it from SSJS
Make sure not to hand over any Notes objects into the custom class, only your own
Check if the Open Document Toolkit would be sufficient to do the operations you are interested in, so you don't need to run OO
let us know how it goes
Update
Try to get outside the standard XPages cycle. One way is to deploy a custom plug-in servlet:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class OpenOfficeServlet extends HttpServlet {
// Your code goes here
}
You need to get the plugin.xml right:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension point="org.eclipse.equinox.http.registry.servlets">
<servlet alias="/ooproxy" class="com.yourcompany.OpenOfficeServlet" />
</extension>
</plugin>
Then you could e.g. post a JSON structure or a serializable Java object to the servlet with the data and process it there (async if necessary). You deploy such a plug-in using the updatesite.nsf
Thanks to the answer of #stwissel I was able to solve the problem (he pointed me to the right direction).
I could solve the problem with a simple OSGI plug-in. The servlet approach solved the problem, too, but for me the OSGI plug-in was easier to use.
So these are the steps to create the plug-in
start a new plugin project
copy the open office jar files into the project and include them into the build path
copy the custom class that uses the UNO API into the plug-in
create a feature project for the plugin
create an update site
deploy the plugin via an update site
The following site where also quite helpfull:
Creating an XPages Library
Wrap an existing JAR file into a plug-in
I'm using Lwuit to develop app on nokia s40 SDK 2.0
I have to add a Map to my application..
So i hav used the code given below but the screen doesnot display anything.
I get a blank screen. How can I display this on lwuit form or container?
(the code runs completely and exits without errors & 'END' is printed)
ApplicationContext.getInstance().setAppID("ruKXq--------Sbgq");
ApplicationContext.getInstance().setToken("kWRp_Vp---------AG7rw");
Display display = Display.getDisplay(COMPANY_Midlet.getInstance());
MapCanvas mapCanvas = new MapCanvas(display) {
public void onMapUpdateError(String description,
Throwable detail, boolean critical) {
// Error handling goes here.
}
public void onMapContentComplete() {
}
};
mapCanvas.getMapDisplay().setState(
new MapDisplayState(new GeoCoordinate(52.51, 13.4, 0), 10));
System.out.println(mapCanvas.getMapDisplay().getState());
display.setCurrent(mapCanvas);
System.out.println("END");
Architecturally the most elegant way would be to create a custom LWUIT component which encapsulates the MapCanvas and exposes a standard LWUIT interface - in other words basic use of an adaptor pattern. There is an example of this pattern to be found within the Nokia Projects Tourist Attractions example (the version updated for LWUIT). Additionally sample code for such a component can be found on GIT hub here
I am using GWTP. I did the nested presenter tutorial. But there is no tutorial for the SAMPLE TAB application (the one with the admin tab appearing if you switch to the admin mode). Can somebody explain me the main concepts of this application ? Tkx.
Update: Update: Now you can download the workable sample Maven project from here: gwtp-sample-tab.zip
I used the tabbed presenter feature successfully in my project (I found the sample code didn't compile as well). I think the first thing is to make it work, and then learn it and feel the benefits gradually :)
Here is the steps I did:
1) Copy the following files
BaseTab.java
BaseTabPanel.java
SimpleTab.java
SimpleTabPanel.java
SimpleTab.ui.xml
SimpleTabPanel.ui.xml
UiModule.java
from the sample code to you project. For example, I copied to this package: com.widenhome.web.client.ui. Also please remember to configure UiModule in ClientGinjector class.
2) Create a normal presenter (MyPresenter) via GWTP eclipse plugin
3) Change EventBus import this in the presenter
import com.google.web.bindery.event.shared.EventBus;
4) Make sure the MyPresenterView.ui.xml has the following code or similar:
<g:HTMLPanel>
<npui:SimpleTabPanel ui:field="tabPanel" />
<g:SimplePanel ui:field="contentPanel" />
</g:HTMLPanel>
5) Change the presenter to extend TabContainerPresenter instead of Presenter
public class MyPresenter extends
TabContainerPresenter<MyPresenter.MyView, MyPresenter.MyProxy>
6) Define several variables in MyPresenter, or you can just copy/paste the following code:
/**
* This will be the event sent to our "unknown" child presenters, in order
* for them to register their tabs.
*/
#RequestTabs
public static final Type<RequestTabsHandler> TYPE_RequestTabs = new Type<RequestTabsHandler>();
/**
* Fired by child proxie's when their tab content is changed.
*/
#ChangeTab
public static final Type<ChangeTabHandler> TYPE_ChangeTab = new Type<ChangeTabHandler>();
/**
* Use this in leaf presenters, inside their {#link #revealInParent} method.
*/
#ContentSlot
public static final Type<RevealContentHandler<?>> TYPE_SetTabContent = new Type<RevealContentHandler<?>>();
7) Change the constructor of MyPresenter to use the variables:
#Inject
public MyPresenter(final EventBus eventBus, final MyView view, final MyProxy proxy) {
super(eventBus, view, proxy, TYPE_SetTabContent, TYPE_RequestTabs, TYPE_ChangeTab);
}
8) Now we can start to create tab presenters, (e.g MyFirstTabPresenter). Just create a normal presenter again via GWTP eclipse plugin
9) In MyFirstTabPresenter, change MyProxy to let it 'extends' TabContentProxyPlace instead of ProxyPlace
10) Create #TabInfo method, please see javadoc of #TabInfo annotation, you can also use other ways here. For example, I did this:
#TabInfo(container = MyPresenter.class)
static TabData getTabLabel(ClientGinjector ginjector) {
return new TabDataBasic("My First Tab", 0);
}
11) In revealInParent() method of MyFirstTabPresenter class, please make sure it has the following code or similar:
#Override
protected void revealInParent() {
RevealContentEvent.fire(this, MyPresenter.TYPE_SetTabContent, this);
}
That's all related to Tabbed presenter configurations. Now you can add some logic to load some data to show in MyFirstPresenter's view.
I hope this can help you to start with GWTP Tabbed presenter, please let me know any issues you have, I will edit answer gradually and perfect it so that it can help more people to get started with it.
BTW, I also posted this to my blog to help more people on this.
Thanks,
Jiakuan
It doesn't even compile. The only way to trigger multiple presenters in via Nested Presenters - which is tooooo complicated. I built a multiple presenter app with simple GWT History mechanism without any pain. This framework has made GWT History (s aimple mechanism) a very esoteric thing.
I have a Bitmap that I want to enlarge programatically to ~1.5x or 2x to its original size. Is there an easy way to do that under .NET CF 2.0?
One "normal" way would be to create a new Bitmap of the desired size, create a Graphics for it and then draw the old image onto it with Graphics.DrawImage(Point, Rectangle). Are any of those calls not available on the Compact Framework?
EDIT: Here's a short but complete app which works on the desktop:
using System;
using System.Drawing;
class Test
{
static void Main()
{
using (Image original = Image.FromFile("original.jpg"))
using (Bitmap bigger = new Bitmap(original.Width * 2,
original.Height * 2,
original.PixelFormat))
using (Graphics g = Graphics.FromImage(bigger))
{
g.DrawImage(original, new Rectangle(Point.Empty, bigger.Size));
bigger.Save("bigger.jpg");
}
}
}
Even though this works, there may well be better ways of doing it in terms of interpolation etc. If it works on the Compact Framework, it would at least give you a starting point.
The CF has access to the standard Graphics and Bitmap objects like the full framework.
Get the original image into a Bitmap
Create a new Bitmap of the desired size
Associate a Graphics object with the NEW Bitmap
Call g.DrawImage() with the old image and the overload to specify width/height
Dispose of things
Versions:
.NET Compact Framework
Supported in: 3.5, 2.0, 1.0