Advertisement
Guest User

Javafx Map TableView

a guest
Jan 24th, 2014
1,122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.87 KB | None | 0 0
  1. package tablemap;
  2.  
  3. import javafx.application.Application;
  4. import javafx.beans.property.SimpleStringProperty;
  5. import javafx.event.ActionEvent;
  6. import javafx.scene.Scene;
  7. import javafx.scene.control.Button;
  8. import java.util.AbstractMap;
  9. import java.util.Map;
  10. import javafx.beans.property.DoubleProperty;
  11. import javafx.beans.property.IntegerProperty;
  12. import javafx.beans.property.SimpleDoubleProperty;
  13. import javafx.beans.property.SimpleIntegerProperty;
  14. import javafx.beans.property.StringProperty;
  15. import javafx.collections.FXCollections;
  16. import javafx.collections.ListChangeListener;
  17. import javafx.collections.MapChangeListener;
  18. import javafx.collections.ObservableList;
  19. import javafx.collections.ObservableMap;
  20. import javafx.scene.control.TableColumn;
  21. import javafx.scene.control.TableColumn.CellEditEvent;
  22. import javafx.scene.control.TableView;
  23. import javafx.scene.control.cell.TextFieldTableCell;
  24. import javafx.scene.layout.HBox;
  25. import javafx.scene.layout.Priority;
  26. import javafx.scene.layout.VBox;
  27. import javafx.stage.Stage;
  28.  
  29. public class TableMap extends Application {
  30.  
  31.     @Override
  32.     public void start(Stage primaryStage) {
  33.         VBox root = new VBox();
  34.  
  35.         final ObservableMap<String, LineItem> obsMap = FXCollections.observableHashMap();
  36.         for (int i = 0; i < 3; i++)
  37.             obsMap.put(String.valueOf(i), new LineItem(String.valueOf(i),"i"));
  38.         final MapTableView<String,LineItem> mtv = new MapTableView(obsMap);
  39.  
  40.         final TableColumn<Map.Entry<String,LineItem>,String> keyCol = new TableColumn("Key");
  41.         keyCol.setCellValueFactory(
  42.             (TableColumn.CellDataFeatures<Map.Entry<String,LineItem>, String> p) ->
  43.                 new SimpleStringProperty(p.getValue().getKey()));
  44.         keyCol.setCellFactory(TextFieldTableCell.forTableColumn());
  45.         keyCol.setOnEditCommit((CellEditEvent<Map.Entry<String,LineItem>, String> t) -> {
  46.             final String oldKey = t.getOldValue();
  47.             final LineItem oldLineItem = obsMap.get(oldKey);
  48.             obsMap.remove(oldKey);//should remove from list but maybe doesn't always
  49.             obsMap.put(t.getNewValue(),oldLineItem);
  50.         });
  51.  
  52.        
  53.         final TableColumn<Map.Entry<String,LineItem>,String> lineNoCol = new TableColumn("Line No");
  54.         lineNoCol.setCellValueFactory(
  55.             (TableColumn.CellDataFeatures<Map.Entry<String,LineItem>, String> p) ->
  56.                 new SimpleStringProperty(p.getValue().getValue().getLineNo()));
  57.  
  58.         final TableColumn<Map.Entry<String,LineItem>,String> descCol = new TableColumn("Desc");
  59.         descCol.setCellValueFactory(
  60.             (TableColumn.CellDataFeatures<Map.Entry<String,LineItem>, String> p) ->
  61.                 new SimpleStringProperty(p.getValue().getValue().getDesc()));
  62.         descCol.setCellFactory(TextFieldTableCell.forTableColumn());
  63.         descCol.setOnEditCommit((CellEditEvent<Map.Entry<String,LineItem>, String> t) -> {
  64.              t.getTableView().getItems().get(t.getTablePosition().getRow())
  65.                      .getValue().setDesc(t.getNewValue());
  66.         });
  67.  
  68.         mtv.getColumns().addAll(keyCol,lineNoCol, descCol);
  69.         mtv.setEditable(true);
  70.         mtv.getSelectionModel().setCellSelectionEnabled(true);
  71.         mtv.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
  72.        
  73.         final Button btnOut = new Button("out");
  74.         btnOut.setOnAction((ActionEvent t) -> {
  75.             System.out.println("MAP");
  76.             for (Map.Entry<String,LineItem> me : obsMap.entrySet()){
  77.                 System.out.print("key->"+me.getKey()+" entry->"+me.getValue().toCSVString());
  78.             }
  79.             System.out.println("LIST");
  80.             for (Map.Entry<String,LineItem> me : mtv.getItems()){
  81.                 System.out.print("key->"+me.getKey()+" entry->"+me.getValue().toCSVString());
  82.             }
  83.             System.out.println("");
  84.         });
  85.  
  86.         final Button btnMapAdd = new Button("Map add");
  87.         btnMapAdd.setOnAction((ActionEvent t) -> {
  88.             obsMap.put("from map code", new LineItem("5","hi from map btn"));
  89.         });
  90.  
  91.         final Button btnListAdd = new Button("List add");
  92.         btnListAdd.setOnAction((ActionEvent t) -> {
  93.             //I could just call add to map instead of list on list.add
  94.             mtv.addUnique("from list code", new LineItem("10","hi from list btn"));
  95.         });
  96.  
  97.         final Button btnMapDel = new Button("Map del");
  98.         btnMapDel.setOnAction((ActionEvent t) -> {
  99.             LineItem remove = obsMap.remove("from map code");
  100.         });
  101.  
  102.         final Button btnListDel = new Button("List del");
  103.         btnListDel.setOnAction((ActionEvent t) -> {
  104.             mtv.getItems().remove(0);
  105.         });
  106.  
  107.         final Button btnTblDel = new Button("Table row del");
  108.         btnTblDel.setOnAction((ActionEvent t) -> {
  109.             mtv.getItems().remove(mtv.getSelectionModel().getSelectedIndex());
  110.         });
  111.  
  112.         final Button btnMapOps = new Button("Map ops");
  113.         btnMapOps.setOnAction((ActionEvent t) -> {
  114.             long start = System.currentTimeMillis();
  115.             mtv.removeMapListener();
  116.             for (int i = 0; i < 100000; i++)
  117.                 obsMap.put(String.valueOf(i), new LineItem(String.valueOf(i),"hi from map ops"));
  118.             for (int i = 0; i < 99999; i++)
  119.                 obsMap.remove(String.valueOf(i));
  120.             mtv.resetMapListener();
  121.             System.out.println("time w/out listeners->"+(System.currentTimeMillis()-start));
  122.  
  123.             start = System.currentTimeMillis();
  124.             for (int i = 100000; i < 200000; i++)
  125.                 obsMap.put(String.valueOf(i), new LineItem(String.valueOf(i),"hi from map ops"));
  126.             for (int i = 100000; i < 199999; i++)
  127.                 obsMap.remove(String.valueOf(i));
  128.             System.out.println("time with listeners->"+(System.currentTimeMillis()-start));
  129.         });
  130.  
  131.         final HBox hbox = new HBox();
  132.         hbox.getChildren().addAll(btnOut,btnMapAdd,btnListAdd,btnMapDel,btnListDel,btnTblDel,btnMapOps);
  133.         root.getChildren().addAll(mtv,hbox);
  134.         VBox.setVgrow(mtv, Priority.ALWAYS);
  135.         final Scene scene = new Scene(root, 600, 500);
  136.  
  137.         primaryStage.setTitle("Map Table Test");
  138.         primaryStage.setScene(scene);
  139.         primaryStage.show();
  140.     }
  141. }
  142.  
  143.  
  144. class MapTableView<K,V> extends TableView<Map.Entry<K,V>>{
  145.     private final ObservableList<Map.Entry<K,V>> obsList;
  146.     private final ObservableMap<K,V> map;
  147.     private final MapChangeListener<K,V> mapChange;
  148.     private final ListChangeListener<Map.Entry<K,V>> listChange;
  149.    
  150.     public MapTableView(ObservableMap<K,V> map) {
  151.         this.map = map;
  152.         obsList = FXCollections.observableArrayList(map.entrySet());
  153.         setItems(obsList);
  154.        
  155.         mapChange = new MapChangeListener<K, V>() {
  156.             @Override
  157.             public void onChanged(MapChangeListener.Change<? extends K, ? extends V> change) {
  158.                 obsList.removeListener(listChange);
  159.                 if (change.wasAdded())
  160.                     obsList.add(new AbstractMap.SimpleEntry(change.getKey(),change.getValueAdded()));
  161.                 if (change.wasRemoved()){
  162.                     //obsList.remove(new AbstractMap.SimpleEntry(change.getKey(),change.getValueRemoved()));
  163.                     // ^ doesn't work always, use loop instead
  164.                     for (Map.Entry<K,V> me : obsList){
  165.                         if (me.getKey().equals(change.getKey())){
  166.                             obsList.remove(me);
  167.                             break;
  168.                         }
  169.                     }
  170.                 }
  171.                 obsList.addListener(listChange);
  172.             }
  173.         };
  174.        
  175.         listChange = (ListChangeListener.Change<? extends Map.Entry<K, V>> change) -> {
  176.             map.removeListener(mapChange);
  177.             while (change.next()){
  178.                 //maybe check for uniqueness here
  179.                 if (change.wasAdded()) for (Map.Entry<K, V> me: change.getAddedSubList())
  180.                     map.put(me.getKey(),me.getValue());
  181.                 if (change.wasRemoved()) for (Map.Entry<K, V> me: change.getRemoved())
  182.                     map.remove(me.getKey());
  183.             }
  184.             map.addListener(mapChange);
  185.         };
  186.        
  187.         map.addListener(mapChange);
  188.         obsList.addListener(listChange);
  189.     }
  190.    
  191.     //adding to list should be unique
  192.     public void addUnique(K key, V value){
  193.         boolean isFound = false;
  194.         //if a duplicate key just change the value
  195.         for (Map.Entry<K,V> me : getItems()){
  196.             if (me.getKey().equals(key)){
  197.                 isFound = true;
  198.                 me.setValue(value);
  199.                 break;//only first match
  200.             }
  201.         }
  202.         if (!isFound) // add new entry
  203.             getItems().add(new AbstractMap.SimpleEntry<>(key,value));
  204.     }
  205.    
  206.     //for doing lenghty map operations
  207.     public void removeMapListener(){
  208.         map.removeListener(mapChange);
  209.     }
  210.    
  211.     //for resyncing list to map after many changes
  212.     public void resetMapListener(){
  213.         obsList.removeListener(listChange);
  214.           obsList.clear();
  215.           obsList.addAll(map.entrySet());
  216.         obsList.addListener(listChange);
  217.         map.addListener(mapChange);
  218.     }
  219. }
  220. class LineItem {
  221.     private final StringProperty lineNo = new SimpleStringProperty();//sym
  222.     private final StringProperty desc = new SimpleStringProperty();//type->gives yld cpn
  223.     private final StringProperty formula = new SimpleStringProperty();//mer ??
  224.     private final DoubleProperty amount = new SimpleDoubleProperty();
  225.     private final IntegerProperty sort = new SimpleIntegerProperty();//mult
  226.     private final StringProperty note = new SimpleStringProperty();
  227.    
  228.     public LineItem() {
  229.     }
  230.    
  231.     public LineItem(String ln, String dsc, String frm, double amt, int srt) {
  232.         lineNo.set(ln);desc.set(dsc);formula.set(frm);amount.set(amt);sort.set(srt);
  233.     }
  234.     public LineItem(String ln, String dsc) {
  235.         lineNo.set(ln); desc.set(dsc);
  236.     }
  237.    
  238.    
  239.     public String getLineNo() {return (lineNo.getValue() != null) ?lineNo.get():"";}
  240.     public void setLineNo(String lineNo) {this.lineNo.set(lineNo);}
  241.     public StringProperty lineNoProperty() {return lineNo;}
  242.  
  243.     public String getDesc() {return (desc.getValue() != null) ?desc.get():"";}
  244.     public void setDesc(String desc) {this.desc.set(desc);}
  245.     public StringProperty descProperty() {return desc;}
  246.  
  247.     //mebbe return "0" as it will get parsed to 0
  248.     public String getFormula() {return (formula.getValue() != null) ? formula.get():"0";}
  249.     public void setFormula(String formula) {this.formula.set(formula);}
  250.     public StringProperty formulaProperty() {return formula;}
  251.    
  252.     //return 0 to prevent nfe
  253.     public double getAmount() {return (amount.getValue() != null) ? amount.doubleValue():0d;}    
  254.     public void setAmount(double amount) {this.amount.set(amount);}
  255.     public DoubleProperty amountProperty() {return amount;}
  256.    
  257.     //return 0 to prevent nfe
  258.     public void setSort(Integer sort) {this.sort.set(sort);}
  259.     public Integer getSort() {return (sort.getValue() != null) ? sort.getValue():0;}
  260.     public IntegerProperty sortProperty() {return sort;}
  261.    
  262.     //return "" if null
  263.     public String getNote() {return (note.getValue() != null) ? note.get():"";}    
  264.     public void setNote(String note) {this.note.set(note);}
  265.     public StringProperty noteProperty() {return note;}
  266.  
  267.     public String toCSVString(){
  268.         //todo test for , and wrap in quotes
  269.         return lineNo.getValueSafe()+","+
  270.                 desc.getValueSafe()+","+
  271.                 "\""+formula.getValueSafe()+"\","+ //wrap in quotes
  272.                 amount.doubleValue()+","+  //no commas anywhere else
  273.                 sort.intValue()+","+
  274.                 "\""+note.getValueSafe()+"\""+//wrap in quotes
  275.                 "\n";
  276.     }
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement