generate different charts in the same activity using a spinner and achartEngine library - achartengine

I am a novice in android and I am using achartEngine library to draw line Graph. what I want to do is to update the graph by using a spinner. For exmaple, if I chose the first option I will get a yellow graph and when
I swich to the second option in my spinner, the graph changes and becomes white with new title and data
for the moment I can only update the data but not the rest of the graph
package com.example.test2;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.SeriesSelection;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.test2.R;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class Graphique extends Activity {
private GraphicalView mChart1;
private GraphicalView mChart2;
private TimeSeries glecimieSeries ;
private TimeSeries pressionSeries;
private XYMultipleSeriesDataset dataset;
private XYSeriesRenderer glecimieRenderer;
private XYSeriesRenderer pressionRenderer;
private XYMultipleSeriesRenderer multiRenderer;
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>> listeappareil;
// url to get all products list
private static String url_liste_appareil ;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static String TAG_APPAREIL;
private static final String TAG_PID = "pid";
private static final String TAG_NOM = "nom";
private static final String TAG_J = "jour";
private static final String TAG_Y = "Y";
// products JSONArray
JSONArray appareil = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.graphique);
// getting intent data
Intent in = getIntent();
// Get JSON values from previous intent
String pid = in.getStringExtra(TAG_PID);
String nom = in.getStringExtra(TAG_NOM);
// Displaying all values on the screen
TextView lblNom = (TextView) findViewById(R.id.nom_patient);
lblNom.setText(nom);
Spinner mySpinner = (Spinner)findViewById(R.id.mesure);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.appareils, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(adapter);
OnItemSelectedListener selectedGraph = new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> spinner, View container,
int position, long id) {
String graph = spinner.getItemAtPosition(position).toString().toLowerCase();
if(graph == "tensiometre"){
url_liste_appareil = "http://10.0.2.2/connexion_android/"+graph+".php";
TAG_APPAREIL = graph;
// Setting up chart
setupChart2();
// Start plotting chart
new ChartTask2().execute();
}else{
url_liste_appareil = "http://10.0.2.2/connexion_android/"+graph+".php";
TAG_APPAREIL = graph;
// Setting up chart
setupChart1();
// Start plotting chart
new ChartTask1().execute();
}
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
// Setting ItemClick Handler for Spinner Widget
mySpinner.setOnItemSelectedListener(selectedGraph);
}
private void setupChart1(){
// Creating TimeSeries for Glecimie
glecimieSeries = new TimeSeries("Glecimie");
// Creating a dataset to hold each series
dataset = new XYMultipleSeriesDataset();
// Adding Glecimie Series to the dataset
dataset.addSeries(glecimieSeries);
// Creating XYSeriesRenderer to customize glecimieSeries
glecimieRenderer = new XYSeriesRenderer();
glecimieRenderer.setColor(Color.YELLOW);
glecimieRenderer.setPointStyle(PointStyle.CIRCLE);
glecimieRenderer.setFillPoints(true);
glecimieRenderer.setLineWidth(2);
glecimieRenderer.setDisplayChartValues(true);
// Creating a XYMultipleSeriesRenderer to customize the whole chart
multiRenderer = new XYMultipleSeriesRenderer();
multiRenderer.setZoomButtonsVisible(true);
// Adding glecimieRenderer and pressionRenderer to multipleRenderer
// Note: The order of adding dataseries to dataset and renderers to multipleRenderer
// should be same
multiRenderer.addSeriesRenderer(glecimieRenderer);
// Getting a reference to LinearLayout of the MainActivity Layout
LinearLayout chartContainer = (LinearLayout) findViewById(R.id.chart_container);
// Creating a Time Chart
mChart1 = (GraphicalView) ChartFactory.getTimeChartView(getBaseContext(), dataset, multiRenderer,"dd-MMM-yyyy");
multiRenderer.setClickEnabled(true);
multiRenderer.setSelectableBuffer(10);
// Setting a click event listener for the graph
mChart1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Format formatter = new SimpleDateFormat("dd-MMM-yyyy");
SeriesSelection seriesSelection = mChart1.getCurrentSeriesAndPoint();
if (seriesSelection != null) {
int seriesIndex = seriesSelection.getSeriesIndex();
String selectedSeries="Glecimie";
if(seriesIndex==0)
selectedSeries = "Glecimie";
else
selectedSeries = "Pression";
// Getting the clicked Date ( x value )
long clickedDateSeconds = (long) seriesSelection.getXValue();
Date clickedDate = new Date(clickedDateSeconds);
String strDate = formatter.format(clickedDate);
// Getting the y value
int amount = (int) seriesSelection.getValue();
// Displaying Toast Message
Toast.makeText(
getBaseContext(),
"Prélèvement au " + strDate + " : " + amount ,
Toast.LENGTH_SHORT).show();
}
}
});
chartContainer.removeAllViews();
// Adding the Line Chart to the LinearLayout
chartContainer.addView(mChart1);
}
private class ChartTask1 extends AsyncTask<String, String, String>{
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Graphique.this);
pDialog.setMessage("Loading data. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
// Generates dummy data in a non-ui thread
protected String doInBackground(String... params) {
// Building Parameters
List<NameValuePair> param = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_liste_appareil, "GET", param);
// Check your log cat for JSON reponse
Log.d("Tous les appareil: ", json.toString());
try{
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
appareil = json.getJSONArray(TAG_APPAREIL);
Date[] dt = new Date[appareil.length()];
// looping through All Products
for (int j = 0; j < appareil.length(); j++) {
JSONObject p = appareil.getJSONObject(j);
// Storing each json item in variable
GregorianCalendar gc = new GregorianCalendar(2012, 10, j+1);
dt[j] = gc.getTime();
String y = p.getString(TAG_Y);
String jr = p.getString(TAG_J);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(jr);
// Adding data to Glecimie and Pression Series
glecimieSeries.add(d,Double.parseDouble(y));
multiRenderer.setXTitle("Dates");
multiRenderer.setYTitle("Prélèvements");
}
}
}catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// Plotting generated data in the graph
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into the graph
* */
mChart1.repaint();
}
});
}
}
private void setupChart2(){
// Creating TimeSeries for Pression
pressionSeries = new TimeSeries("Pression");
// Creating a dataset to hold each series
dataset = new XYMultipleSeriesDataset();
// Adding Glecimie Series to dataset
dataset.addSeries(pressionSeries);
// Creating XYSeriesRenderer to customize pressionSeries
pressionRenderer = new XYSeriesRenderer();
pressionRenderer.setColor(Color.YELLOW);
pressionRenderer.setPointStyle(PointStyle.CIRCLE);
pressionRenderer.setFillPoints(true);
pressionRenderer.setLineWidth(2);
pressionRenderer.setDisplayChartValues(true);
// Creating a XYMultipleSeriesRenderer to customize the whole chart
multiRenderer = new XYMultipleSeriesRenderer();
multiRenderer.setZoomButtonsVisible(true);
// Adding glecimieRenderer and pressionRenderer to multipleRenderer
// Note: The order of adding dataseries to dataset and renderers to multipleRenderer
// should be same
multiRenderer.addSeriesRenderer(pressionRenderer);
// Getting a reference to LinearLayout of the MainActivity Layout
LinearLayout chartContainer = (LinearLayout) findViewById(R.id.chart_container);
// Creating a Time Chart
mChart2 = (GraphicalView) ChartFactory.getTimeChartView(getBaseContext(), dataset, multiRenderer,"dd-MMM-yyyy");
multiRenderer.setClickEnabled(true);
multiRenderer.setSelectableBuffer(10);
// Setting a click event listener for the graph
mChart2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Format formatter = new SimpleDateFormat("dd-MMM-yyyy");
SeriesSelection seriesSelection = mChart2.getCurrentSeriesAndPoint();
if (seriesSelection != null) {
int seriesIndex = seriesSelection.getSeriesIndex();
String selectedSeries="Glecimie";
if(seriesIndex==0)
selectedSeries = "Glecimie";
else
selectedSeries = "Pression";
// Getting the clicked Date ( x value )
long clickedDateSeconds = (long) seriesSelection.getXValue();
Date clickedDate = new Date(clickedDateSeconds);
String strDate = formatter.format(clickedDate);
// Getting the y value
int amount = (int) seriesSelection.getValue();
// Displaying Toast Message
Toast.makeText(
getBaseContext(),
" Prélèvement au" + strDate + " : " + amount ,
Toast.LENGTH_SHORT).show();
}
}
});
chartContainer.removeAllViews();
// Adding the Line Chart to the LinearLayout
chartContainer.addView(mChart2);
}
private class ChartTask2 extends AsyncTask<String, String, String>{
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Graphique.this);
pDialog.setMessage("Loading data. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
// Generates dummy data in a non-ui thread
protected String doInBackground(String... params) {
// Building Parameters
List<NameValuePair> param = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_liste_appareil, "GET", param);
// Check your log cat for JSON reponse
Log.d("Tous les appareil: ", json.toString());
try{
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
appareil = json.getJSONArray(TAG_APPAREIL);
Date[] dt = new Date[appareil.length()];
// looping through All Products
for (int j = 0; j < appareil.length(); j++) {
JSONObject p = appareil.getJSONObject(j);
// Storing each json item in variable
GregorianCalendar gc = new GregorianCalendar(2012, 10, j+1);
dt[j] = gc.getTime();
String y = p.getString(TAG_Y);
String jr = p.getString(TAG_J);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(jr);
// Adding data to Glecimie and Pression Series
pressionSeries.add(d,Double.parseDouble(y));
multiRenderer.setChartTitle("la pression");
multiRenderer.setXTitle("Dates");
multiRenderer.setYTitle("Prélèvements");
}
}
}catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// Plotting generated data in the graph
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into the graph
* */
mChart2.repaint();
}
});
}
}
// Initiating Menu XML file (menu.xml)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_graphique, menu);
return (super.onCreateOptionsMenu(menu));
}
}
Please help

In order to refresh both charts, you need to call repaint on both:
mChart1.repaint();
mChart2.repaint();

You can update the color and other values of the chart by passing values.
In openChart() method you can pass the values.
private void openChart(final String[] code, final int[] distribution,final int color){
defaultRenderer.setBackgroundColor(color);
}

Related

How to extract date from tweets with lucene?

I have some tweets that I have already indexed "TweetIndexer" with lucene knowing that each tweet contains an ID, USER, TEXT, and DATE.
I want to only retrieve the date with another class "TweetSearcher" how to proceed?
Example of tweet:
"0","1467811372","Mon Apr 06 22:20:00 PDT 2009","NO_QUERY","joy_wolf","#Kwesidei not the whole crew ".
This my class TweetIndexer:
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TweetIndexer {
protected static final String COMMA = "\",\"";
protected static final String POLARITY = "polarity";
protected static final String ID = "id";
protected static final String DATE = "date";
protected static final String QUERY = "query";
protected static final String USER = "user";
protected static final String TEXT = "text";
public static void main(String[] args) throws Exception {
try {
String indexDir = "D:\\tweet\\index";
String dataFile = "D:\\tweet\\collection\\tweets.csv";
TweetIndexer tweetIndexer = new TweetIndexer();
long start = System.currentTimeMillis();
int count = tweetIndexer.index(new File(indexDir), new File(dataFile));
System.out.print(String.format("Indexed %d documents in %d seconds", count, (System.currentTimeMillis() - start) / 1000));
}
catch (Exception e) {
System.out.println("Usage: java TweetIndexer <index directory> <csv data file>");
}
}
private int index(File indexDir, File dataFile) throws Exception {
IndexWriter indexWriter = new IndexWriter(
FSDirectory.open(indexDir),
new IndexWriterConfig(Version.LUCENE_44, new KeywordAnalyzer()));
int count = indexFile(indexWriter, dataFile);
indexWriter.close();
return count;
}
private int indexFile(IndexWriter indexWriter, File dataFile) throws IOException {
FieldType fieldType = new FieldType();
fieldType.setStored(true);
fieldType.setIndexed(true);
BufferedReader bufferedReader = new BufferedReader(new FileReader(dataFile));
String line = "";
int count = 0;
while ((line = bufferedReader.readLine()) != null) {
// Hack to ignore commas within elements in csv (so we can split on "," rather than just ,)
line = line.substring(1, line.length() - 1);
String[] tweetInfo = line.split(COMMA);
Document document = new Document();
document.add(new Field(POLARITY, tweetInfo[0], fieldType));
document.add(new Field(ID, tweetInfo[1], fieldType));
document.add(new Field(DATE, tweetInfo[2], fieldType));
document.add(new Field(QUERY, tweetInfo[3], fieldType));
document.add(new StringField(USER, tweetInfo[4], Field.Store.YES));
document.add(new StringField(TEXT, tweetInfo[5], Field.Store.YES));
indexWriter.addDocument(document);
count++;
}
return count;
}
}
And this is short java code for my class TweetSearcher:
public class TweetSearcher {
public static void main(String[] args) throws Exception {
try {
String indexDir = "D:\\tweet\\index";
int numHits = Integer.parseInt("3");
TweetSearcher tweetSearcher = new TweetSearcher();
tweetSearcher.dateSearch(new File(indexDir), numHits);
private void dateSearch(File indexDir, int numHits) throws Exception {
System.out.println("Find dates:");
Directory directory = FSDirectory.open(indexDir);
DirectoryReader directoryReader = DirectoryReader.open(directory);
IndexSearcher indexSearcher = new IndexSearcher(directoryReader);

While parsing input as JSON and persisting, only firsts JSON object is persisted

I am trying to read array of JSON posted to a topic that my pipeline is subscribed to and persist the same to BigQuery. The problem I face while doing so is that it persists only the first object, can someone please provide me insight on what I am doing wrong here.
/** A DoFn that converts a table row from JSON into a BigQuery table row. */
static class FormatAsTableRowFn extends DoFn<TableRow, TableRow> {
private static final long serialVersionUID = 0;
static TableSchema getSchema() {
return new TableSchema().setFields(new ArrayList<TableFieldSchema>() {
// Compose the list of TableFieldSchema from tableSchema.
{
add(new TableFieldSchema().setName("PillBoxID").setType("STRING").setMode("NULLABLE"));
add(new TableFieldSchema().setName("Period").setType("STRING").setMode("NULLABLE"));
add(new TableFieldSchema().setName("Time").setType("TIMESTAMP").setMode("NULLABLE"));
add(new TableFieldSchema().setName("IsTaken").setType("STRING").setMode("NULLABLE"));
}
});
}
#Override
public void processElement(ProcessContext c) {
TableRow jsonRow = c.element();
// Setup a date formatter to parse the date appropriately
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
TableRow bQueryRow = new TableRow()
.set("PillBoxID", (String) jsonRow.get("PillBoxID"))
.set("Period", (String) jsonRow.get("Period"))
.set("Time",ft.format(ft.parse((String) jsonRow.get("Time"))))
.set("IsTaken", (String) jsonRow.get("IsTaken"));
LOG.error("Inside try" + bQueryRow.getF());
c.output(bQueryRow);
} catch (ParseException pe) {
LOG.error("ParseException");
LOG.error(pe.getMessage());
}
}
}
and my pipleline code is as shown below,
bigQueryPipeLine
.apply(PubsubIO.Read.topic(options.getPubsubTopic()).withCoder(TableRowJsonCoder.of()))
.apply(ParDo.of(new FormatAsTableRowFn()))
.apply(BigQueryIO.Write.to(tableSpec)
.withSchema(FormatAsTableRowFn.getSchema()));
it is possible to process multiple records if you format the input JSON to include an array of items.
Example input:
{
"items":
[
{"PillBoxID":"ID5", "Period":"Morning", "Time":"2016-03-14T11:11:11", "IsTaken":"true"},
{"PillBoxID":"ID6", "Period":"Afternoon", "Time":"2016-03-14T15:11:11", "IsTaken":"false"}
]
}
The rough example processElement() code adds the 2 items to c.output() for later storage in BigQuery.
#Override
public void processElement(ProcessContext c) throws DatastoreException, IOException{
TableRow jsonRowObj = c.element();
LOG.info("Original input:" + c.element().toPrettyString());
ArrayList<Map> jsonRows = (ArrayList<Map>)jsonRowObj.get("items");
Iterator<Map> iterator = jsonRows.iterator();
while(iterator.hasNext()) {
Map jsonRow = (Map)iterator.next();
// Setup a date formatter to parse the date appropriately
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
LOG.info("child input JSON: "+jsonRow.toString());
TableRow bQueryRow = new TableRow()
.set("PillboxID", (String) jsonRow.get("PillBoxID"))
.set("Period", (String) jsonRow.get("Period"))
.set("Time",ft.format(ft.parse((String) jsonRow.get("Time"))))
.set("IsTaken", (boolean) Boolean.parseBoolean((String)jsonRow.get("IsTaken")));
c.output(bQueryRow);
} catch (ParseException pe) {
LOG.error("");
LOG.error("ParseException " +pe.getMessage());
}
}
}

win:length(2) is fired after first event

I made a very simple test gui based on this brilliant article about getting started with Esper.
What surprises me is that this query is validated to true after the very first tick event is sent, if the price is above 6.
select * from StockTick(symbol='AAPL').win:length(2) having avg(price) > 6.0
As far as I understand, win:length(2) needs TWO ticks before an event is fired, or am I wrong?
Here is a SSCCE for this question, just press the "Create Tick Event" button and you will see the StockTick Event being fired at once.
It needs the following jars which comes bundled with Esper
esper\lib\antlr-runtime-3.2.jar
esper\lib\cglib-nodep-2.2.jar
esper\lib\commons-logging-1.1.1.jar
esper\lib\esper_3rdparties.license
esper\lib\log4j-1.2.16.jar
esper-4.11.0.jar
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Random;
import javax.swing.JRadioButton;
import javax.swing.JPanel;
import java.awt.GridLayout;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import com.espertech.esper.client.Configuration;
import com.espertech.esper.client.EPAdministrator;
import com.espertech.esper.client.EPRuntime;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.UpdateListener;
import javax.swing.JTextField;
public class Tester extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton createRandomValueEventButton;
private JPanel panel;
private JPanel southPanel;
private JPanel centerPanel;
private static JTextArea centerTextArea;
private static JTextArea southTextArea;
private static Random generator = new Random();
private EPRuntime cepRT;
private JSplitPane textSplitPane;
private JButton btnNewButton;
private static JTextField priceTextField;
public Tester() {
getContentPane().setLayout(new BorderLayout(0, 0));
JSplitPane splitPane = new JSplitPane();
createRandomValueEventButton = new JButton("Create Tick Event With Random Price");
splitPane.setLeftComponent(createRandomValueEventButton);
createRandomValueEventButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
createTickWithRandomPrice();
}
});
panel = new JPanel();
splitPane.setRightComponent(panel);
panel.setLayout(new GridLayout(1, 0, 0, 0));
btnNewButton = new JButton("Create Tick Event");
panel.add(btnNewButton);
btnNewButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
createTick();
}
});
priceTextField = new JTextField();
priceTextField.setText(new Integer(10).toString());
panel.add(priceTextField);
priceTextField.setColumns(4);
getContentPane().add(splitPane, BorderLayout.NORTH);
textSplitPane = new JSplitPane();
textSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
getContentPane().add(textSplitPane, BorderLayout.CENTER);
centerPanel = new JPanel();
centerPanel.setLayout(new BorderLayout(0, 0));
JScrollPane centerTextScrollPane = new JScrollPane();
centerTextScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
centerTextArea = new JTextArea();
centerTextArea.setRows(12);
centerTextScrollPane.setViewportView(centerTextArea);
southPanel = new JPanel();
southPanel.setLayout(new BorderLayout(0, 0));
JScrollPane southTextScrollPane = new JScrollPane();
southTextScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
southTextArea = new JTextArea();
southTextArea.setRows(5);
southTextScrollPane.setViewportView(southTextArea);
textSplitPane.setRightComponent(southTextScrollPane);
textSplitPane.setLeftComponent(centerTextScrollPane);
setupCEP();
}
public static void GenerateRandomTick(EPRuntime cepRT) {
double price = (double) generator.nextInt(10);
long timeStamp = System.currentTimeMillis();
String symbol = "AAPL";
Tick tick = new Tick(symbol, price, timeStamp);
System.out.println("Sending tick:" + tick);
centerTextArea.append(new Date().toString()+" Sending tick:" + tick+"\n");
cepRT.sendEvent(tick);
}
public static void GenerateTick(EPRuntime cepRT) {
double price = Double.parseDouble(priceTextField.getText());
long timeStamp = System.currentTimeMillis();
String symbol = "AAPL";
Tick tick = new Tick(symbol, price, timeStamp);
System.out.println("Sending tick:" + tick);
centerTextArea.append(new Date().toString()+" Sending tick: " + tick+"\n");
cepRT.sendEvent(tick);
}
public static void main(String[] args){
Tester tester = new Tester();
tester.setSize(new Dimension(570,500));
tester.setVisible(true);
}
private void createTickWithRandomPrice(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GenerateRandomTick(getEPRuntime());
}
});
}
private void createTick(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GenerateTick(getEPRuntime());
}
});
}
private void setupCEP(){
Configuration cepConfig = new Configuration();
cepConfig.addEventType("StockTick", Tick.class.getName());
EPServiceProvider cep = EPServiceProviderManager.getProvider("myCEPEngine", cepConfig);
cepRT = cep.getEPRuntime();
EPAdministrator cepAdm = cep.getEPAdministrator();
EPStatement cepStatement = cepAdm.createEPL(
"select * from " +
"StockTick(symbol='AAPL').win:length(2) " +
"having avg(price) > 6.0");
cepStatement.addListener(new CEPListener());
//System.out.println("cepStatement.getText(): "+cepStatement.getText());
}
private EPRuntime getEPRuntime(){
public static class Tick {
String symbol;
Double price;
Date timeStamp;
public Tick(String s, double p, long t) {
symbol = s;
price = p;
timeStamp = new Date(t);
}
public double getPrice() {return price;}
public String getSymbol() {return symbol;}
public Date getTimeStamp() {return timeStamp;}
#Override
public String toString() {
return symbol+" Price: " + price.toString();
}
}
public static class CEPListener implements UpdateListener {
}
Actually aggregation and conditions are independent of how many events are in data window. There are functions you could use to check whether a data window is "filled": the "leaving", "count" or "prevcount" for example.
For anyone interested,
changing the query to this solved the problem
select * from StockTick(symbol='AAPL').win:length_batch(2) having avg(price) > 6.0 and count(*) >= 2
Now an event will be triggered for every consecutive tick with the price higher than 6, in batches of two.

JavaFX WebView loading page in background

I have a problem using the JavaFX WebView. What I want to achieve is pre-fetching a web page in the background and visualiszing it only when the page is totally loaded.
I have made a simple exmaple program to reproduce the problem. After the page is loaded I enable a button. A Click on this button then makes the WebView visible.
The problem I have is, that if I click on the button when it gets enabled, the web page is not visible directly. Instead the following happens: At first there is a totally white panel and then after a short time the web page is visible. I don't understand why the page is not visible directly. How can I achieve it, that the web page is directly visible?
The following link points to an animated gif which shows the behaviour:
http://tinypic.com/view.php?pic=oh66bl&s=5#.Ujmv1RddWKk
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class WebViewTest extends javax.swing.JPanel {
private static JFXPanel browserFxPanel;
private WebView webView;
private WebEngine eng;
/**
* Creates new form WebViewTest
*/
public WebViewTest() {
initComponents();
Platform.setImplicitExit(false);
browserFxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
public void run() {
webView = createBrowser();
Scene scene = new Scene(webView);
scene.setFill(null);
browserFxPanel.setScene(
scene);
}
});
}
/**
* This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
* content of this method is always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
pnlMain = new javax.swing.JPanel();
showWebpageButton = new javax.swing.JButton();
setLayout(new java.awt.GridBagLayout());
pnlMain.setLayout(new java.awt.BorderLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
add(pnlMain, gridBagConstraints);
showWebpageButton.setText("show web page");
showWebpageButton.setEnabled(false);
showWebpageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showWebpageButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10);
add(showWebpageButton, gridBagConstraints);
}// </editor-fold>
private void showWebpageButtonActionPerformed(java.awt.event.ActionEvent evt) {
pnlMain.removeAll();
pnlMain.add(browserFxPanel, BorderLayout.CENTER);
WebViewTest.this.invalidate();
WebViewTest.this.revalidate();
}
// Variables declaration - do not modify
private javax.swing.JPanel pnlMain;
private javax.swing.JButton showWebpageButton;
// End of variables declaration
private WebView createBrowser() {
Double widthDouble = pnlMain.getSize().getWidth();
Double heightDouble = pnlMain.getSize().getHeight();
final WebView view = new WebView();
view.setMinSize(widthDouble, heightDouble);
view.setPrefSize(widthDouble, heightDouble);
eng = view.getEngine();
eng.load("http://todomvc.com/architecture-examples/angularjs/#/");
eng.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
final double workDone = eng.getLoadWorker().getWorkDone();
final double totalWork = eng.getLoadWorker().getTotalWork();
if (workDone == totalWork) {
showWebpageButton.setEnabled(true);
}
}
});
return view;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame f = new JFrame("Navigator Dummy");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setSize(new Dimension(1024, 800));
final WebViewTest navDummy = new WebViewTest();
f.getContentPane().add(navDummy);
f.setVisible(true);
}
});
}
}
JFX needs a "stage" to show up its face. Modify your codes as following and it will work perfectly
/**
* Creates new form WebViewTest
*/
private Stage stage; // insert this line
public WebViewTest() {
initComponents();
Platform.setImplicitExit(false);
browserFxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
public void run() {
webView = createBrowser();
Scene scene = new Scene(webView);
scene.setFill(null);
stage = new Stage(); // <<<
stage.setScene(scene); // <<<
browserFxPanel.setScene(scene);
}
});
}
...
private void showWebpageButtonActionPerformed(java.awt.event.ActionEvent evt) {
pnlMain.removeAll();
pnlMain.add(browserFxPanel, BorderLayout.CENTER);
WebViewTest.this.invalidate();
WebViewTest.this.revalidate();
stage.show(); // <<< afer click Button
}

Primefaces dataExporter - inline PDF in new window without footer

I'm trying to use Primefaces's dataExporter component. I have two problems with it (for now):
In column footers of datatable I have a p:commandButton. What happens to me is that when I export datatable with dataExporter to PDF I can see that it added column footers to PDF and wrote something like this: javax.faces.component.UIPanel#9e08b9 (it just called toString of UIComponent I suppose). Is there any way to instruct dataExporter to ignore column footers?
I want to try to somehow open new window with generated PDF and show that PDF inline on a new page. I don't wont to see Download file prompt. Is this possible?
After some time, and coding I finally succeeded to make this work. Primefaces doesn't have this functions included so I have to override default behavior little bit.
First I created custom PDFExporter to skip footer printing:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.component.export.PDFExporter;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfPTable;
public class CustomPDFExporter extends PDFExporter {
#Override
protected void addColumnFacets(DataTable table, PdfPTable pdfTable,
ColumnType columnType) {
if (columnType == ColumnType.HEADER) {
super.addColumnFacets(table, pdfTable, columnType);
}
}
#Override
protected void writePDFToResponse(ExternalContext externalContext,
ByteArrayOutputStream baos, String fileName) throws IOException,
DocumentException {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.put("reportBytes", baos.toByteArray());
FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.put("reportName", fileName);
}
}
As you can see, report data is added in session.
Now DataExporter of Primefaces should be rewriten:
import java.io.IOException;
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.component.export.CSVExporter;
import org.primefaces.component.export.Exporter;
import org.primefaces.component.export.ExporterType;
import org.primefaces.component.export.XMLExporter;
import org.primefaces.context.RequestContext;
import asw.iis.common.ui.beans.DatatableBackingBean;
public class CustomDataExporter implements ActionListener, StateHolder {
private ValueExpression target;
private ValueExpression type;
private ValueExpression fileName;
private ValueExpression encoding;
private MethodExpression preProcessor;
private MethodExpression postProcessor;
private DatatableBackingBean<?> datatableBB;
public CustomDataExporter() {}
public CustomDataExporter(ValueExpression target, ValueExpression type, ValueExpression fileName, ValueExpression encoding,
MethodExpression preProcessor, MethodExpression postProcessor, DatatableBackingBean<?> datatableBB) {
this.target = target;
this.type = type;
this.fileName = fileName;
this.encoding = encoding;
this.preProcessor = preProcessor;
this.postProcessor = postProcessor;
this.datatableBB = datatableBB;
}
public void processAction(ActionEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
try {
datatableBB.stampaPreProcess();
ELContext elContext = context.getELContext();
String tableId = (String) target.getValue(elContext);
String exportAs = (String) type.getValue(elContext);
String outputFileName = (String) fileName.getValue(elContext);
String encodingType = "UTF-8";
if(encoding != null) {
encodingType = (String) encoding.getValue(elContext);
}
try {
Exporter exporter;
ExporterType exporterType = ExporterType.valueOf(exportAs.toUpperCase());
switch(exporterType) {
case XLS:
exporter = new ExcelExporter();
break;
case PDF:
exporter = new CustomPDFExporter();
break;
case CSV:
exporter = new CSVExporter();
break;
case XML:
exporter = new XMLExporter();
break;
default:
exporter = new CustomPDFExporter();
break;
}
UIComponent component = event.getComponent().findComponent(tableId);
if(component == null) {
throw new FacesException("Cannot find component \"" + tableId + "\" in view.");
}
if(!(component instanceof DataTable)) {
throw new FacesException("Unsupported datasource target:\"" + component.getClass().getName() + "\", exporter must target a PrimeFaces DataTable.");
}
DataTable table = (DataTable) component;
exporter.export(context, table, outputFileName, false, false, encodingType, preProcessor, postProcessor);
if ("pdf".equals(exportAs)) {
String path = ((ServletContext)(FacesContext.getCurrentInstance().getExternalContext().getContext())).getContextPath();
RequestContext.getCurrentInstance().execute("window.open('" + path + "/report.pdf', '_blank', 'dependent=yes, menubar=no, toolbar=no')");
} else {
context.responseComplete();
}
}
catch (IOException e) {
throw new FacesException(e);
}
}
finally {
((HttpServletRequest) context.getExternalContext().getRequest()).removeAttribute("vrstaStampe");
datatableBB.stampaPostProcess();
}
}
public boolean isTransient() {
return false;
}
public void setTransient(boolean value) {
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
target = (ValueExpression) values[0];
type = (ValueExpression) values[1];
fileName = (ValueExpression) values[2];
preProcessor = (MethodExpression) values[3];
postProcessor = (MethodExpression) values[4];
encoding = (ValueExpression) values[5];
datatableBB = (DatatableBackingBean<?>) values[6];
}
public Object saveState(FacesContext context) {
Object values[] = new Object[7];
values[0] = target;
values[1] = type;
values[2] = fileName;
values[3] = preProcessor;
values[4] = postProcessor;
values[5] = encoding;
values[6] = datatableBB;
return ((Object[]) values);
}
}
Main job here is to instantiate CustomPDFExporter, and open new window in case when report type is PDF.
Now I wrote simple Servlet to handle this request and print report data:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/report.pdf")
public class PdfReportServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
byte[] b = (byte[]) req.getSession().getAttribute("reportBytes");
if (b == null) {
b = new byte[0];
}
resp.setContentType("application/pdf");
resp.setContentLength(b.length);
resp.getOutputStream().write(b);
req.getSession().removeAttribute("reportBytes");
}
}
This will configure HTTP header, and print bytes of report to output stream. Also it removes report bytes from session.
Finally, as I handle this printing from dynamically created menu button I add this action listener in code:
MenuItem item = ...;
ELContext el = FacesContext.getCurrentInstance().getELContext();
ExpressionFactory ef = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
ValueExpression typeEL = ef.createValueExpression(el, "#{startBean.reportType}", String.class);
ValueExpression fileEL = ef.createValueExpression(el, datasource, String.class);
ValueExpression targetEL = ef.createValueExpression(el, ":" + datatableId + ":datatableForm:datatable", String.class);
ValueExpression encodingEL = ef.createValueExpression(el, "ISO-8859-2", String.class);
CustomDataExporter de = new CustomDataExporter(targetEL, typeEL, fileEL, encodingEL, null, null, this);
item.setAjax(true);
item.addActionListener(de);

Resources