CodenameOne Charts not rendering well when sharing or simulator screen capture - codenameone

The recent updates draw the lines on the charts when sharing, but the chart seems to get a bit mangled both when shared and when doing a screen capture on the simulator. The legend gets rotated and moved into the grid area, the title is missing, and there is a yellow outline that runs through the grid area.
Different chart renderings. The far right image got mirrored somehow when I pasted it, it isn't actually a mirror-image when shared.
Here is a test case:
package com.fastlaneinnovations.chartexample;
import com.codename1.charts.ChartComponent;
import com.codename1.charts.models.XYMultipleSeriesDataset;
import com.codename1.charts.models.XYSeries;
import com.codename1.charts.renderers.XYMultipleSeriesRenderer;
import com.codename1.charts.renderers.XYSeriesRenderer;
import com.codename1.charts.util.ColorUtil;
import com.codename1.charts.views.LineChart;
import com.codename1.components.ShareButton;
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Log;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.ImageIO;
import com.codename1.ui.util.Resources;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Set;
public class ChartExample {
private Form current;
private Resources theme;
private XYMultipleSeriesRenderer chartRenderer;
private Container rpmChartContainer;
private XYSeries series;
private LineChart lineChart;
private ChartComponent chart;
private Hashtable<Long, Integer> chartData;
private String chartName = "Chart";
private String path;
private Object os;
private int chartHeight;
private int chartWidth;
private ShareButton share;
private Set<Long> keys;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if (current != null) {
current.show();
return;
}
Form form = new Form();
form.setLayout(new BorderLayout());
chartData = new Hashtable<Long, Integer>();
for (int i = 0; i < 8000; i += 100) {
chartData.put(Long.valueOf(i), Integer.valueOf(i));
}
rpmChartContainer = new Container();
rpmChartContainer.setLayout(new BorderLayout());
series = new XYSeries("RPM");
chartRenderer = createChartRenderer();
setChartSettings(chartRenderer, "RPM vs Time", "Time (s)", "RPM", 0.0,
10.0, 0.0, 8000.0, ColorUtil.YELLOW, ColorUtil.WHITE);
lineChart = new LineChart(buildDataSet(series), chartRenderer);
chart = new ChartComponent(lineChart);
chart.setUIID("ChartComponent");
rpmChartContainer.addComponent(BorderLayout.CENTER, chart);
updateChart();
share = new ShareButton();
share.setName(chartName);
share.setText("Share this chart");
share.setTextToShare("RPM chart created by R-P-M Control Center app");
rpmChartContainer.add(BorderLayout.SOUTH, share);
form.add(BorderLayout.CENTER, rpmChartContainer);
form.show();
createShareButton();
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
}
public void updateChart() {
keys = chartData.keySet();
series.clear();
for (Long key : keys) {
series.add((key / 1000.0), (chartData.get(key) / 1.0));
}
}
private XYMultipleSeriesRenderer createChartRenderer() {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
renderer.setPointSize(3f);
XYSeriesRenderer seriesRenderer = new XYSeriesRenderer();
seriesRenderer.setColor(ColorUtil.GREEN);
// seriesRenderer.setPointStyle(PointStyle.CIRCLE);
// seriesRenderer.setFillPoints(true);
seriesRenderer.setLineWidth(5f);
seriesRenderer.setShowLegendItem(true);
renderer.addSeriesRenderer(seriesRenderer);
return renderer;
}
private XYMultipleSeriesDataset buildDataSet(XYSeries dataSeries) {
XYMultipleSeriesDataset multiDataSet = new XYMultipleSeriesDataset();
multiDataSet.addSeries(dataSeries);
return multiDataSet;
}
private void setChartSettings(XYMultipleSeriesRenderer renderer,
String title, String xTitle, String yTitle, double xMin,
double xMax, double yMin, double yMax, int axesColor,
int labelsColor) {
renderer.setChartTitle(title);
renderer.setXTitle(xTitle);
renderer.setYTitle(yTitle);
renderer.setXAxisMin(xMin);
// renderer.setXAxisMax(xMax);
renderer.setYAxisMin(yMin);
renderer.setYAxisMax(yMax);
renderer.setAxesColor(axesColor);
renderer.setLabelsColor(labelsColor);
renderer.setMarginsColor(ColorUtil.BLACK);
renderer.setGridColor(ColorUtil.BLACK);
}
public void createShareButton() {
rpmChartContainer.revalidate();
chartWidth = rpmChartContainer.getWidth();
chartHeight = rpmChartContainer.getHeight();
Image chartAsImage = Image.createImage(chartWidth, chartHeight);
rpmChartContainer.paint(chartAsImage.getGraphics());
setShareImage(share, chartAsImage);
}
public void setShareImage(ShareButton shareButton, Image shareImage) {
OutputStream os = null;
final String shareImagePath = FileSystemStorage.getInstance()
.getAppHomePath() + shareButton.getName();
FileSystemStorage.getInstance().delete(shareImagePath);
try {
os = FileSystemStorage.getInstance().openOutputStream(
shareImagePath);
ImageIO.getImageIO().save(shareImage, os, ImageIO.FORMAT_JPEG,
0.95f);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
shareButton.setImageToShare(shareImagePath, "image/jpeg");
}
}

In implementing the 2D transformations on iOS mutable images, I fixed some bugs related to transforms on mutable images in the simulator. You may not have these until the next plugin update.
As for the third image on the right in your screenshot. What device was that from? Can you share a test case with your chart so I can test it out?

Related

JFreeChart get getWidth() returns 0.0

I' m using the ChartPanel class from JFreeChart and want to know the width of the plot's data area.
The returned value from the method chartPanel.getChartRenderingInfo().getPlotInfo().getDataArea().getWidth() is 0.0d.
I'm using the JFreeChart version 1.5.0.
My suspicion was a thread-problem, which means that the plotting isn't finished, when I call the .getWidth()-method. So I tried to use ChartChange events, but the result is always a width of 0.0 pixels.
Here is a short example class I created to Show the Problem:
The println in the main() gives "xAxisLengthInPixels = 0.0":
package jFreeChartTest;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
public class Panel_Chart extends JFrame implements ChartChangeListener {
private ChartPanel chartPanel = null;
private int width = 1024;
private int height = 820;
public Panel_Chart() {
this.setTitle("XY Plot");
setBounds(0, 0, width, height);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
XYSeries testXYSeries = new XYSeries("Test-Series", true);
testXYSeries.add(4,10);
testXYSeries.add(5,20);
testXYSeries.add(6,30);
xySeriesCollection.addSeries(testXYSeries);
boolean includeLegend = true;
boolean useTooltips = true;
boolean useUrls = true;
JFreeChart chart = ChartFactory.createScatterPlot(//createXYLineChart(
"",
"X-Axis",
"Y-Axis",
xySeriesCollection,
PlotOrientation.VERTICAL,
includeLegend,
useTooltips,
useUrls);
this.chartPanel = new ChartPanel(chart);
getContentPane().add(chartPanel, BorderLayout.PAGE_START);
}
public Double getXAxisLengthInPixels(){
return chartPanel.getChartRenderingInfo().getPlotInfo().getDataArea().getWidth();
}
#Override
public void chartChanged(ChartChangeEvent arg0) {
// TODO Auto-generated method stub
System.out.println("ChartChangeEvent:" + arg0);
}
public static void main(String[] args){
Panel_Chart panelChart = new Panel_Chart();
panelChart.setVisible(true);
System.out.println("xAxisLengthInPixels = " + panelChart.getXAxisLengthInPixels());
}
}

Unusual Crop/GeneralPath behaviour in CodenameOne

I created a minor crop image app which crops the set image in a closed free path defined by the user (closed by joining the starting and ending point). This app is depicting unusual behavior when cropping in different path directions (clockwise and anticlockwise). Can anyone explain why is this happening and how to rectify this problem?
The following is the code:-
My own defined GeneralPath class
package com.mycompany.myapp;
import com.codename1.charts.util.ColorUtil;
import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Graphics;
import com.codename1.ui.Stroke;
public class GeneralPath extends Component{
com.codename1.ui.geom.GeneralPath generalPath;
Stroke stroke = new Stroke();
int firstPointX = 0, firstpointY = 0;
MyApplication myApplication;
public GeneralPath(MyApplication application) {
// TODO Auto-generated constructor stub
generalPath = new com.codename1.ui.geom.GeneralPath();
stroke.setLineWidth(Math.max(1, Display.getInstance().convertToPixels(1, true)/2));
getAllStyles().setBgColor(0xffffff);
getAllStyles().setBgTransparency(200);
myApplication = application;
}
#Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
paintDrawing(g);
}
private void paintDrawing(Graphics g)
{
g.setColor(ColorUtil.argb(0, 255, 255, 255));
boolean oldAA = g.isAntiAliased();
g.setAntiAliased(true);
g.drawShape(generalPath, stroke);
g.setAntiAliased(oldAA);
}
#Override
public void pointerPressed(int a, int b) {
firstPointX = a;
firstpointY = b;
generalPath.moveTo(x(a), y(b));
}
#Override
public void pointerDragged(int a, int b) {
generalPath.lineTo(x(a), y(b));
}
#Override
public void pointerReleased(int x, int y) {
generalPath.lineTo(x(firstPointX), y(firstpointY));
myApplication.clip();
}
public int x(int x)
{
return x-getParent().getAbsoluteX();
}
public int y(int y)
{
return y - getParent().getAbsoluteY();
}
public com.codename1.ui.geom.GeneralPath getPath()
{
return generalPath;
}
}
MyApplication.java (main class)
package com.mycompany.myapp;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.Stroke;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.geom.GeneralPath;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.util.UITimer;
import java.io.IOException;
import com.codename1.ui.Toolbar;
import com.codename1.ui.geom.Rectangle;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
Form hi;
com.mycompany.myapp.GeneralPath gp;
Image finalDuke;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if(current != null){
current.show();
return;
}
// Form hi = new Form("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
// final Label apple = new Label(theme.getImage("apple-icon.png"));
// final Label android = new Label(theme.getImage("android-icon.png"));
// final Label windows = new Label(theme.getImage("windows-icon.png"));
// Button getStarted = new Button("Let's Get Started!");
// FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK);
// getStarted.setUIID("GetStarted");
// hi.addComponent(BorderLayout.CENTER,
// LayeredLayout.encloseIn(
// BoxLayout.encloseY(
// new Label(theme.getImage("duke-no-logos.png")),
// getStarted
// ),
// FlowLayout.encloseRightMiddle(apple)
// )
// );
//
// getStarted.addActionListener((e) -> {
// Display.getInstance().execute("https://www.codenameone.com/developers.html");
// });
//
// new UITimer(() -> {
// if(apple.getParent() != null) {
// apple.getParent().replace(apple, android, CommonTransitions.createFade(500));
// } else {
// if(android.getParent() != null) {
// android.getParent().replace(android, windows, CommonTransitions.createFade(500));
// } else {
// windows.getParent().replace(windows, apple, CommonTransitions.createFade(500));
// }
// }
// }).schedule(2200, true, hi);
Image duke = null;
try {
// duke.png is just the default Codename One icon copied into place
duke = theme.getImage("promo_5.png");
} catch(Exception err) {
Log.e(err);
}
finalDuke = duke;
hi = new Form("Shape Clip", new BorderLayout());
// We create a 50 x 100 shape, this is arbitrary since we can scale it easily
// GeneralPath path = new GeneralPath();
// path.moveTo(20,0);
// path.lineTo(30, 0);
// path.lineTo(30, 100);
// path.lineTo(20, 100);
// path.lineTo(20, 15);
// path.lineTo(5, 40);
// path.lineTo(5, 25);
// path.lineTo(20,0);
gp = new com.mycompany.myapp.GeneralPath(this);
hi.add(BorderLayout.CENTER,gp);
hi.getLayeredPane().add(finalDuke);
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
public void clip()
{
Stroke stroke = new Stroke(0.5f, Stroke.CAP_ROUND, Stroke.JOIN_ROUND, 4);
// hi.getContentPane().getUnselectedStyle().setBgPainter((Graphics g, Rectangle rect) -> {
// g.setColor(0xff0000);
// float widthRatio = ((float)rect.getWidth()) / 50f;
// float heightRatio = ((float)rect.getHeight()) / 100f;
// g.scale(widthRatio, heightRatio);
// g.translate((int)(((float)rect.getX()) / widthRatio), (int)(((float)rect.getY()) / heightRatio));
// g.setClip(gp.getPath());
// g.setAntiAliased(true);
// g.drawImage(finalDuke, 0, 0, 50, 100);
// g.setClip(gp.getPath().getBounds());
// g.drawShape(gp.getPath(), stroke);
// g.translate(-(int)(((float)rect.getX()) / widthRatio), -(int)(((float)rect.getY()) / heightRatio));
// g.resetAffine();
// });
hi.getContentPane().getAllStyles().setBgPainter((Graphics g, Rectangle rect) -> {
g.drawShape(gp.getPath(), stroke);
g.setClip(gp.getPath());
Image image = finalDuke;
g.drawImage(image, 0, 0);
});
}
}
Please ignore the commented out portions. Thank you
ScreenShots:-
3 overlapping rectangles don't invert the picture during crop but a triangular shape in the opposite direction of that to the rectangle inversely cuts the previous paths
Try calling closePath() in pointerReleased. Even the user is almost closing the path manually, it might not really be closed. If you try to use an unclosed shape as a clip shape you'll get unexpected results.

Rotate a fontImage in codenameone

Image shareIcon = FontImage.createMaterial(FontImage.MATERIAL_REPLY, s);
shareIcon = shareIcon.rotate(180);
ShareButton shareButton = new ShareButton();
shareButton.setIcon(shareIcon);
How can I flip the image here? The rotate method does nothing.
The answer below by shai doesn't work in my project
package com.mycompany.myapp;
import com.codename1.components.ShareButton;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.Button;
import com.codename1.ui.FontImage;
import com.codename1.ui.Image;
import com.codename1.ui.Toolbar;
import com.codename1.ui.layouts.BoxLayout;
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Rotate");
hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Image shareIcon = FontImage.createMaterial(FontImage.MATERIAL_REPLY, new Button("").getUnselectedStyle(), 5);
for (int i = 0; i < 360; i += 45) {
ShareButton s = new ShareButton();
s.setIcon(shareIcon.rotate(i));
hi.add(s);
}
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
if (current instanceof Dialog) {
((Dialog) current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
}
If you want to see the project, heres the project:
https://drive.google.com/open?id=0B8ATnICIY2S8OEtUU2lPSlFid3M
This works for me:
Image shareIcon = FontImage.createMaterial(FontImage.MATERIAL_REPLY, new Button("").getUnselectedStyle(), 5);
for(int i = 0 ; i < 360 ; i += 45) {
ShareButton s = new ShareButton();
s.setIcon(shareIcon.rotate(i));
hi.add(s);
}

XYDataset with a single data point : nothing gets plotted

This is a corner case I encountered. Below's a SSCCE:
import java.util.*;
import java.io.*;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.axis.*;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
public class FooMain {
public static void main(String args[]) throws Exception {
BufferedImage img = timeAxisSSEProcessionsChart();
ImageIO.write(img, "png", new File("img.png"));
System.exit(0);
}
private static XYDataset createTimeSeriesDataset() {
TimeSeries timeSeries = new TimeSeries("series-a");
timeSeries.add(RegularTimePeriod.createInstance(Millisecond.class, new java.util.Date(0) , TimeZone.getTimeZone("Zulu")), 100);
// if below line is commented out, nothing is plotted:
timeSeries.add(RegularTimePeriod.createInstance(Millisecond.class, new java.util.Date(1000), TimeZone.getTimeZone("Zulu")), 100);
TimeSeriesCollection rv = new TimeSeriesCollection();
rv.addSeries(timeSeries);
return rv;
}
public static BufferedImage timeAxisSSEProcessionsChart() throws Exception {
XYDataset dataset = createTimeSeriesDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart("title", "date", "series-a", dataset, true, true, false);
InputStream in = new ByteArrayInputStream(imageBytesFromChart(chart, 600, 400));
return ImageIO.read(in);
}
private static byte[] imageBytesFromChart(JFreeChart chart, int width, int height) {
BufferedImage objBufferedImage = chart.createBufferedImage(width, height);
ByteArrayOutputStream bas = new ByteArrayOutputStream();
try {
ImageIO.write(objBufferedImage, "png", bas);
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray=bas.toByteArray();
return byteArray;
}
}
The above code produces a plot as expected.
If however we comment out the line indicated in the createTimeSeriesDataset method, then nothing gets plotted:
So the question is: how can I ensure that at least a dot (or some other mark) gets printed in the corner case where the XYDataset contains only one data point?
The time series chart primarily consists of lines connecting the individual data points. When there is only one data element, there are no data points to connect. So far, so obvious.
One possible solution would be to enable the "tick shapes" for the chart when there is only one entry. I'm not sure whether this is an appropriate solution for your case. But this could be done with a method like
private static void showTickMarksForSingleElements(
XYDataset dataset, JFreeChart chart)
{
TimeSeriesCollection timeSeriesCollection =
(TimeSeriesCollection)dataset;
List<?> series = timeSeriesCollection.getSeries();
TimeSeries timeSeries = (TimeSeries) series.get(0);
if (timeSeries.getItemCount() == 1)
{
XYPlot plot = (XYPlot) chart.getPlot();
XYLineAndShapeRenderer renderer
= (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setSeriesShapesVisible(0, true);
}
}
(Caution, there are obviously some assumptions about the types of the given objects involved - in doubt, check the types before doing the casts!)
The result would then be a single tick mark for time series that only contain a single element:
Here as another MVCE:
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.TimeZone;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
public class SingleElementChart {
public static void main(String args[]) throws Exception {
BufferedImage img = timeAxisSSEProcessionsChart();
show(img);
}
private static void show(final BufferedImage img)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JLabel(new ImageIcon(img)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private static TimeSeriesCollection createTimeSeriesDataset() {
TimeSeries timeSeries = new TimeSeries("series-a");
timeSeries.add(RegularTimePeriod.createInstance(
Millisecond.class, new java.util.Date(0),
TimeZone.getTimeZone("Zulu")), 100);
// if below line is commented out, nothing is plotted:
//timeSeries.add(RegularTimePeriod.createInstance(
// Millisecond.class, new java.util.Date(1000),
// TimeZone.getTimeZone("Zulu")), 100);
TimeSeriesCollection rv = new TimeSeriesCollection();
rv.addSeries(timeSeries);
return rv;
}
public static BufferedImage timeAxisSSEProcessionsChart() throws Exception {
XYDataset dataset = createTimeSeriesDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"title", "date", "series-a", dataset, true, true, false);
showTickMarksForSingleElements(dataset, chart);
InputStream in = new ByteArrayInputStream(
imageBytesFromChart(chart, 600, 400));
return ImageIO.read(in);
}
private static void showTickMarksForSingleElements(
XYDataset dataset, JFreeChart chart)
{
TimeSeriesCollection timeSeriesCollection =
(TimeSeriesCollection)dataset;
List<?> series = timeSeriesCollection.getSeries();
TimeSeries timeSeries = (TimeSeries) series.get(0);
if (timeSeries.getItemCount() == 1)
{
XYPlot plot = (XYPlot) chart.getPlot();
XYLineAndShapeRenderer renderer
= (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setSeriesShapesVisible(0, true);
}
}
private static byte[] imageBytesFromChart(JFreeChart chart, int width, int height) {
BufferedImage objBufferedImage =
chart.createBufferedImage(width, height);
ByteArrayOutputStream bas = new ByteArrayOutputStream();
try {
ImageIO.write(objBufferedImage, "png", bas);
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray=bas.toByteArray();
return byteArray;
}

Tap events not fired in mgwt

I have just started learning mgwt. After creating a Button and adding a TapHandler, the tap events are not fired. I don't know what is wrong in the code. I have deployed this on GAE and accessing the site on a Android device. Below is the code for onModuleLoad()
import com.citrix.demo.client.css.AppBundle;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.googlecode.mgwt.dom.client.event.tap.TapEvent;
import com.googlecode.mgwt.dom.client.event.tap.TapHandler;
import com.googlecode.mgwt.mvp.client.AnimatableDisplay;
import com.googlecode.mgwt.mvp.client.AnimatingActivityManager;
import com.googlecode.mgwt.mvp.client.Animation;
import com.googlecode.mgwt.mvp.client.AnimationMapper;
import com.googlecode.mgwt.ui.client.MGWT;
import com.googlecode.mgwt.ui.client.MGWTSettings;
import com.googlecode.mgwt.ui.client.MGWTStyle;
import com.googlecode.mgwt.ui.client.animation.AnimationHelper;
import com.googlecode.mgwt.ui.client.dialog.TabletPortraitOverlay;
import com.googlecode.mgwt.ui.client.layout.MasterRegionHandler;
import com.googlecode.mgwt.ui.client.layout.OrientationRegionHandler;
import com.googlecode.mgwt.ui.client.widget.Button;
import com.googlecode.mgwt.ui.client.widget.LayoutPanel;
/**
* #author Daniel Kurka
*
*/
public class MgwtAppEntryPoint implements EntryPoint {
private static LayoutPanel layout = new LayoutPanel();
private void start() {
//set viewport and other settings for mobile
MGWT.applySettings(MGWTSettings.getAppSetting());
final ClientFactory clientFactory = new ClientFactoryImpl();
// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);
final PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(clientFactory.getPlaceController(), clientFactory.getEventBus(), new com.citrix.demo.client.activities.HomePlace());
if ((MGWT.getOsDetection().isTablet())) {
// very nasty workaround because GWT does not correctly support
// #media
StyleInjector.inject(AppBundle.INSTANCE.css().getText());
createTabletDisplay(clientFactory);
} else {
createPhoneDisplay(clientFactory);
}
historyHandler.handleCurrentHistory();
}
private void createPhoneDisplay(ClientFactory clientFactory) {
AnimatableDisplay display = GWT.create(AnimatableDisplay.class);
PhoneActivityMapper appActivityMapper = new PhoneActivityMapper(clientFactory);
PhoneAnimationMapper appAnimationMapper = new PhoneAnimationMapper();
AnimatingActivityManager activityManager = new AnimatingActivityManager(appActivityMapper, appAnimationMapper, clientFactory.getEventBus());
activityManager.setDisplay(display);
RootPanel.get().add(display);
}
private void createTabletDisplay(ClientFactory clientFactory) {
SimplePanel navContainer = new SimplePanel();
navContainer.getElement().setId("nav");
navContainer.getElement().addClassName("landscapeonly");
AnimatableDisplay navDisplay = GWT.create(AnimatableDisplay.class);
final TabletPortraitOverlay tabletPortraitOverlay = new TabletPortraitOverlay();
new OrientationRegionHandler(navContainer, tabletPortraitOverlay, navDisplay);
new MasterRegionHandler(clientFactory.getEventBus(), "nav", tabletPortraitOverlay);
ActivityMapper navActivityMapper = new TabletNavActivityMapper(clientFactory);
AnimationMapper navAnimationMapper = new TabletNavAnimationMapper();
AnimatingActivityManager navActivityManager = new AnimatingActivityManager(navActivityMapper, navAnimationMapper, clientFactory.getEventBus());
navActivityManager.setDisplay(navDisplay);
RootPanel.get().add(navContainer);
SimplePanel mainContainer = new SimplePanel();
mainContainer.getElement().setId("main");
AnimatableDisplay mainDisplay = GWT.create(AnimatableDisplay.class);
TabletMainActivityMapper tabletMainActivityMapper = new TabletMainActivityMapper(clientFactory);
AnimationMapper tabletMainAnimationMapper = new TabletMainAnimationMapper();
AnimatingActivityManager mainActivityManager = new AnimatingActivityManager(tabletMainActivityMapper, tabletMainAnimationMapper, clientFactory.getEventBus());
mainActivityManager.setDisplay(mainDisplay);
mainContainer.setWidget(mainDisplay);
RootPanel.get().add(mainContainer);
}
#Override
public void onModuleLoad() {
GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void onUncaughtException(Throwable e) {
Window.alert("uncaught: " + e.getMessage());
e.printStackTrace();
}
});
new Timer() {
#Override
public void run() {
start();
}
}.schedule(1);
//set viewport and other settings for mobile
MGWT.applySettings(MGWTSettings.getAppSetting());
MGWTStyle.getTheme().getMGWTClientBundle().getMainCss().ensureInjected();
Label label = new Label("Welcome");
label.setAutoHorizontalAlignment(Label.ALIGN_CENTER);
Button button = new Button();
button.setRound(true);
button.setText("Click");
button.addTapHandler(new TapHandler() {
#Override
public void onTap(TapEvent event) {
Window.alert("Hola !");
}
});
layout.add(label);
layout.add(button);
//build animation helper and attach it
AnimationHelper animationHelper = new AnimationHelper();
// RootPanel.get().add(layout);
RootPanel.get().add(animationHelper);
animationHelper.goTo(layout, Animation.POP);
}
}
Can somebody help me out with this ? Thanks..!
You are adding more than one AnimatableDisplays to one region. Those will overlap.
You just added some lines of code to the mgwt showcase I guess without removing the showcase code. To fix this you could remove the call to start() from the timer.

Resources