BarChart Update - multithreading

Now it is another problem that occurred, it seems that the query I'm using only works for the first time but after pressing the next/previous buttons, it is giving me something else !!
Here is the query I used:
for (int i = 0; i <= months.length + 1; i++) {
try {
String a;
if (i < 9) {
a = y + "0" + (i + 1);
} else {
a = y + "" + (i + 1);
}
System.out.println("Année Courante " + a);
conn = DBConnection.connect();
String sql = "select sum(montant_operation) from operations where (select Extract(YEAR_MONTH from date_operation)) = '" + a + "' and typ_operation ='Versement';";
final ResultSet rs = conn.prepareStatement(sql).executeQuery();
if (rs.next()) {
System.out.println(series1.getData().toString());
series1.getData().add(new XYChart.Data<>(months[i], rs.getFloat("sum(montant_operation)")));
}
} catch (SQLException e) {
System.out.println(e);
}
}
But is there a query that works fine one time and then it gives error.
Have a nice day

In your BuildData (by the way, not following Java Naming Conventions, change its name) method you are updating the data of series. In the same method you are adding this series to the chart. By clicking the "next" button, BuildData method is invoked where this chart is added again which is unnecessary. Delete the
Platform.runLater(() -> {
barchart.getData().add(series1);
});
part from the method and add the chart only once in start:
...
...
vbox.getChildren().addAll(box, barchart);
barchart.getData().add(series1);
pane.getChildren().add(vbox);
...
...
The tested SSCCE:
import java.util.Calendar;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class BarChartDemo extends Application {
final String[] months = {"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"};
//Connection conn;
final CategoryAxis month_axis = new CategoryAxis();
final NumberAxis data_axis = new NumberAxis();
final XYChart.Series<String, Number> series1 = new XYChart.Series();
private final BarChart<String, Number> barchart = new BarChart(month_axis, data_axis);
private Integer year = 0;
#Override
public void start(Stage primaryStage) {
year = Calendar.getInstance().get(Calendar.YEAR);
Button btn_next = new Button("NEXT");
Button btn_previous = new Button("PREVIOUS");
HBox box = new HBox(50);
box.getChildren().addAll(btn_previous, btn_next);
box.setAlignment(Pos.TOP_CENTER);
VBox vbox = new VBox(25);
box.setPadding(new Insets(10, 0, 10, 0));
FlowPane pane = new FlowPane(Orientation.VERTICAL);
vbox.getChildren().addAll(box, barchart);
barchart.getData().add(series1);
pane.getChildren().add(vbox);
Scene scene = new Scene(pane);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
BuildData(year);
btn_next.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
year += 1;
BuildData(year);
}
});
btn_previous.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
year -= 1;
BuildData(year);
}
});
}
public static void main(String[] args) {
launch(args);
}
private void BuildData(Integer y) {
series1.setName("Versement");
month_axis.setLabel("Mois de l'Année");
month_axis.setStyle("-fx-font-weight:BOLD;" + "-fx-font-size:15");
data_axis.setLabel("Valeur des Opérations Bancaires");
data_axis.setStyle("-fx-font-weight:BOLD;" + "-fx-font-size:15");
series1.getData().clear(); // clear old values
for (int i = 0; i < months.length; i++) {
series1.getData().add(new XYChart.Data(months[i], i * 10 * (y-2000)));
// try {
// String a;
// if (i < 9) {
// a = y + "0" + (i + 1);
// } else {
// a = y + "" + (i + 1);
// }
// conn = DBConnection.connect();
// String sql = "select sum(montant_operation) from operations where (select Extract(YEAR_MONTH from date_operation)) = '" + a + "' and typ_operation ='Versement';";
// final ResultSet rs = conn.prepareStatement(sql).executeQuery();
// if (rs.next()) {
// series1.getData().add(new XYChart.Data<>(months[i], rs.getFloat("sum(montant_operation)")));
// }
// } catch (SQLException e) {
// System.out.println(e);
// }
}
}
}

Related

Issues with runaway thread

I'm pretty new to android studio. I noticed that my program had a very severe performance hiccup and I believe it is slowing down after I run the app every time. I think I have a runaway thread and I will attach pictures at the end of my post. I could really use some help. The first picture shows an example of the thread and then the second picture shows the thread after 5 minutes or so of waiting. I attached two codes. CameraSurfaceView runs the code while FaceDetectionThread creates the thread.
package com.example.phliip_vision;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.FaceDetector;
import android.media.FaceDetector.Face;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import com.example.phliip_vision.Point;
import com.example.phliip_vision.MeasurementStepMessage;
import com.example.phliip_vision.MessageHUB;
import com.example.phliip_vision.Util;
public class CameraSurfaceView extends SurfaceView implements Callback,
Camera.PreviewCallback {
public static final int CALIBRATION_DISTANCE_A4_MM = 294;
public static final int CALIBRATION_MEASUREMENTS = 10;
public static final int AVERAGE_THREASHHOLD = 5;
private static final String TAG = "CameraSurfaceView";
/**
* Measured distance at calibration point
*/
private float _distanceAtCalibrationPoint = -1;
private float _currentAvgEyeDistance = -1;
// private int _facesFoundInMeasurement = -1;
/**
* in cm
*/
private float _currentDistanceToFace = -1;
private final SurfaceHolder mHolder;
private Camera mCamera;
private Face _foundFace = null;
private int _threashold = CALIBRATION_MEASUREMENTS;
private FaceDetectionThread _currentFaceDetectionThread;
private List<Point> _points;
protected final Paint _middlePointColor = new Paint();
protected final Paint _eyeColor = new Paint();
private Size _previewSize;
// private boolean _measurementStartet = false;
private boolean _calibrated = false;
private boolean _calibrating = false;
private int _calibrationsLeft = -1;
public CameraSurfaceView(final Context context, final AttributeSet attrs) {
super(context, attrs);
_middlePointColor.setARGB(100, 200, 0, 0);
_middlePointColor.setStyle(Paint.Style.FILL);
_middlePointColor.setStrokeWidth(2);
_eyeColor.setColor(Color.GREEN);
mHolder = getHolder();
mHolder.addCallback(this);
}
public void setCamera(final Camera camera) {
mCamera = camera;
if (mCamera != null) {
requestLayout();
Log.d(TAG, "mCamera RANNNNNNN!!!!");
Camera.Parameters params = mCamera.getParameters();
camera.setDisplayOrientation(90);
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
Log.d(TAG, "FOCUS_MODE_AUTO RANNNNNNN!!!!");
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);
}
}
}
/**
* Variables for the onDraw method, in order to prevent variable allocation
* to slow down the sometimes heavily called onDraw method
*/
private final PointF _middlePoint = new PointF();
private final Rect _trackingRectangle = new Rect();
private final static int RECTANGLE_SIZE = 20;
private boolean _showEyes = false;
private boolean _showTracking = true;
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(final Canvas canvas) {
// super.onDraw(canvas);
if (_foundFace != null) {
_foundFace.getMidPoint(_middlePoint);
Log.d(TAG, "_middlePoint RANNNNNNN!!!!");
Log.i("Camera", _middlePoint.x + " : " + _middlePoint.y);
// portrait mode!
float heightRatio = getHeight() / (float) _previewSize.width;
float widthRatio = getWidth() / (float) _previewSize.height;
Log.i("Drawcall", _middlePoint.x + " : " + _middlePoint.y);
int realX = (int) (_middlePoint.x * widthRatio);
int realY = (int) (_middlePoint.y * heightRatio);
Log.i("Drawcall", "Real :" + realX + " : " + realY);
int halfEyeDist = (int) (widthRatio * _foundFace.eyesDistance() / 2);
if (_showTracking) {
// Middle point
Log.d(TAG, "_showTracking RANNNNNNN!!!!");
_trackingRectangle.left = realX - RECTANGLE_SIZE;
_trackingRectangle.top = realY - RECTANGLE_SIZE;
_trackingRectangle.right = realX + RECTANGLE_SIZE;
_trackingRectangle.bottom = realY + RECTANGLE_SIZE;
canvas.drawRect(_trackingRectangle, _middlePointColor);
}
if (_showEyes) {
// Left eye
Log.d(TAG, "_showEyes RANNNNNNN!!!!");
_trackingRectangle.left = realX - halfEyeDist - RECTANGLE_SIZE;
_trackingRectangle.top = realY - RECTANGLE_SIZE;
_trackingRectangle.right = realX - halfEyeDist + RECTANGLE_SIZE;
_trackingRectangle.bottom = realY + RECTANGLE_SIZE;
canvas.drawRect(_trackingRectangle, _eyeColor);
// Right eye
_trackingRectangle.left = realX + halfEyeDist - RECTANGLE_SIZE;
_trackingRectangle.top = realY - RECTANGLE_SIZE;
_trackingRectangle.right = realX + halfEyeDist + RECTANGLE_SIZE;
_trackingRectangle.bottom = realY + RECTANGLE_SIZE;
canvas.drawRect(_trackingRectangle, _eyeColor);
}
}
}
public void reset() {
Log.d(TAG, "reset RANNNNNNN!!!!");
_distanceAtCalibrationPoint = -1;
_currentAvgEyeDistance = -1;
_calibrated = false;
_calibrating = false;
_calibrationsLeft = -1;
}
/**
* Sets this current EYE distance to be the distance of a peace of a4 paper
* e.g. 29,7cm
*/
public void calibrate() {
Log.d(TAG, "calibrate RANNNNNNN!!!!");
if (!_calibrating || !_calibrated) {
_points = new ArrayList<>();
_calibrating = true;
_calibrationsLeft = CALIBRATION_MEASUREMENTS;
_threashold = CALIBRATION_MEASUREMENTS;
}
}
private void doneCalibrating() {
Log.d(TAG, "doneCalibrating RANNNNNNN!!!!");
_calibrated = true;
_calibrating = false;
_currentFaceDetectionThread = null;
// _measurementStartet = false;
_threashold = AVERAGE_THREASHHOLD;
_distanceAtCalibrationPoint = _currentAvgEyeDistance;
MessageHUB.get().sendMessage(MessageHUB.DONE_CALIBRATION, null);
}
public boolean isCalibrated() {
Log.d(TAG, "isCalibrated RANNNNNNN!!!!");
return _calibrated || _calibrating;
}
public void showMiddleEye(final boolean on) {
Log.d(TAG, "showMiddleEye RANNNNNNN!!!!");
_showTracking = on;
}
public void showEyePoints(final boolean on) {
Log.d(TAG, "showEyePoints RANNNNNNN!!!!");
_showEyes = on;
}
private void updateMeasurement(final FaceDetector.Face currentFace) {
if (currentFace == null) {
Log.d(TAG, "updateMeasurement RANNNNNNN!!!!");
// _facesFoundInMeasurement--;
return;
}
_foundFace = _currentFaceDetectionThread.getCurrentFace();
_points.add(new Point(_foundFace.eyesDistance(),
CALIBRATION_DISTANCE_A4_MM
* (_distanceAtCalibrationPoint / _foundFace
.eyesDistance())));
while (_points.size() > _threashold) {
_points.remove(0);
Log.d(TAG, "Removing points RANNNNNNN!!!!");
}
float sum = 0;
for (Point p : _points) {
sum += p.getEyeDistance();
Log.d(TAG, "adding points RANNNNNNN!!!!");
}
_currentAvgEyeDistance = sum / _points.size();
_currentDistanceToFace = CALIBRATION_DISTANCE_A4_MM
* (_distanceAtCalibrationPoint / _currentAvgEyeDistance);
_currentDistanceToFace = Util.MM_TO_CM(_currentDistanceToFace);
MeasurementStepMessage message = new MeasurementStepMessage();
message.setConfidence(currentFace.confidence());
message.setCurrentAvgEyeDistance(_currentAvgEyeDistance);
message.setDistToFace(_currentDistanceToFace);
message.setEyesDistance(currentFace.eyesDistance());
message.setMeasurementsLeft(_calibrationsLeft);
message.setProcessTimeForLastFrame(_processTimeForLastFrame);
MessageHUB.get().sendMessage(MessageHUB.MEASUREMENT_STEP, message);
}
private long _lastFrameStart = System.currentTimeMillis();
private float _processTimeForLastFrame = -1;
#Override
public void onPreviewFrame(final byte[] data, final Camera camera) {
Log.d(TAG, "onPreviewFrame RANNNNNNN!!!!" + _calibrationsLeft);
if (_calibrationsLeft == -1)
return;
if (_calibrationsLeft > 0) {
// Doing calibration !
Log.d(TAG, "_calibrationLeft RANNNNNNN!!!!" + _calibrationsLeft);
if (_currentFaceDetectionThread != null
&& _currentFaceDetectionThread.isAlive()) {
Log.d(TAG, "_currentFaceDectectionThread RANNNNNNN!!!!" + _currentFaceDetectionThread);
// Drop Frame
return;
}
// No face detection started or already finished
_processTimeForLastFrame = System.currentTimeMillis()
- _lastFrameStart;
_lastFrameStart = System.currentTimeMillis();
if (_currentFaceDetectionThread != null) {
Log.d(TAG, "_calibrationLeft-- RANNNNNNN!!!!");
_calibrationsLeft--;
updateMeasurement(_currentFaceDetectionThread.getCurrentFace());
if (_calibrationsLeft == 0) {
Log.d(TAG, "Calibrating done RANNNNNNN!!!!");
doneCalibrating();
invalidate();
return;
}
}
_currentFaceDetectionThread = new FaceDetectionThread(data,
_previewSize);
_currentFaceDetectionThread.start();
invalidate();
} else {
// Simple Measurement
if (_currentFaceDetectionThread != null
&& _currentFaceDetectionThread.isAlive()) {
Log.d(TAG, "Dropping frames RANNNNNNN!!!!");
// Drop Frame
return;
}
// No face detection started or already finished
_processTimeForLastFrame = System.currentTimeMillis()
- _lastFrameStart;
_lastFrameStart = System.currentTimeMillis();
if (_currentFaceDetectionThread != null)
updateMeasurement(_currentFaceDetectionThread.getCurrentFace());
Log.d(TAG, "Updating measurements RANNNNNNN!!!!");
_currentFaceDetectionThread = new FaceDetectionThread(data,
_previewSize);
_currentFaceDetectionThread.start();
Log.d(TAG, "invalidate RANNNNNNN!!!!");
invalidate();
}
}
/*
* SURFACE METHODS, TO CREATE AND RELEASE SURFACE THE CORRECT WAY.
*
* #see
* android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
* )
*/
#Override
public void surfaceCreated(final SurfaceHolder holder) {
synchronized (this) {
// This allows us to make our own drawBitmap
this.setWillNotDraw(false);
}
}
#Override
public void surfaceDestroyed(final SurfaceHolder holder) {
mCamera.release();
mCamera = null;
}
#Override
public void surfaceChanged(final SurfaceHolder holder, final int format,
final int width, final int height) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
Parameters parameters = mCamera.getParameters();
_previewSize = parameters.getPreviewSize();
// mCamera.setDisplayOrientation(90);
// mCamera.setParameters(parameters);
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
mCamera.setPreviewCallback(this);
} catch (Exception e) {
Log.d("This", "Error starting camera preview: " + e.getMessage());
}
}
}
Here is the other code.
package com.example.phliip_vision;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera.Size;
import android.media.FaceDetector;
import android.media.FaceDetector.Face;
import android.util.Log;
public class FaceDetectionThread extends Thread {
public static final String FACEDETECTIONTHREAD_TAG = "FaceDetectionThread_Tag";
private static final String TAG = "FaceDetectionThread";
private Face _currentFace;
private final byte[] _data;
private final Size _previewSize;
private Bitmap _currentFrame;
public FaceDetectionThread(final byte[] data, final Size previewSize) {
Log.d(TAG, "What are we waiting on in FaceDetectionThread????");
_data = data;
_previewSize = previewSize;
}
public Face getCurrentFace() {
Log.d(TAG, "What are we waiting on in Current faces????");
return _currentFace;
}
public Bitmap getCurrentFrame() {
return _currentFrame;
}
/**
* bla bla bla
*/
#Override
public void run() {
long t = System.currentTimeMillis();
YuvImage yuvimage = new YuvImage(_data, ImageFormat.NV21,
_previewSize.width, _previewSize.height, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (!yuvimage.compressToJpeg(new Rect(0, 0, _previewSize.width,
_previewSize.height), 100, baos)) {
Log.e("Camera", "compressToJpeg failed");
}
Log.i("Timing", "Compression finished: "
+ (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.RGB_565;
_currentFrame = BitmapFactory.decodeStream(new ByteArrayInputStream(
baos.toByteArray()), null, bfo);
Log.i("Timing", "Decode Finished: " + (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
// Rotate the so it siuts our portrait mode
Matrix matrix = new Matrix();
matrix.postRotate(90);
matrix.preScale(-1, 1);
// We rotate the same Bitmap
_currentFrame = Bitmap.createBitmap(_currentFrame, 0, 0,
_previewSize.width, _previewSize.height, matrix, false);
Log.i("Timing",
"Rotate, Create finished: " + (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
if (_currentFrame == null) {
Log.e(FACEDETECTIONTHREAD_TAG, "Could not decode Image");
return;
}
FaceDetector d = new FaceDetector(_currentFrame.getWidth(),
_currentFrame.getHeight(), 1);
Face[] faces = new Face[1];
d.findFaces(_currentFrame, faces);
Log.i("Timing",
"FaceDetection finished: " + (System.currentTimeMillis() - t));
t = System.currentTimeMillis();
_currentFace = faces[0];
Log.d(FACEDETECTIONTHREAD_TAG, "Found: " + faces[0] + " Faces");
}
}
enter image description here
enter image description here

Limit width size of Stacked Bar chart

I tried to implement this solution for StackedBar Chart but it turns out that there is no Java method getBarGap() in StackedBar chart. Is there any solution into the latest JavaFX version for this problem?
Basic example:
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class MainApp extends Application
{
private StackedBarChart<String, Number> stackedChart;
private List<EventsObj> eventsObj;
#Override
public void start(Stage stage) throws Exception
{
createStackedChart();
List<EventsObj> testData = generateTestData();
addStackedChartData(testData);
HBox hb = new HBox();
hb.getChildren().add(stackedChart);
Scene scene = new Scene(hb);
stage.setTitle("JavaFX and Maven");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
private void createStackedChart()
{
CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Days");
NumberAxis yAxis = new NumberAxis();
stackedChart = new StackedBarChart<>(xAxis, yAxis);
stackedChart.setCategoryGap(20);
stackedChart.widthProperty().addListener((obs, b, b1) ->
{
// Chart Bar column is not automatically resized. We need to wait for next JavaFX releases to fix this.
Platform.runLater(() -> setMaxBarWidth(stackedChart, xAxis, 40, 10));
});
}
private List<EventsObj> generateTestData()
{
eventsObj = new ArrayList<>();
for (int i = 0; i < 5; i++)
{
eventsObj.add(new EventsObj(String.valueOf(randomDate()), random(2, 60), random(2, 60), random(2, 60), random(2, 60)));
}
return eventsObj;
}
public static int random(int lowerBound, int upperBound)
{
return (lowerBound + (int) Math.round(Math.random() * (upperBound - lowerBound)));
}
private LocalDate randomDate()
{
Random random = new Random();
int minDay = (int) LocalDate.of(1900, 1, 1).toEpochDay();
int maxDay = (int) LocalDate.of(2015, 1, 1).toEpochDay();
long randomDay = minDay + random.nextInt(maxDay - minDay);
LocalDate randomBirthDate = LocalDate.ofEpochDay(randomDay);
return randomBirthDate;
}
private void addStackedChartData(List<EventsObj> data)
{
List<XYChart.Series<String, Number>> dataSeries = new ArrayList<>(data.size());
for (EventsObj data1 : data)
{
final XYChart.Series<String, Number> series1 = new XYChart.Series<>();
series1.setName(data1.getDate());
series1.getData().setAll(
new XYChart.Data<>("Info", data1.getInfo()));
dataSeries.add(series1);
}
stackedChart.getData().setAll(dataSeries);
}
private void setMaxBarWidth(StackedBarChart<String, Number> bc, CategoryAxis xAxis, double maxBarWidth, double minCategoryGap)
{
double barWidth = 0;
do
{
double catSpace = xAxis.getCategorySpacing();
double avilableBarSpace = catSpace - (bc.getCategoryGap() + bc.getCategoryGap());
barWidth = (avilableBarSpace / bc.getData().size()) - bc.getCategoryGap();
if (barWidth > maxBarWidth)
{
avilableBarSpace = (maxBarWidth + bc.getCategoryGap()) * bc.getData().size();
bc.setCategoryGap(catSpace - avilableBarSpace - bc.getCategoryGap());
}
}
while (barWidth > maxBarWidth);
do
{
double catSpace = xAxis.getCategorySpacing();
double avilableBarSpace = catSpace - (minCategoryGap + bc.getCategoryGap());
barWidth = Math.min(maxBarWidth, (avilableBarSpace / bc.getData().size()) - bc.getCategoryGap());
avilableBarSpace = (barWidth + bc.getCategoryGap()) * bc.getData().size();
bc.setCategoryGap(catSpace - avilableBarSpace - bc.getCategoryGap());
}
while (barWidth < maxBarWidth && bc.getCategoryGap() > minCategoryGap);
}
}
In a BarChart chart, the different series added are plotted in the different columns from the same category with a barGap, some spacing in between.
But in a StackBarChart chart, the different series are plotted stacked in the same column, hence in this case there is no bar gap.
If you take the setMaxBarWidth() method from this answer, all you need to do is set bc.getBarGap() to 0, and take sbc.getData().size() as 1. In this case there is no need for iterations.
This will be the new method, really simplified:
private void setMaxCategoryWidth(double maxCategoryWidth, double minCategoryGap){
double catSpace = xAxis.getCategorySpacing();
sbc.setCategoryGap(catSpace - Math.min(maxCategoryWidth, catSpace - minCategoryGap));
}
Basically, all you have to do is subtract the desired width of your category from the initial width of the category and put this extra space into the categoryGap.
Now, you can create your chart:
StackedBarChart<String, Number> sbc = new StackedBarChart<>(xAxis, yAxis);
And set your desired size for the categories:
setMaxCategoryWidth(40, 10);
sbc.widthProperty().addListener((obs, b, b1) -> {
Platform.runLater(() -> setMaxCategoryWidth(40, 10));
});
This pic is generated based on the sample 7.4 taken from here.

Android WebView shows extra horizontal white spaces in Android 4.0+ devices

In my code attached, I am trying to use two Android WebViews (webView1 and webView2) to display a javaScript enabled menu inside webView1 and a page showing the result of menu-click triggered in webView1 inside webView2.
As the code show, I am dynamically trying to fit the WebViews dynamically to the target screen by calculating my own initial scales and then plug the computed scales into the WebViews during Run-time.
Here is the problem I would like to ask for your assistance... When I click on the menu items in webView1 in order to show the result in webView2, extra horizontal white spaces (size of the horizontal white spaces are about the same width of the target screen, but the horizontal scroll bar is about the witdh of webView2) are shown in webView2. The white spaces appears randomly (i.e. The white spaces somtimes appears sometimes not).
I have tried adding function calls to clear the WebViews cache. The horiztonal white spaces appears less frequently in webView2, but the problem still persists.
It is interesting to know that this only happen in Android 4.0+ devices and does not happen in devices whose OS is Android 3 and below. We have tested this using Samsung Galaxy Notes II and Samsung Galaxy Tab 10.1 for Android 4 devices. We tested on Huawei Ideos U8150 for Android 2.2 device and a no brand device for Android 3 device.
I have set the minimum SDK target to API 8 and the maximum SDK target to API 15 when compiling the Android project.
I have already done extensive research on this problem in the Internet (including in StackOverflow) for 2 days, but I could not find any post similar to my problem's context.
I would like to know how to remove the horizontal white spaces in webView2. Please assists.
Thanks.
Please see code listing below:
package com.xyz.XyzPkg;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ScrollView;
import android.graphics.Bitmap;
public class OpenxyzActivitiesActivity extends Activity implements OnClickListener {
private final static int ID_BTNBACK = 987654321;
private final static int ID_BTNACTIVITY_UI1 = 999977777;
private final static int ID_BTNACTIVITY_UI2 = 999977776;
WebView webView1;
WebView webView2;
protected String TAG = OpenxyzActivitiesActivity.class.getSimpleName();
ImageButton btnBack;
int screenwidth = 0;
float fOrigWidth1 = 0.0f; //180.0f;
float fOrigWidth2 = 0.0f; //300.0f;
float fWeightSum = 0.0f;
float fWeight1 = 0.0f;
float fWeight2 = 0.0f;
float fWindowWidth = 0.0f;
float fWindowHeight = 0.0f;
float fWindowDensity = 0.0f;
float fInitScale1 = 0.0f;
float fInitScale2 = 0.0f;
int fViewportSize1 = 0;
int fViewportSize2 = 0;
int delta = 0;
boolean bChosenWidth = false;
String sUrlBase = "http://test.xyz.com/parents";
LinearLayout LinearLayout1;
ImageButton btnActivityUI1;
ImageButton btnActivityUI2;
FrameLayout frameLayout0;
LinearLayout LinearLayout4;
final int ID_WEBVIEW1 = 987654321;
#SuppressLint("SetJavaScriptEnabled")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
webView1 = new WebView(this);
webView1.setId(ID_WEBVIEW1);
webView1.getSettings().setJavaScriptEnabled(true);
webView2 = new WebView(this);
//new InitTask().execute(new String[]{sUrlBase + "/activities/sendActvtData.php"});
new InitTask().execute(new String[]{sUrlBase + "/activities/sendActvtData.php"});
}
//public class InitThread implements Runnable{
private class InitTask extends AsyncTask<String, Void, ArrayList<Float> >{
#Override
protected void onPostExecute(ArrayList<Float> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
frameLayout0 = new FrameLayout(getApplicationContext());
LinearLayout.LayoutParams oFrameLayout0Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
frameLayout0.setLayoutParams(oFrameLayout0Params);
LinearLayout LinearLayout0 = new LinearLayout(getApplicationContext());
LinearLayout0.setWeightSum(100.0f);
LinearLayout LinearLayout1 = new LinearLayout(getApplicationContext());
LinearLayout.LayoutParams oLinearLayout1Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout1.setLayoutParams(oLinearLayout1Params);
LinearLayout1.setWeightSum(100.0f);
//BEGIN: Setting up Window Size -- Change Windows Size in UI Thread
LayoutParams oLayoutParams = (LayoutParams)LinearLayout1.getLayoutParams();
oLayoutParams.width = (int)fWindowWidth;
oLayoutParams.height = (int)fWindowHeight;
LinearLayout1.setLayoutParams(oLayoutParams);
LinearLayout linearLayoutDummyProduct = new LinearLayout(getApplicationContext());
android.widget.LinearLayout.LayoutParams linearLayoutDummyProductLayoutParams = new android.widget.LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
linearLayoutDummyProduct.setLayoutParams(linearLayoutDummyProductLayoutParams);
oLayoutParams = (LayoutParams)linearLayoutDummyProduct.getLayoutParams();
LinearLayout linearLayoutDummyProduct2 = new LinearLayout(getApplicationContext());
linearLayoutDummyProduct2.setLayoutParams(linearLayoutDummyProductLayoutParams);
oLayoutParams = (LayoutParams)linearLayoutDummyProduct2.getLayoutParams();
float fDummy1Weight = 0.0f;
float fFrameLayoutWeight = 0.0f;
if (bChosenWidth)
{
LinearLayout0.setOrientation(LinearLayout.VERTICAL);
fDummy1Weight = 100.0f*delta/fWindowHeight;
linearLayoutDummyProductLayoutParams = new android.widget.LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, fDummy1Weight);
fFrameLayoutWeight = 100.0f-2*fDummy1Weight;
oFrameLayout0Params = new android.widget.LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, fFrameLayoutWeight);
Log.d(TAG, "fDummy1Weight = 100.0f*delta/fWindowHeight;");
}
else{
LinearLayout0.setOrientation(LinearLayout.HORIZONTAL);
fDummy1Weight = 100.0f*delta/fWindowWidth;
linearLayoutDummyProductLayoutParams = new android.widget.LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, fDummy1Weight);
fFrameLayoutWeight = 100.0f-2*fDummy1Weight;
oFrameLayout0Params = new android.widget.LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, fFrameLayoutWeight);
Log.d(TAG, "fDummy1Weight = 100.0f*delta/fWindowWidth;");
}
Log.d(TAG, "fDummy1Weight = " + fDummy1Weight);
Log.d(TAG, "fFrameLayoutWeight = " + fFrameLayoutWeight);
linearLayoutDummyProduct.setLayoutParams(linearLayoutDummyProductLayoutParams);
linearLayoutDummyProduct2.setLayoutParams(linearLayoutDummyProductLayoutParams);
frameLayout0.setLayoutParams(oFrameLayout0Params);
//END: Setting up Window Size
float fWeightSum = LinearLayout1.getWeightSum();
float fWidthSum = fOrigWidth1 + fOrigWidth2;
fWeight1 = fOrigWidth1 / fWidthSum * fWeightSum;
fWeight2 = fOrigWidth2 / fWidthSum * fWeightSum;
fViewportSize1 = screenwidth * (int)fOrigWidth1 / (int)(fOrigWidth1+fOrigWidth2);
fViewportSize2 = screenwidth * (int)fOrigWidth2 / (int)(fOrigWidth1+fOrigWidth2);
Log.d(TAG, "onPostExecute: fViewportSize1=" + fViewportSize1);
Log.d(TAG, "onPostExecute: fViewportSize2=" + fViewportSize2);
android.widget.LinearLayout.LayoutParams oLinearLayoutParams1 = new android.widget.LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, fWeight1);
android.widget.LinearLayout.LayoutParams oLinearLayoutParams2 = new android.widget.LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, fWeight2);
webView1.setLayoutParams(oLinearLayoutParams1);
webView2.setLayoutParams(oLinearLayoutParams2);
oLinearLayoutParams1 = (android.widget.LinearLayout.LayoutParams)webView1.getLayoutParams();
oLinearLayoutParams2 = (android.widget.LinearLayout.LayoutParams)webView2.getLayoutParams();
webView2.getSettings().setUseWideViewPort(false);
LinearLayout1.addView(webView1);
LinearLayout1.addView(webView2);
Log.d(TAG, "onPostExecute: fWeightSum=" + fWeightSum);
Log.d(TAG, "onPostExecute: fWidthSum=" + fWidthSum);
Log.d(TAG, "onPostExecute: oLinearLayoutParams1.weight=" + oLinearLayoutParams1.weight);
Log.d(TAG, "onPostExecute: oLinearLayoutParams2.weight=" + oLinearLayoutParams2.weight);
webView1.setInitialScale((int)fInitScale1);
webView2.setInitialScale((int)fInitScale2);
webView1.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView2.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView1.setPersistentDrawingCache(ViewGroup.PERSISTENT_NO_CACHE);
webView1.clearCache(true);
webView1.clearHistory();
webView1.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
//webView1.loadUrl(sUrlBase + "/activities/?lang=en");
String sWebView1Url = sUrlBase + "/activities/?lang=en&viewport_width="+fViewportSize1 + "&viewport_initial_scale=" + fInitScale1*0.01f;
webView1.loadUrl(sWebView1Url);
Log.d(TAG, "onPostExecute(): sWebView1Url: " + sWebView1Url);
webView1.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url){
//webView1.stopLoading();
url = url + "&viewport_width=" + fViewportSize2 + "&viewport_initial_scale=" + fInitScale2*0.01f;
Log.d(TAG, "setWebViewClient: CHK000: url: " + url);
if (view.getId() == ID_WEBVIEW1)
{
Log.d(TAG, "ID_WEBVIEW1: " + ID_WEBVIEW1);
Log.d(TAG, "WebView1 stopped loading");
//view.stopLoading();
webView1.setPersistentDrawingCache(ViewGroup.PERSISTENT_NO_CACHE);
webView1.clearCache(true);
webView1.clearHistory();
webView2.setPersistentDrawingCache(ViewGroup.PERSISTENT_NO_CACHE);
webView2.clearView();
webView2.clearCache(true);
webView2.clearHistory();
Map<String, String> noCacheHeaders = new HashMap<String, String>(2);
noCacheHeaders.put("Pragma", "no-cache");
noCacheHeaders.put("Cache-Control", "no-cache");
// webView2.getSettings().setAppCacheMaxSize(0);
// webView2.getSettings().setAppCacheEnabled(false);
webView2.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView2.loadUrl(url, noCacheHeaders);
// webView2.loadUrl(url);
Log.d(TAG , "shouldOverrideUrlLoading(): fInitScale1: " + fInitScale1);
Log.d(TAG , "shouldOverrideUrlLoading(): fInitScale2: " + fInitScale2);
Log.d(TAG , "shouldOverrideUrlLoading(): webView1.getScale(): " + webView1.getScale());
Log.d(TAG , "shouldOverrideUrlLoading(): webView2.getScale(): " + webView2.getScale());
Log.d(TAG, "shouldOverrideUrlLoading(): ((LinearLayout.LayoutParams)webView2.getLayoutParams()).weight: " + ((LinearLayout.LayoutParams)webView2.getLayoutParams()).weight);
Log.d(TAG , "shouldOverrideUrlLoading(): url: " + url);
webView1.setInitialScale((int)fInitScale1);
webView2.setInitialScale((int)fInitScale2);
}
else
{
Log.d(TAG, "Other Web View triggered shouldOverrideUrlLoading");
}
return true;
}
});
webView2.setPersistentDrawingCache(ViewGroup.PERSISTENT_NO_CACHE);
webView2.clearView();
webView2.clearCache(true);
webView2.clearHistory();
// Map<String, String> noCacheHeaders = new HashMap<String, String>(2);
// noCacheHeaders.put("Pragma", "no-cache");
// noCacheHeaders.put("Cache-Control", "no-cache");
// webView2.getSettings().setAppCacheMaxSize(0);
// webView2.getSettings().setAppCacheEnabled(false);
webView2.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// webView2.loadUrl("http://parents.xyz.com/activities/?catg=coloring", noCacheHeaders);
//webView2.loadUrl(sUrlBase + "/activities/?catg=coloring");
webView2.loadUrl(sUrlBase + "/activities/?catg=coloring&viewport_width="+fViewportSize2 + "&viewport_initial_scale=" + fInitScale1*0.01f);
//webView2.getSettings().setTextSize(t)
frameLayout0.addView(LinearLayout1);
LinearLayout LinearLayout2 = new LinearLayout(getApplicationContext());
LinearLayout.LayoutParams oLinearLayout2Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout2.setLayoutParams(oLinearLayout2Params);
LinearLayout2.setWeightSum(100.0f);
LinearLayout2.setOrientation(LinearLayout.HORIZONTAL);
frameLayout0.addView(LinearLayout2);
ImageView btnInvisible0 = new ImageView(getApplicationContext());
LinearLayout.LayoutParams btnInvisible0Params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 90.0f);
btnInvisible0.setLayoutParams(btnInvisible0Params);
LinearLayout LinearLayout3 = new LinearLayout(getApplicationContext());
LinearLayout.LayoutParams oLinearLayout3Params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 10.0f);
LinearLayout3.setLayoutParams(oLinearLayout3Params);
LinearLayout3.setWeightSum(100.0f);
LinearLayout3.setOrientation(LinearLayout.VERTICAL);
btnBack = new ImageButton(getApplicationContext());
btnBack.setId(ID_BTNBACK);
LinearLayout.LayoutParams btnBackParams = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 0, 18.0f);
btnBack.setLayoutParams(btnBackParams);
btnBack.setScaleType(ScaleType.FIT_XY);
btnBack.post(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
btnBack.setBackgroundDrawable((Drawable)getResources().getDrawable(R.drawable.btn_back));
}
});
btnBack.setOnClickListener(OpenxyzActivitiesActivity.this);
ImageView btnInvisible1 = new ImageView(getApplicationContext());
LinearLayout.LayoutParams btnInvisible1Params = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 0, 82.0f);
btnInvisible1.setLayoutParams(btnInvisible1Params);
LinearLayout4 = new LinearLayout(getApplicationContext());
LinearLayout.LayoutParams oLinearLayout4Params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout4.setLayoutParams(oLinearLayout4Params);
LinearLayout4.setWeightSum(100.0f);
LinearLayout4.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout4.setOnClickListener(OpenxyzActivitiesActivity.this);
frameLayout0.addView(LinearLayout4);
btnActivityUI1 = new ImageButton(getApplicationContext());
btnActivityUI1.setId(ID_BTNACTIVITY_UI1);
LinearLayout.LayoutParams btnActivityUI1Params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 37.5f);
btnActivityUI1.setLayoutParams(btnActivityUI1Params);
btnActivityUI1.setScaleType(ScaleType.FIT_CENTER);
btnActivityUI1.post(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
btnActivityUI1.setImageDrawable((Drawable)getResources().getDrawable(R.drawable.activityui_300));
}
});
btnActivityUI1.setOnClickListener(OpenxyzActivitiesActivity.this);
btnActivityUI2 = new ImageButton(getApplicationContext());
btnActivityUI2.setId(ID_BTNACTIVITY_UI2);
LinearLayout.LayoutParams btnActivityUI2Params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 62.5f);
btnActivityUI2.setLayoutParams(btnActivityUI2Params);
btnActivityUI2.setScaleType(ScaleType.FIT_CENTER);
btnActivityUI2.post(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
btnActivityUI2.setImageDrawable((Drawable)getResources().getDrawable(R.drawable.activityui_500));
}
});
btnActivityUI2.setOnClickListener(OpenxyzActivitiesActivity.this);
LinearLayout4.addView(btnActivityUI1);
LinearLayout4.addView(btnActivityUI2);
LinearLayout3.addView(btnBack);
LinearLayout3.addView(btnInvisible1);
LinearLayout2.addView(btnInvisible0);
LinearLayout2.addView(LinearLayout3);
LinearLayout0.addView(linearLayoutDummyProduct);
LinearLayout0.addView(frameLayout0);
LinearLayout0.addView(linearLayoutDummyProduct2);
setContentView(LinearLayout0);
}
#Override
protected ArrayList<Float> doInBackground(String... params) {
// TODO Auto-generated method stub
Log.d(InitTask.class.getSimpleName() , "params[0]: " + params[0]);
return callHttp(params[0]);
}
private ArrayList<Float> callHttp(String url) {
ArrayList<Float> alResult = new ArrayList<Float>();
//BEGIN HTTP Request...
//String url = "http://parents.xyz.com/activities/sendActvtData.php";
Log.d(InitTask.class.getSimpleName() , "url: " + url);
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet(url);
Log.d(TAG , "CHK000");
// Execute the request
HttpResponse response;
String result = "";
try {
Log.d(TAG , "CHK010");
response = httpclient.execute(httpget);
// Examine the response status
Log.d(TAG , "CHK020");
Log.i(TAG,response.getStatusLine().toString());
Log.d(TAG , "CHK030");
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
Log.d(TAG , "Is entity null? " + ((entity == null)?"YES":"NO") );
Log.d(TAG , "CHK040");
if (entity != null) {
// A Simple JSON Response Read
InputStream instream = entity.getContent();
result= convertStreamToString(instream);
// now you have the string representation of the HTML request
instream.close();
}
Log.d(TAG , "CHK100");
}
catch (ClientProtocolException cpe){
Log.e(TAG , cpe.getMessage());
}
catch (IOException ioe){
Log.e(TAG , ioe.getMessage());
}
catch (Exception e) {
Log.d(TAG , "CHK EXP");
Log.d(TAG, e.toString());
}
//END HTTP Request...
Log.d(TAG, "http result: " + result);
String[] ActvData = result.split(",");
fOrigWidth1 = Float.parseFloat(ActvData[0]);
fOrigWidth2 = Float.parseFloat(ActvData[1]);
Log.d(TAG, "fOrigWidth1: " + fOrigWidth1);
Log.d(TAG, "fOrigWidth2: " + fOrigWidth2);
//BEGIN: Setting up Window Size -- Calculation
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenwidth = metrics.widthPixels;
int screenheight = metrics.heightPixels;
Log.d(TAG, "screenwidth: " + screenwidth);
Log.d(TAG, "screenheight: " + screenheight);
//800x480
float heightFactor = (float)screenheight / 480f;
float widthFactor = (float)screenwidth / 800f;
float chosenFactor = 1f;
bChosenWidth = false;
if (widthFactor < heightFactor)
{
bChosenWidth = true;
chosenFactor = widthFactor;
}
else
{
bChosenWidth = false;
chosenFactor = heightFactor;
}
int newHeight = (int)((float)480.0 * (float)chosenFactor);
int newWidth = (int)((float)800.0 * (float)chosenFactor);
Log.d(TAG, "heightFactor: " + heightFactor);
Log.d(TAG, "widthFactor: " + widthFactor);
Log.d(TAG, "newHeight: " + newHeight);
Log.d(TAG, "newWidth: " + newWidth);
delta = 0;
if (bChosenWidth)
{
delta = (screenheight - newHeight) / 2;
}
else{
delta = (screenwidth - newWidth) / 2;
}
Log.d(TAG, "delta: " + delta);
//END: Setting up Window Size -- Calculation
fWindowWidth = newWidth;
fWindowHeight = newHeight;
fWindowDensity = (float)metrics.density;
fWeight1 = fOrigWidth1;
fWeight2 = fOrigWidth2;
fWeightSum = fWeight1 + fWeight2;
Log.d(TAG , "fWeight1: " + fWeight1);
Log.d(TAG , "fWeight2: " + fWeight2);
fInitScale1 = 0.0f;
fInitScale2 = 0.0f;
fInitScale1 = fInitScale2 = fWindowWidth / fWeightSum * 100;
Log.d(TAG , "fWindowWidth: " + fWindowWidth);
Log.d(TAG , "fWindowHeight: " + fWindowHeight);
Log.d(TAG , "fWindowDensity: " + fWindowDensity);
Log.d(TAG , "fInitScale1: " + fInitScale1);
Log.d(TAG , "fInitScale2: " + fInitScale2);
Log.d(TAG , "CHK200");
return alResult;
}
private String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case ID_BTNBACK:
Intent myIntent = new Intent();
setResult(Activity.RESULT_OK, myIntent);
finish();
break;
case ID_BTNACTIVITY_UI1: case ID_BTNACTIVITY_UI2:
LinearLayout4.setClickable(false);
frameLayout0.removeView(LinearLayout4);
break;
}
}
}

Retrieve String values from a CategoryAxis in a javaFX Line Chart -CategoryAxis JavaFx 2.2.3 bug in .getValueForDisplay(double displayPosition)-

I have a JavaFXline chart with months versus values. I'm trying to print in the console the month and the value from a Line chart every time I click the graph .The problem is that when I call the method getValueForDisplay in my CategoryAxis object, it returns null.
When I click (x,y):jan,3
I want to print:
X value = jan Y value: 3
but the program is printing:
X value = **null** Y value: 2.7796610169491527
Another question;
2) Why when attempting to print the coordinates it seems to be not calibrated (if I click on 3 the program print 2.779661016949152? You can notice this issue checking the values printed on the console.
Here is the code I'm using:
public class LineChartTest extends Application {
String xValue;
Number yValue;
private void init(Stage primaryStage) {
Group root = new Group();
primaryStage.setScene(new Scene(root));
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis("Values for Y-Axis", 0, 3, 1);
yAxis.setUpperBound(5);
ObservableList<XYChart.Series<String,Double>> lineChartData = FXCollections.observableArrayList(
new LineChart.Series<String,Double>("en", FXCollections.observableArrayList(
new XYChart.Data<String,Double>("jan", 1.0),
new XYChart.Data<String,Double>("feb", 2.0),
new XYChart.Data<String,Double>("mar", 3.0),
new XYChart.Data<String,Double>("apr", 4.0),
new XYChart.Data<String,Double>("may", 0.5)
)),
new LineChart.Series<String,Double>("to", FXCollections.observableArrayList(
new XYChart.Data<String,Double>("jan", 1.6),
new XYChart.Data<String,Double>("feb", 0.4),
new XYChart.Data<String,Double>("mar", 2.9),
new XYChart.Data<String,Double>("apr", 1.3),
new XYChart.Data<String,Double>("may", 0.9)
))
);
//define a new line
final Series<String,Double> otherSeries = new Series<String,Double>();
//set points
otherSeries.getData().add(new XYChart.Data("jan",3));
otherSeries.getData().add(new XYChart.Data("feb",2));
otherSeries.getData().add(new XYChart.Data("mar",4));
//set name to the line
otherSeries.setName("tre");
//add the new line to the graph
lineChartData.add(otherSeries);
final LineChart chart = new LineChart(xAxis, yAxis, lineChartData);
//set title to the figure
chart.setTitle("Line Chart Test");
root.getChildren().add(chart);
chart.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
//Why this seems to be not working properly?
double sceneX = t.getSceneX();
double sceneY = t.getSceneY();
//gives the point of the graph
xValue = xAxis.getValueForDisplay(sceneX);
yValue = yAxis.getValueForDisplay(sceneY);
System.out.println("sceneX-25: "+ sceneX);
System.out.println("getDisplayPosition: " + xAxis.getValueForDisplay(sceneX));
//Test
System.out.println(" X value = " +
xValue + " Y value: " + yValue );
}
});
}
#Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Answer:
Thanks to Sergey Grinev and Uluk Biy
in the previous code you have to modified:
Line chart code:
chart.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
Node chartPlotBackground = chart.lookup(".chart-plot-background");
final double shiftX = xSceneShift(chartPlotBackground);
final double shiftY = ySceneShift(chartPlotBackground);
double x = e.getSceneX() - shiftX;
double y = e.getSceneY() - shiftY;
xValue = xAxis.getValueForDisplay(x);
yValue = yAxis.getValueForDisplay(y );
System.out.println("shiftX = " + shiftX + " shiftY: " + shiftY);
System.out.println("X value = "
+ xValue + " \nY value: " + yValue);
}
});
}
//recursive calls
private double xSceneShift(Node node) {
return node.getParent() == null ? 0 : node.getBoundsInParent().getMinX() + xSceneShift(node.getParent());
}
private double ySceneShift(Node node) {
return node.getParent() == null ? 0 : node.getBoundsInParent().getMinY() + ySceneShift(node.getParent());
}
#Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
in the CategoryAxis source code you have to modified (look at the comments!):
#Override public String getValueForDisplay(double displayPosition) {
if (getSide().equals(Side.TOP) || getSide().equals(Side.BOTTOM)) { // HORIZONTAL
if (displayPosition < 0 || displayPosition > getHeight()) return null; // <-------------- WRONG SHOULD BE displayPosition > getWidth()
double d = (displayPosition - firstCategoryPos.get()) / categorySpacing.get();
return toRealValue(d);
} else { // VERTICAL
if (displayPosition < 0 || displayPosition > getWidth()) return null; // <-------------- WRONG SHOULD BE displayPosition > getHeight()
double d = (displayPosition - firstCategoryPos.get()) / (categorySpacing.get() * -1);
return toRealValue(d);
}
}
you can find the source code here:
http://hg.openjdk.java.net/openjfx/2.1/master/rt/file/5c3b3d524f07/javafx-ui-controls/src/javafx/scene/chart/CategoryAxis.java
If you are aiming to display the data point that user clicked on the chart, then you can access directly to the underlining data. Hover to the data X-Y intersection points on this example:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.control.LabelBuilder;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
public class ChartDemo extends Application {
private DropShadow ds = new DropShadow();
#Override
public void start(Stage stage) {
stage.setTitle("Linear plot");
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis(0, 22, 0.5);
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
#Override
public String toString(Number object) {
return String.format("%7.2f", object);
}
});
final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
lineChart.setCreateSymbols(true);
lineChart.setAlternativeRowFillVisible(false);
lineChart.setLegendVisible(false);
final XYChart.Series series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Jan", 1));
series1.getData().add(new XYChart.Data("Feb", 1.5));
series1.getData().add(new XYChart.Data("Mar", 2));
series1.getData().add(new XYChart.Data("Apr", 2.5));
series1.getData().add(new XYChart.Data("May", 3));
series1.getData().add(new XYChart.Data("Jun", 4));
series1.getData().add(new XYChart.Data("Jul", 6));
series1.getData().add(new XYChart.Data("Aug", 9));
series1.getData().add(new XYChart.Data("Sep", 12));
series1.getData().add(new XYChart.Data("Oct", 15));
series1.getData().add(new XYChart.Data("Nov", 20));
series1.getData().add(new XYChart.Data("Dec", 22));
final Label lbl = LabelBuilder.create().font(Font.font("Arial", FontWeight.BOLD, 25))
.textFill(Color.BLUEVIOLET).translateY(-200).build();
StackPane pane = new StackPane();
pane.getChildren().addAll(lineChart, lbl);
Scene scene = new Scene(pane, 800, 600);
lineChart.getData().addAll(series1);
for (Object obj : series1.getData()) {
final XYChart.Data data = (XYChart.Data) obj;
final Node node = data.getNode();
node.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
node.setEffect(ds);
node.setCursor(Cursor.HAND);
lbl.setText("X-value=" + data.getXValue().toString() + "\nY-value=" + data.getYValue().toString());
System.out.println("X-value=" + data.getXValue().toString() + ", Y-value=" + data.getYValue().toString());
}
});
node.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
node.setEffect(null);
node.setCursor(Cursor.DEFAULT);
lbl.setText("");
}
});
}
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
There are 2 issues.
1) You are using wrong coordinates. getValueForDisplay expects coordinates relative to chart drawing area, not to scene.
To fix that you can use next trick.
Introduce next recursive calls to calculate scene shift:
private double xSceneShift(Node node) {
return node.getParent() == null ? 0 : node.getBoundsInParent().getMinX() + xSceneShift(node.getParent());
}
private double ySceneShift(Node node) {
return node.getParent() == null ? 0 : node.getBoundsInParent().getMinY() + ySceneShift(node.getParent());
}
Find shift of chart drawing area:
Node chartPlotBackground = chart.lookup(".chart-plot-background");
final double shiftX = xSceneShift(chartPlotBackground);
final double shiftY = ySceneShift(chartPlotBackground);
And use them in your mouse handler:
public void handle(MouseEvent e) {
double x = e.getSceneX() - shiftX;
double y = e.getSceneY() - shiftY;
xValue = xAxis.getValueForDisplay(x );
yValue = yAxis.getValueForDisplay(y);
System.out.println(" X value = "
+ xValue + " \nY value: " + yValue);
}
2) You met an issue in CategoryAxis which is fixed but in next release (8.0): http://javafx-jira.kenai.com/browse/RT-25899
As a workaround you can download CategoryAxis source, rename it to MyCategoryAxis and fix a bug in method getValueForDisplay() -- just switch places of getWidth() and getHeight() call.
http://hg.openjdk.java.net/openjfx/2.1/master/rt/file/5c3b3d524f07/javafx-ui-controls/src/javafx/scene/chart/CategoryAxis.java

table component not working in lwuit?

I want to display the table after selecting the values from comboBox. It working first time selection after that it adding another two more table in UI.
Can anyone say how to fix this?
Here the code:
package com.onmo.classes;
import java.io.IOException;
import com.sun.lwuit.Button;
import com.sun.lwuit.ComboBox;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Form;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import com.sun.lwuit.TabbedPane;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.events.SelectionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.layouts.FlowLayout;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.table.DefaultTableModel;
import com.sun.lwuit.table.Table;
import com.sun.lwuit.table.TableModel;
import com.sun.lwuit.util.Resources;
public class CompareScreen implements ActionListener, SelectionListener {
private Command enterCmd;
private Command backCmd;
private Command exitCmd;
private Form comparePage;
private Label lblLeagues, lblTeam;
private Button btnTeams, btnPlayers;
private FlowLayout flowLayout;
private ComboBox comboTeamA, comboTeamB, comboTeamC, comboTeamD, player1,
player2;
private Image firstTeamImage, secondTeamImage = null;
private Container teamsContainer, teamCombo, teamImages, playersTeamTab,
playersContainer, playersTab, playerImages;
int count = 0;
CompareScreen(){
enterCmd = new Command("Select");
backCmd = new Command("Back");
exitCmd = new Command("Exit");
}
public void displayCompareScreen() {
comparePage = new Form();
// comparePage.getStyle().setBgColor(0xaa00ff);
String[] teamA = { "Team A", "Villarreal", "Violent Vegans",
"Venom XI", "Betis" };
String[] teamB = { "Team B", "Villarreal", "Violent Vegans",
"Venom XI", "Betis" };
String[] playerList1 = { "Player1", "Acho, Sam", "Adams, Mike",
"Ajirotutu, Seyi", "Abel Gomez" };
String[] playerList2 = { "Player2", "Acho, Sam", "Adams, Mike",
"Ajirotutu, Seyi", "Abel Gomez" };
comparePage.addCommand(backCmd);
comparePage.addCommandListener(this);
lblLeagues = new Label("Premier League");
lblTeam = new Label("Team");
btnTeams = new Button("Teams");
btnPlayers = new Button("Players");
comboTeamA = new ComboBox(teamA);
comboTeamB = new ComboBox(teamB);
comboTeamC = new ComboBox(teamA);
comboTeamD = new ComboBox(teamB);
player1 = new ComboBox(playerList1);
player2 = new ComboBox(playerList2);
comparePage.setLayout(new BorderLayout());
comparePage
.addComponent(BorderLayout.WEST, new Label("Premier League"));
comparePage.addComponent(BorderLayout.EAST, new Label("Compare"));
flowLayout = new FlowLayout();
comparePage.setLayout(flowLayout);
try {
Resources r = Resources.open("/theme/javathema.res");
UIManager.getInstance().setThemeProps(r.getTheme("javathema"));
} catch (IOException ioe) {
System.out.println("Couldn't load theme.");
}
try {
firstTeamImage = Image.createImage("/team1.png");
secondTeamImage = Image.createImage("/team2.png");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Label lblFirstTeam = new Label(firstTeamImage);
lblFirstTeam.setAlignment(Component.LEFT);
Label lblSecondTeam = new Label(secondTeamImage);
lblSecondTeam.setAlignment(Component.RIGHT);
Label lblFirstPlayer = new Label(firstTeamImage);
lblFirstTeam.setAlignment(Component.LEFT);
Label lblSecondPlayer = new Label(secondTeamImage);
lblSecondTeam.setAlignment(Component.RIGHT);
teamsContainer = new Container(new BoxLayout(BoxLayout.Y_AXIS));
teamCombo = new Container(new BoxLayout(BoxLayout.X_AXIS));
teamCombo.addComponent(comboTeamA);
teamCombo.addComponent(comboTeamB);
teamImages = new Container(new BoxLayout(BoxLayout.X_AXIS));
teamImages.addComponent(lblFirstTeam);
teamImages.addComponent(lblSecondTeam);
teamsContainer.addComponent(teamCombo);
teamsContainer.addComponent(teamImages);
playersTeamTab = new Container(new BoxLayout(BoxLayout.X_AXIS));
playersTeamTab.addComponent(comboTeamC);
playersTeamTab.addComponent(comboTeamD);
playersTab = new Container(new BoxLayout(BoxLayout.X_AXIS));
playersTab.addComponent(player1);
playersTab.addComponent(player2);
playerImages = new Container(new BoxLayout(BoxLayout.X_AXIS));
playerImages.addComponent(lblFirstPlayer);
playerImages.addComponent(lblSecondPlayer);
playersContainer = new Container(new BoxLayout(BoxLayout.Y_AXIS));
playersContainer.addComponent(playersTeamTab);
playersContainer.addComponent(playersTab);
playersContainer.addComponent(playerImages);
TabbedPane tabbedPane = new TabbedPane(TabbedPane.TOP);
tabbedPane.addTab("Teams", teamsContainer);
tabbedPane.addTab("Players", playersContainer);
// comboTeamA.addSelectionListener(this);
comboTeamB.addSelectionListener(this);
// comboTeamC.addSelectionListener(this);
comboTeamD.addSelectionListener(this);
// comboTeamA.addActionListener(this);
comparePage.addComponent(tabbedPane);
comparePage.show();
}
public void selectionChanged(int arg0, int arg1) {
// TODO Auto-generated method stub
System.out.println("Before :" + count);
Table tableTeam = null, tablePlayer = null;
if (comboTeamA.getSelectedIndex() != 0 && comboTeamB.getSelectedIndex() != 0 && comboTeamC.getSelectedIndex() == 0 && comboTeamD.getSelectedIndex() == 0) {
TableModel model = new DefaultTableModel(new String[] { "10 ",
"Games Played", "10" }, new Object[][] {
{ "7 ", "Wins", " 6" }, { "2 ", "Draws", " 1" },
{ "1 ", "Defeats", " 1" }, { "10 ", "Goals for", " 8" }, });
tableTeam = new Table(model);
if (count == 1) {
teamsContainer.addComponent(tableTeam);
count = 0;
}
count = count + 1;
System.out.println("On :" + count);
}
if (comboTeamA.getSelectedIndex() == 0 && comboTeamB.getSelectedIndex() == 0 && comboTeamC.getSelectedIndex() != 0 && comboTeamD.getSelectedIndex() != 0) {
TableModel model = new DefaultTableModel(new String[] { "10 ",
"Games Played", "10" }, new Object[][] {
{ "260 ", "Minutes Played", " 280" },
{ "240 ", "Starts", " 230" },
{ "20 ", "Substitute", " 30" },
{ "6 ", "Goals for", " 9" }, });
tablePlayer = new Table(model);
if (count == 1) {
playersContainer.addComponent(tablePlayer);
count = 0;
}
count = count + 1;
System.out.println("On :" + count);
}
/*
* if(tableTeam != null && tablePlayer != null) {
* teamsContainer.removeComponent(tableTeam);
* playersContainer.removeComponent(tablePlayer); }
*/
System.out.println("After :" + count);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
HomePage homePageObj=HomePage.getInstance();
homePageObj.displayHomePage();
}
}
The problem is at this code:
public void selectionChanged(int arg0, int arg1) {
...
tableTeam = new Table(model);
if (count == 1) {
teamsContainer.addComponent(tableTeam);
count = 0;
}
count = count + 1;
...
}
This code snippet means that you add another Table each time you select another value from the ComboBox : DON'T RESET "count" TO 0 !

Resources