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.Iterator;
  28 import java.util.Random;
  29 import javafx.beans.property.DoubleProperty;
  30 import javafx.beans.property.SimpleDoubleProperty;
  31 import javafx.beans.value.ChangeListener;
  32 import javafx.beans.value.ObservableValue;
  33 import javafx.collections.FXCollections;
  34 import javafx.collections.ObservableList;
  35 import javafx.event.ActionEvent;
  36 import javafx.event.Event;
  37 import javafx.event.EventHandler;
  38 import javafx.scene.Scene;
  39 import javafx.scene.chart.BubbleChart;
  40 import javafx.scene.chart.NumberAxis;
  41 import javafx.scene.chart.XYChart;
  42 import javafx.scene.chart.XYChart.Series;
  43 import javafx.scene.control.*;
  44 import static javafx.scene.control.test.chart.apps.CommonFunctions.*;
  45 import javafx.scene.control.test.utils.CommonPropertiesScene;
  46 import javafx.scene.control.test.utils.ptables.PropertiesTable;
  47 import javafx.scene.control.test.utils.ptables.TabPaneWithControl;
  48 import javafx.scene.layout.HBox;
  49 import javafx.scene.layout.VBox;
  50 import test.javaclient.shared.InteroperabilityApp;
  51 import test.javaclient.shared.Utils;
  52 
  53 /**
  54  * @author Alexander Kirov
  55  */
  56 public class NewBubbleChartApp extends InteroperabilityApp implements ChartIDsInterface {
  57 
  58     public final static String REMOVE_ITEM_POS_TEXT_FIELD_ID = "REMOVE_ITEM_POS_TEXT_FIELD_ID";
  59     public final static String REMOVE_BUTTON_ID = "REMOVE_BUTTON_ID";
  60     public final static String ADD_ITEM_TEXT_FIELD_ID = "ADD_ITEM_TEXT_FIELD_ID";
  61     public final static String ADD_ITEM_POSITION_TEXT_FIELD_ID = "ADD_ITEM_POSITION_TEXT_FIELD_ID";
  62     public final static String ADD_ITEM_BUTTON_ID = "ADD_ITEM_BUTTON_ID";
  63 
  64     public static void main(String[] args) {
  65         Utils.launch(NewBubbleChartApp.class, args);
  66     }
  67 
  68     @Override
  69     protected Scene getScene() {
  70         Utils.setTitleToStage(stage, "BubbleChartTestApp");
  71         return new NewBubbleChartApp.BubbleChartScene();
  72     }
  73 
  74     class BubbleChartScene extends CommonPropertiesScene {
  75 
  76         //BubbleChart to be tested.
  77         BubbleChart testedBubbleChart;
  78         NumberAxis axis1;
  79         NumberAxis axis2;
  80         TabPaneWithControl pane;
  81 
  82         public BubbleChartScene() {
  83             super("BubbleChart", 1300, 800);            
  84         }
  85 
  86         @Override
  87         final protected void prepareScene() {
  88             Utils.addBrowser(this);
  89             
  90             axis1 = new NumberAxis(0, 100, 10);
  91             axis2 = new NumberAxis(0, 100, 10);
  92             testedBubbleChart = getNewChart();
  93             testedBubbleChart.setId(TESTED_CHART_ID);
  94 
  95             Button hardResetButton = new Button("Hard reset");
  96             hardResetButton.setId(HARD_RESET_BUTTON_ID);
  97             hardResetButton.setOnAction(new EventHandler<ActionEvent>() {
  98                 public void handle(ActionEvent t) {
  99                     HBox hb = (HBox) getRoot();
 100                     hb.getChildren().clear();
 101                     prepareMainSceneStructure();
 102                     prepareScene();
 103                 }
 104             });
 105 
 106             Button softResetButton = new Button("Soft reset");
 107             softResetButton.setId(SOFT_RESET_BUTTON_ID);
 108             softResetButton.setOnAction(new EventHandler<ActionEvent>() {
 109                 public void handle(ActionEvent t) {
 110                     //throw new UnsupportedOperationException("Not supported yet.");
 111                 }
 112             });
 113 
 114             HBox resetButtonsHBox = new HBox();
 115             resetButtonsHBox.getChildren().addAll(hardResetButton, softResetButton);
 116 
 117             VBox vb = new VBox(5);
 118             vb.getChildren().addAll(resetButtonsHBox, getAddItemHBox(), getAddBubbleToSerieDialog(), getRemoveDataDialog(), getRemoveDataFromSerieDialog());
 119 
 120             pane = getPaneFor(testedBubbleChart, CHART_TAB_NAME, axis1, AXIS_1_TAB_NAME, axis2, AXIS_2_TAB_NAME);
 121 
 122             setTestedControlContainerSize(500, 500);
 123             setTestedControl(testedBubbleChart);
 124             setPropertiesContent(pane);
 125             setControllersContent(vb);
 126         }
 127 
 128         public HBox getRemoveDataDialog() {
 129             HBox hb = new HBox();
 130             Label lb = new Label("From position");
 131             final TextField tf = new TextField("0");
 132             tf.setPrefWidth(50);
 133             tf.setId(REMOVE_ITEM_POS_TEXT_FIELD_ID);
 134             Button bt = new Button("Remove serie!");
 135             bt.setId(REMOVE_BUTTON_ID);
 136             bt.setOnAction(new EventHandler() {
 137                 public void handle(Event t) {
 138                     int index = Integer.parseInt(tf.getText());
 139                     testedBubbleChart.getData().remove(index);
 140                 }
 141             });
 142             hb.getChildren().addAll(lb, tf, bt);
 143             return hb;
 144         }
 145 
 146         public HBox getRemoveDataFromSerieDialog() {
 147             HBox hb = new HBox();
 148             Label lb1 = new Label("From serie");
 149             final TextField tf1 = new TextField("0");
 150             tf1.setPrefWidth(50);
 151 
 152             Label lb2 = new Label("from index");
 153             final TextField tf2 = new TextField("0");
 154             tf2.setPrefWidth(50);
 155 
 156             Button bt = new Button("remove bubble!");
 157             bt.setId(REMOVE_BUTTON_ID);
 158             bt.setOnAction(new EventHandler() {
 159                 public void handle(Event t) {
 160                     int serie = Integer.parseInt(tf1.getText());
 161                     int index = Integer.parseInt(tf2.getText());
 162                     ((Series) testedBubbleChart.getData().get(serie)).getData().remove(index);
 163                 }
 164             });
 165             hb.getChildren().addAll(lb1, tf1, lb2, tf2, bt);
 166             return hb;
 167         }
 168 
 169         public HBox getAddBubbleToSerieDialog() {
 170             HBox hb = new HBox();
 171             Label lb1 = new Label("To serie");
 172             final TextField tf1 = new TextField("0");
 173             tf1.setPrefWidth(50);
 174 
 175             Label lb2 = new Label("to index");
 176             final TextField tf2 = new TextField("0");
 177             tf2.setPrefWidth(50);
 178 
 179             Label lb3 = new Label("X");
 180             final TextField tf3 = new TextField("0");
 181             tf3.setPrefWidth(50);
 182 
 183             Label lb4 = new Label("Y");
 184             final TextField tf4 = new TextField("0");
 185             tf4.setPrefWidth(50);
 186 
 187             Label lb5 = new Label("R");
 188             final TextField tf5 = new TextField("0");
 189             tf5.setPrefWidth(50);
 190 
 191             Button bt = new Button("add bubble!");
 192             bt.setId(REMOVE_BUTTON_ID);
 193             bt.setOnAction(new EventHandler() {
 194                 public void handle(Event t) {
 195                     int serie = Integer.parseInt(tf1.getText());
 196                     int index = Integer.parseInt(tf2.getText());
 197                     double X = Double.parseDouble(tf3.getText());
 198                     double Y = Double.parseDouble(tf4.getText());
 199                     double R = Double.parseDouble(tf5.getText());
 200 
 201                     XYChart.Data newData = new XYChart.Data();
 202                     newData.setXValue(X);
 203                     newData.setYValue(Y);
 204                     newData.setExtraValue(R);
 205 
 206                     ((Series) testedBubbleChart.getData().get(serie)).getData().add(index, newData);
 207                 }
 208             });
 209             hb.getChildren().addAll(lb1, tf1, lb2, tf2, lb3, tf3, lb4, tf4, lb5, tf5, bt);
 210             return hb;
 211         }
 212 
 213         public HBox getAddItemHBox() {
 214             HBox hb = new HBox();
 215             Label lb = new Label("Add series named ");
 216             final TextField tf = new TextField();
 217             tf.setPrefWidth(50);
 218             tf.setId(ADDED_SERIES_NAME_TEXTFIELD_ID);
 219 
 220             Label minLabel = new Label(" min X,Y ");
 221             final TextField minText = new TextField();
 222             minText.setPrefWidth(50);
 223             minText.setId(ADDED_SERIES_MIN_VALUE_TEXTFIELD_ID);
 224 
 225             Label maxLabel = new Label(" max X,Y ");
 226             final TextField maxText = new TextField();
 227             maxText.setPrefWidth(50);
 228             maxText.setId(ADDED_SERIES_MAX_VALUE_TEXTFIELD_ID);
 229 
 230             Label amountLabel = new Label(" add ");
 231             final TextField amountText = new TextField();
 232             amountText.setPrefWidth(50);
 233             amountText.setId(ADDED_SERIES_DOTS_COUNT_TEXTFIELD_ID);
 234 
 235             Button bt = new Button(" bubbles!");
 236             bt.setId(ADD_SERIES_COMMAND_BUTTON_ID);
 237             bt.setOnAction(new EventHandler() {
 238                 public void handle(Event t) {
 239                     String serieName = tf.getText();
 240                     double min = Double.parseDouble(minText.getText());
 241                     double max = Double.parseDouble(maxText.getText());
 242                     int amount = Integer.parseInt(amountText.getText());
 243 
 244                     ObservableList list = FXCollections.observableArrayList();
 245 
 246                     XYChart.Series serie = new XYChart.Series(serieName, list);
 247 
 248                     for (int i = 0; i < amount; i++) {
 249                         XYChart.Data newData = new XYChart.Data();
 250                         newData.setXValue(new Random().nextDouble() * (max - min) + min);
 251                         newData.setYValue(new Random().nextDouble() * (max - min) + min);
 252                         newData.setExtraValue(new Random().nextDouble() * (max - min) / 8 + min);
 253                         list.add(newData);
 254                     }
 255 
 256                     testedBubbleChart.getData().add(serie);
 257                     pane.addPropertiesTable(serieName, getTableForProperty(serie, min, max).getVisualRepresentation());
 258                 }
 259             });
 260             hb.getChildren().addAll(lb, tf, minLabel, minText, maxLabel, maxText, amountLabel, amountText, bt);
 261             return hb;
 262         }
 263 
 264         protected PropertiesTable getTableForProperty(XYChart.Series serie, double min, double max) {
 265             PropertiesTable table = new PropertiesTable(serie);
 266 
 267             table.addSimpleListener(serie.chartProperty(), serie);
 268             table.addSimpleListener(serie.nameProperty(), serie);
 269             table.addSimpleListener(serie.dataProperty(), serie);
 270 
 271             for (Iterator it = serie.getData().iterator(); it.hasNext();) {
 272                 final XYChart.Data data = (XYChart.Data) it.next();
 273 
 274                 final DoubleProperty intermediateX = new SimpleDoubleProperty(null, "XValue");
 275                 final DoubleProperty intermediateY = new SimpleDoubleProperty(null, "YValue");
 276                 final DoubleProperty intermediateExtra = new SimpleDoubleProperty(null, "ExtraValue");
 277 
 278                 data.XValueProperty().addListener(new ChangeListener() {
 279                     public void changed(ObservableValue ov, Object t, Object t1) {
 280                         if (!intermediateX.isBound()) {
 281                             intermediateX.setValue((Double) data.XValueProperty().getValue());
 282                         }
 283                     }
 284                 });
 285 
 286                 data.YValueProperty().addListener(new ChangeListener() {
 287                     public void changed(ObservableValue ov, Object t, Object t1) {
 288                         if (!intermediateY.isBound()) {
 289                             intermediateY.setValue((Double) data.YValueProperty().getValue());
 290                         }
 291                     }
 292                 });
 293 
 294                 data.extraValueProperty().addListener(new ChangeListener() {
 295                     public void changed(ObservableValue ov, Object t, Object t1) {
 296                         if (!intermediateExtra.isBound()) {
 297                             intermediateExtra.setValue((Double) data.extraValueProperty().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                 intermediateExtra.addListener(new ChangeListener() {
 315                     public void changed(ObservableValue ov, Object t, Object t1) {
 316                         data.setExtraValue(t1);
 317                     }
 318                 });
 319 
 320                 table.addDoublePropertyLine(intermediateX, min, max, (Double) data.getXValue(), data);
 321                 table.addDoublePropertyLine(intermediateY, min, max, (Double) data.getYValue(), data);
 322                 table.addDoublePropertyLine(intermediateExtra, min, max, (Double) data.getYValue(), data);
 323             }
 324 
 325             return table;
 326         }
 327 
 328         public BubbleChart getNewChart() {
 329             BubbleChart chart = new BubbleChart(axis1, axis2);
 330             chart.setTitle("BubbleChart");
 331             chart.setStyle("-fx-border-color: darkgray;");
 332             return chart;
 333         }
 334     }
 335 }