1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation. Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javafx.scene.control.test.chart.apps;
  26 
  27 import java.util.Arrays;
  28 import java.util.Comparator;
  29 import java.util.Iterator;
  30 import java.util.Random;
  31 import javafx.beans.property.DoubleProperty;
  32 import javafx.beans.property.SimpleDoubleProperty;
  33 import javafx.beans.value.ChangeListener;
  34 import javafx.beans.value.ObservableValue;
  35 import javafx.collections.FXCollections;
  36 import javafx.collections.ObservableList;
  37 import javafx.event.ActionEvent;
  38 import javafx.event.Event;
  39 import javafx.event.EventHandler;
  40 import javafx.scene.Scene;
  41 import javafx.scene.chart.AreaChart;
  42 import javafx.scene.chart.NumberAxis;
  43 import javafx.scene.chart.XYChart;
  44 import javafx.scene.chart.XYChart.Series;
  45 import javafx.scene.control.*;
  46 import static javafx.scene.control.test.chart.apps.ChartIDsInterface.HARD_RESET_BUTTON_ID;
  47 import static javafx.scene.control.test.chart.apps.CommonFunctions.*;
  48 import javafx.scene.control.test.utils.CommonPropertiesScene;
  49 import javafx.scene.control.test.utils.ptables.PropertiesTable;
  50 import javafx.scene.control.test.utils.ptables.TabPaneWithControl;
  51 import javafx.scene.layout.HBox;
  52 import javafx.scene.layout.VBox;
  53 import test.javaclient.shared.InteroperabilityApp;
  54 import test.javaclient.shared.Utils;
  55 
  56 /**
  57  * @author Alexander Kirov
  58  */
  59 public class NewAreaChartApp extends InteroperabilityApp implements ChartIDsInterface {
  60 
  61     public final static String REMOVE_ITEM_POS_TEXT_FIELD_ID = "REMOVE_ITEM_POS_TEXT_FIELD_ID";
  62     public final static String REMOVE_BUTTON_ID = "REMOVE_BUTTON_ID";
  63     public final static String ADD_ITEM_TEXT_FIELD_ID = "ADD_ITEM_TEXT_FIELD_ID";
  64     public final static String ADD_ITEM_POSITION_TEXT_FIELD_ID = "ADD_ITEM_POSITION_TEXT_FIELD_ID";
  65     public final static String ADD_ITEM_BUTTON_ID = "ADD_ITEM_BUTTON_ID";
  66     public final static String REMOVE_AREA_POS_TEXT_FIELD_ID = "REMOVE_AREA_POS_TEXT_FIELD_ID";
  67     public final static String REMOVE_INDEX_TEXT_FIELD_ID = "REMOVE_INDEX_TEXT_FIELD_ID";
  68     public final static String ADD_AREA_POS_TEXT_FIELD_ID = "ADD_AREA_POS_TEXT_FIELD_ID";
  69     public final static String ADD_INDEX_TEXT_FIELD_ID = "ADD_INDEX_TEXT_FIELD_ID";
  70     public final static String ADD_VALUE_TEXT_FIELD_ID = "ADD_VALUE_TEXT_FIELD_ID";
  71 
  72     public static void main(String[] args) {
  73         Utils.launch(NewAreaChartApp.class, args);
  74     }
  75 
  76     @Override
  77     protected Scene getScene() {
  78         Utils.setTitleToStage(stage, "AreaChartTestApp");
  79         return new NewAreaChartApp.AreaChartScene();
  80     }
  81 
  82     class AreaChartScene extends CommonPropertiesScene {
  83 
  84         //AreaChart to be tested.
  85         AreaChart testedAreaChart;
  86         NumberAxis axis1;
  87         NumberAxis axis2;
  88         TabPaneWithControl pane;
  89 
  90         public AreaChartScene() {
  91             super("AreaChart", 1300, 800);
  92         }
  93 
  94         @Override
  95         final protected void prepareScene() {
  96             Utils.addBrowser(this);
  97 
  98             axis1 = new NumberAxis(0, 100, 10);
  99             axis2 = new NumberAxis(0, 100, 10);
 100             testedAreaChart = getNewChart();
 101             testedAreaChart.setId(TESTED_CHART_ID);
 102 
 103             Button hardResetButton = new Button("Hard reset");
 104             hardResetButton.setId(HARD_RESET_BUTTON_ID);
 105             hardResetButton.setOnAction(new EventHandler<ActionEvent>() {
 106                 public void handle(ActionEvent t) {
 107                     HBox hb = (HBox) getRoot();
 108                     hb.getChildren().clear();
 109                     prepareMainSceneStructure();
 110                     prepareScene();
 111                 }
 112             });
 113 
 114             Button softResetButton = new Button("Soft reset");
 115             softResetButton.setId(SOFT_RESET_BUTTON_ID);
 116             softResetButton.setOnAction(new EventHandler<ActionEvent>() {
 117                 public void handle(ActionEvent t) {
 118                     //throw new UnsupportedOperationException("Not supported yet.");
 119                 }
 120             });
 121 
 122             HBox resetButtonsHBox = new HBox();
 123             resetButtonsHBox.getChildren().addAll(hardResetButton, softResetButton);
 124 
 125             VBox vb = new VBox(5);
 126             vb.getChildren().addAll(resetButtonsHBox, getAddAreaHBox(), getAddPointToDataDialog(), getRemovePointFromDataDialog(), getRemoveDataDialog());
 127 
 128             pane = getPaneFor(testedAreaChart, CHART_TAB_NAME, axis1, AXIS_1_TAB_NAME, axis2, AXIS_2_TAB_NAME);
 129 
 130             setTestedControlContainerSize(500, 500);
 131             setTestedControl(testedAreaChart);
 132             setPropertiesContent(pane);
 133             setControllersContent(vb);
 134         }
 135 
 136         public HBox getAddPointToDataDialog() {
 137             HBox hb = new HBox();
 138 
 139             Label lb1 = new Label("To area");
 140             final TextField tf1 = new TextField("0");
 141             tf1.setPrefWidth(50);
 142             tf1.setId(ADD_AREA_POS_TEXT_FIELD_ID);
 143 
 144             Label lb2 = new Label("to index");
 145             final TextField tf2 = new TextField("0");
 146             tf2.setPrefWidth(50);
 147             tf2.setId(ADD_INDEX_TEXT_FIELD_ID);
 148 
 149             Label lb3 = new Label("value");
 150             final TextField tf3 = new TextField("0");
 151             tf3.setPrefWidth(50);
 152             tf3.setId(ADD_VALUE_TEXT_FIELD_ID);
 153 
 154             Button bt = new Button("add point!");
 155             bt.setId(REMOVE_BUTTON_ID);
 156             bt.setOnAction(new EventHandler() {
 157                 public void handle(Event t) {
 158                     int area = Integer.parseInt(tf1.getText());
 159                     int point = Integer.parseInt(tf2.getText());
 160                     double value = Double.parseDouble(tf3.getText());
 161 
 162                     XYChart.Data newData = new XYChart.Data();
 163                     newData.setXValue((((Double) ((XYChart.Data) (((Series) testedAreaChart.getData().get(area)).getData().get(point))).getXValue()) + ((Double) ((XYChart.Data) (((Series) testedAreaChart.getData().get(area)).getData().get(point - 1))).getXValue())) / 2);
 164                     newData.setYValue(value);
 165 
 166                     ((Series) testedAreaChart.getData().get(area)).getData().add(point, newData);
 167                 }
 168             });
 169             hb.getChildren().addAll(lb1, tf1, lb2, tf2, lb3, tf3, bt);
 170             return hb;
 171         }
 172 
 173         public HBox getRemovePointFromDataDialog() {
 174             HBox hb = new HBox();
 175 
 176             Label lb1 = new Label("From area");
 177             final TextField tf1 = new TextField("0");
 178             tf1.setPrefWidth(50);
 179             tf1.setId(REMOVE_AREA_POS_TEXT_FIELD_ID);
 180 
 181             Label lb2 = new Label("From index");
 182             final TextField tf2 = new TextField("0");
 183             tf2.setPrefWidth(50);
 184             tf2.setId(REMOVE_INDEX_TEXT_FIELD_ID);
 185 
 186             Button bt = new Button("remove point!");
 187             bt.setId(REMOVE_BUTTON_ID);
 188             bt.setOnAction(new EventHandler() {
 189                 public void handle(Event t) {
 190                     int area = Integer.parseInt(tf1.getText());
 191                     int point = Integer.parseInt(tf2.getText());
 192                     ((Series) testedAreaChart.getData().get(area)).getData().remove(point);
 193                 }
 194             });
 195             hb.getChildren().addAll(lb1, tf1, lb2, tf2, bt);
 196             return hb;
 197         }
 198 
 199         public HBox getRemoveDataDialog() {
 200             HBox hb = new HBox();
 201             Label lb = new Label("From index");
 202             final TextField tf = new TextField("0");
 203             tf.setPrefWidth(50);
 204             tf.setId(REMOVE_AREA_INDEX_TEXTFIELD_ID);
 205             Button bt = new Button("remove area!");
 206             bt.setId(REMOVE_AREA_BUTTON_ID);
 207             bt.setOnAction(new EventHandler() {
 208                 public void handle(Event t) {
 209                     int index = Integer.parseInt(tf.getText());
 210                     testedAreaChart.getData().remove(index);
 211                 }
 212             });
 213             hb.getChildren().addAll(lb, tf, bt);
 214             return hb;
 215         }
 216 
 217         public HBox getAddAreaHBox() {
 218             HBox hb = new HBox();
 219             Label lb = new Label("Add series named ");
 220             final TextField tf = new TextField();
 221             tf.setPrefWidth(50);
 222             tf.setId(ADDED_SERIES_NAME_TEXTFIELD_ID);
 223 
 224             Label minLabel = new Label(" minX ");
 225             final TextField minText = new TextField();
 226             minText.setPrefWidth(50);
 227             minText.setId(ADDED_SERIES_MIN_VALUE_TEXTFIELD_ID);
 228 
 229             Label maxLabel = new Label(" maxX ");
 230             final TextField maxText = new TextField();
 231             maxText.setPrefWidth(50);
 232             maxText.setId(ADDED_SERIES_MAX_VALUE_TEXTFIELD_ID);
 233 
 234             Label amountLabel = new Label(" with ");
 235             final TextField amountText = new TextField();
 236             amountText.setPrefWidth(50);
 237             amountText.setId(ADDED_SERIES_DOTS_COUNT_TEXTFIELD_ID);
 238 
 239             Button bt = new Button("add area!");
 240             bt.setId(ADD_SERIES_COMMAND_BUTTON_ID);
 241             bt.setOnAction(new EventHandler() {
 242                 public void handle(Event t) {
 243                     String serieName = tf.getText();
 244                     double min = Double.parseDouble(minText.getText());
 245                     double max = Double.parseDouble(maxText.getText());
 246                     int amount = Integer.parseInt(amountText.getText());
 247 
 248                     ObservableList list = FXCollections.observableArrayList();
 249 
 250                     for (int i = 0; i < amount; i++) {
 251                         XYChart.Data newData = new XYChart.Data();
 252                         newData.setXValue(new Random().nextDouble() * (max - min) + min);
 253                         newData.setYValue(new Random().nextDouble() * (max - min) + min);
 254                         list.add(newData);
 255                     }
 256                     Object[] array = list.toArray();
 257                     Arrays.sort(array, new Comparator() {
 258                         public int compare(Object t, Object t1) {
 259                             return (int) Math.round(((Double) ((XYChart.Data) t).getXValue()) - ((Double) ((XYChart.Data) t1).getXValue()));
 260                         }
 261                     });
 262 
 263                     XYChart.Series serie = new XYChart.Series(serieName, FXCollections.observableArrayList(array));
 264 
 265                     testedAreaChart.getData().add(serie);
 266                     pane.addPropertiesTable(serieName, getTableForProperty(serie, min, max).getVisualRepresentation());
 267                 }
 268             });
 269             hb.getChildren().addAll(lb, tf, minLabel, minText, maxLabel, maxText, amountLabel, amountText, bt);
 270             return hb;
 271         }
 272 
 273         protected PropertiesTable getTableForProperty(XYChart.Series serie, double min, double max) {
 274             PropertiesTable table = new PropertiesTable(serie);
 275 
 276             table.addSimpleListener(serie.chartProperty(), serie);
 277             table.addSimpleListener(serie.nameProperty(), serie);
 278             table.addSimpleListener(serie.dataProperty(), serie);
 279 
 280             for (Iterator it = serie.getData().iterator(); it.hasNext();) {
 281                 final XYChart.Data data = (XYChart.Data) it.next();
 282 
 283                 final DoubleProperty intermediateX = new SimpleDoubleProperty(null, "XValue");
 284                 final DoubleProperty intermediateY = new SimpleDoubleProperty(null, "YValue");
 285 
 286                 data.XValueProperty().addListener(new ChangeListener() {
 287                     public void changed(ObservableValue ov, Object t, Object t1) {
 288                         if (!intermediateX.isBound()) {
 289                             intermediateX.setValue((Double) data.XValueProperty().getValue());
 290                         }
 291                     }
 292                 });
 293 
 294                 data.YValueProperty().addListener(new ChangeListener() {
 295                     public void changed(ObservableValue ov, Object t, Object t1) {
 296                         if (!intermediateY.isBound()) {
 297                             intermediateY.setValue((Double) data.YValueProperty().getValue());
 298                         }
 299                     }
 300                 });
 301 
 302                 intermediateX.addListener(new ChangeListener() {
 303                     public void changed(ObservableValue ov, Object t, Object t1) {
 304                         data.setXValue(t1);
 305                     }
 306                 });
 307 
 308                 intermediateY.addListener(new ChangeListener() {
 309                     public void changed(ObservableValue ov, Object t, Object t1) {
 310                         data.setYValue(t1);
 311                     }
 312                 });
 313 
 314                 table.addDoublePropertyLine(intermediateX, min, max, (Double) data.getXValue(), data);
 315                 table.addDoublePropertyLine(intermediateY, min, max, (Double) data.getYValue(), data);
 316             }
 317 
 318             return table;
 319         }
 320 
 321         public AreaChart getNewChart() {
 322             AreaChart chart = new AreaChart(axis1, axis2);
 323             chart.setTitle("AreaChart");
 324             chart.setStyle("-fx-border-color: darkgray;");
 325             return chart;
 326         }
 327     }
 328 }