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 }