1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package ensemble.samplepage; 33 34 35 import ensemble.samples.charts.pie.chart.PieChartApp; 36 import javafx.beans.value.ObservableValue; 37 import javafx.collections.ObservableList; 38 import javafx.event.ActionEvent; 39 import javafx.event.EventHandler; 40 import javafx.scene.Node; 41 import javafx.scene.chart.PieChart; 42 import javafx.scene.chart.PieChart.Data; 43 import javafx.scene.control.ContextMenu; 44 import javafx.scene.control.MenuItem; 45 import javafx.scene.control.TableCell; 46 import javafx.scene.control.TableView; 47 import javafx.scene.control.TableColumn; 48 import javafx.scene.control.TableColumn.CellDataFeatures; 49 import javafx.scene.control.TableRow; 50 import javafx.scene.control.cell.TextFieldTableCell; 51 import javafx.scene.input.ContextMenuEvent; 52 import javafx.util.StringConverter; 53 54 55 public class PieChartDataVisualizer extends TableView<Data> { 56 57 PieChart chart; 58 59 public PieChartDataVisualizer(final PieChart chart) { 60 this.chart = chart; 61 setItems(chart.getData()); 62 setEditable(true); 63 setMinHeight(100); 64 setMinWidth(100); 65 66 chart.dataProperty().addListener((ObservableValue<? extends ObservableList<Data>> ov, ObservableList<Data> t, ObservableList<Data> t1) -> { 67 setItems(t1); 68 }); 69 70 TableColumn<Data, String> nameColumn = new TableColumn<>("Name"); 71 nameColumn.setCellValueFactory((CellDataFeatures<Data, String> p) -> p.getValue().nameProperty()); 72 nameColumn.setCellFactory(TextFieldTableCell.<Data>forTableColumn()); 73 nameColumn.setEditable(true); 74 nameColumn.setSortable(false); 75 nameColumn.setMinWidth(80); 76 77 TableColumn<Data, Number> pieValueColumn = new TableColumn<>("PieValue"); 78 pieValueColumn.setCellValueFactory((CellDataFeatures<Data, Number> p) -> p.getValue().pieValueProperty()); 79 pieValueColumn.setCellFactory(TextFieldTableCell.<Data, Number>forTableColumn(new StringConverter<Number>() { 80 81 @Override 82 public String toString(Number t) { 83 return t == null ? null : t.toString(); 84 } 85 86 @Override 87 public Number fromString(String string) { 88 if (string == null) { 89 return null; 90 } 91 try { 92 return (Double) new Double(string); 93 } catch (Exception ignored) { 94 return 0; 95 } 96 } 97 })); 98 pieValueColumn.setEditable(true); 99 pieValueColumn.setSortable(false); 100 pieValueColumn.setMinWidth(80); 101 102 setOnContextMenuRequested((ContextMenuEvent t) -> { 103 Node node = t.getPickResult().getIntersectedNode(); 104 while (node != null && !(node instanceof TableRow) && !(node instanceof TableCell)) { 105 node = node.getParent(); 106 } 107 if (node instanceof TableCell) { 108 TableCell tc = (TableCell) node; 109 getSelectionModel().select(tc.getIndex()); 110 } else if (node instanceof TableRow) { 111 TableRow tr = (TableRow) node; 112 if (tr.getItem() == null) { 113 getSelectionModel().clearSelection(); 114 } else { 115 getSelectionModel().select(tr.getIndex()); 116 } 117 } 118 }); 119 120 MenuItem item1 = new MenuItem("Insert item"); 121 item1.setOnAction(new EventHandler<ActionEvent>() { 122 long itemIndex = 0; 123 @Override 124 public void handle(ActionEvent t) { 125 int index = getSelectionModel().getSelectedIndex(); 126 if (index < 0 || index >= chart.getData().size()) { 127 index = chart.getData().size(); 128 } 129 chart.getData().add(index, new Data("Item " + (++itemIndex), Math.random() * 100)); 130 getSelectionModel().select(index); 131 } 132 }); 133 134 MenuItem item2 = new MenuItem("Delete item"); 135 item2.setOnAction((ActionEvent t) -> { 136 int index = getSelectionModel().getSelectedIndex(); 137 if (index >= 0 && index < chart.getData().size()) { 138 chart.getData().remove(index); 139 } 140 }); 141 142 MenuItem item3 = new MenuItem("Clear data"); 143 item3.setOnAction((ActionEvent t) -> { 144 chart.getData().clear(); 145 }); 146 147 MenuItem item4 = new MenuItem("Set new data"); 148 item4.setOnAction((ActionEvent t) -> { 149 chart.setData(PieChartApp.generateData()); 150 }); 151 152 setContextMenu(new ContextMenu(item1, item2, item3, item4)); 153 getColumns().setAll(nameColumn, pieValueColumn); 154 } 155 }