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