apps/experiments/ConferenceScheduleApp/src/main/java/com/javafx/experiments/scheduleapp/pages/SpeakersPage.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization


  44 import javafx.animation.Timeline;
  45 import javafx.beans.InvalidationListener;
  46 import javafx.beans.Observable;
  47 import javafx.beans.binding.DoubleBinding;
  48 import javafx.beans.property.SimpleDoubleProperty;
  49 import javafx.beans.value.ChangeListener;
  50 import javafx.beans.value.ObservableValue;
  51 import javafx.collections.ObservableList;
  52 import javafx.event.ActionEvent;
  53 import javafx.event.Event;
  54 import javafx.event.EventHandler;
  55 import javafx.geometry.HPos;
  56 import javafx.geometry.Orientation;
  57 import javafx.geometry.VPos;
  58 import javafx.scene.Node;
  59 import javafx.scene.control.ContentDisplay;
  60 import javafx.scene.control.Label;
  61 import javafx.scene.control.ListCell;
  62 import javafx.scene.control.ListView;
  63 import javafx.scene.control.Skin;

  64 import javafx.scene.image.Image;
  65 import javafx.scene.image.ImageView;
  66 import javafx.scene.input.MouseEvent;
  67 import javafx.scene.layout.ColumnConstraints;
  68 import javafx.scene.layout.GridPane;
  69 import javafx.scene.layout.Priority;
  70 import javafx.scene.layout.Region;
  71 import javafx.scene.layout.VBox;
  72 import javafx.scene.paint.Color;
  73 import javafx.scene.shape.Rectangle;
  74 import javafx.scene.text.Text;
  75 import javafx.stage.Window;
  76 import javafx.util.Callback;
  77 import javafx.util.Duration;
  78 import com.javafx.experiments.scheduleapp.TouchClickedEventAvoider;
  79 import com.javafx.experiments.scheduleapp.Page;
  80 import com.javafx.experiments.scheduleapp.control.EventPopoverPage;
  81 import com.javafx.experiments.scheduleapp.control.Popover;
  82 import com.javafx.experiments.scheduleapp.control.ResizableWrappingText;
  83 import com.javafx.experiments.scheduleapp.control.SearchBox;
  84 import com.javafx.experiments.scheduleapp.data.DataService;
  85 import com.javafx.experiments.scheduleapp.model.Session;
  86 import com.javafx.experiments.scheduleapp.model.SessionTime;
  87 import com.javafx.experiments.scheduleapp.model.Speaker;
  88 import com.sun.javafx.scene.control.skin.FXVK;
  89 
  90 import static com.javafx.experiments.scheduleapp.ConferenceScheduleApp.*;
  91 import static com.javafx.experiments.scheduleapp.Theme.*;
  92 import java.awt.image.BufferedImage;
  93 import java.io.IOException;
  94 import java.net.URL;
  95 import java.util.HashMap;
  96 import java.util.Map;
  97 import java.util.logging.Level;
  98 import java.util.logging.Logger;
  99 import javafx.embed.swing.SwingFXUtils;
 100 import javafx.scene.image.WritableImage;
 101 import javax.imageio.ImageIO;
 102 
 103 /**
 104  * Page showing searchable list of all speakers at the conference
 105  */
 106 public class SpeakersPage extends Page implements ChangeListener<String> {
 107     private static DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("hh:mma EEE");
 108     private static final Pattern HYPERLINK_PATTERN = Pattern.compile("http(s)?://\\S+");
 109     private static final int PIC_SIZE = 48;
 110     private static final int GAP = 6;
 111     private static final int IMG_GAP = 12;
 112     private static final int MIN_HEIGHT = GAP + PIC_SIZE + 10 + GAP;
 113     private static final int TEXT_LEFT = GAP+PIC_SIZE+IMG_GAP;
 114     
 115     private final SpeakerList speakersList = new SpeakerList();
 116     private final SearchBox searchBox = new SearchBox();
 117     private final Map<Speaker,Image> speakerImageCache = new HashMap<>();
 118     
 119     /** 
 120      * index of currently expanded cell. We need to keep tack of the cell that 
 121      * is expanded so that when you scroll away from it and its cell is reused 


 245      * @param show true if the star should be added to the label, false if it 
 246      *             should be removed.
 247      */
 248     private static void updateStar(Label sessionTitle, boolean show) {
 249         if(show) {
 250             ImageView star = new ImageView(STAR);
 251             sessionTitle.setGraphic(star);
 252             sessionTitle.setContentDisplay(ContentDisplay.RIGHT);
 253         } else {
 254             sessionTitle.setGraphic(null);
 255         }
 256     }
 257     
 258     /**
 259      * Custom list for speakers, will all standard CSS removed an using our 
 260      * custom SpeakerListCell.
 261      */
 262     private class SpeakerList extends ListView<Speaker> implements Callback<ListView<Speaker>, ListCell<Speaker>>{
 263         public SpeakerList(){
 264             getStyleClass().setAll("twitter-list-view");
 265 //            skinClassNameProperty().set("com.sun.javafx.scene.control.skin.ListViewSkin");
 266             setSkin(new com.sun.javafx.scene.control.skin.ListViewSkin(this));
 267             setCellFactory(this);
 268             // hack workaround for cell sizing
 269             Node node = lookup(".clipped-container");
 270             if (node != null) node.setManaged(true);
 271         }
 272 
 273         @Override public ListCell<Speaker> call(ListView<Speaker> p) {
 274             return new SpeakerListCell();
 275         }
 276     }
 277 
 278     /**
 279      * The main body of the speaker list cell. This is separate from the cell 
 280      * so that it can be cached and not need to be updated while the cells clip 
 281      * is changing during expansion.
 282      */
 283     private final static class SpeakerListCellBody extends Region {
 284         private final Text name = new Text();
 285         private final Text company = new Text();
 286         private final ImageView image = new ImageView();




  44 import javafx.animation.Timeline;
  45 import javafx.beans.InvalidationListener;
  46 import javafx.beans.Observable;
  47 import javafx.beans.binding.DoubleBinding;
  48 import javafx.beans.property.SimpleDoubleProperty;
  49 import javafx.beans.value.ChangeListener;
  50 import javafx.beans.value.ObservableValue;
  51 import javafx.collections.ObservableList;
  52 import javafx.event.ActionEvent;
  53 import javafx.event.Event;
  54 import javafx.event.EventHandler;
  55 import javafx.geometry.HPos;
  56 import javafx.geometry.Orientation;
  57 import javafx.geometry.VPos;
  58 import javafx.scene.Node;
  59 import javafx.scene.control.ContentDisplay;
  60 import javafx.scene.control.Label;
  61 import javafx.scene.control.ListCell;
  62 import javafx.scene.control.ListView;
  63 import javafx.scene.control.Skin;
  64 import javafx.scene.control.skin.ListViewSkin;
  65 import javafx.scene.image.Image;
  66 import javafx.scene.image.ImageView;
  67 import javafx.scene.input.MouseEvent;
  68 import javafx.scene.layout.ColumnConstraints;
  69 import javafx.scene.layout.GridPane;
  70 import javafx.scene.layout.Priority;
  71 import javafx.scene.layout.Region;
  72 import javafx.scene.layout.VBox;
  73 import javafx.scene.paint.Color;
  74 import javafx.scene.shape.Rectangle;
  75 import javafx.scene.text.Text;
  76 import javafx.stage.Window;
  77 import javafx.util.Callback;
  78 import javafx.util.Duration;
  79 import com.javafx.experiments.scheduleapp.TouchClickedEventAvoider;
  80 import com.javafx.experiments.scheduleapp.Page;
  81 import com.javafx.experiments.scheduleapp.control.EventPopoverPage;
  82 import com.javafx.experiments.scheduleapp.control.Popover;
  83 import com.javafx.experiments.scheduleapp.control.ResizableWrappingText;
  84 import com.javafx.experiments.scheduleapp.control.SearchBox;
  85 import com.javafx.experiments.scheduleapp.data.DataService;
  86 import com.javafx.experiments.scheduleapp.model.Session;
  87 import com.javafx.experiments.scheduleapp.model.SessionTime;
  88 import com.javafx.experiments.scheduleapp.model.Speaker;
  89 import com.sun.javafx.scene.control.skin.FXVK;
  90 
  91 import static com.javafx.experiments.scheduleapp.ConferenceScheduleApp.*;
  92 import static com.javafx.experiments.scheduleapp.Theme.*;
  93 


  94 import java.util.HashMap;
  95 import java.util.Map;





  96 
  97 /**
  98  * Page showing searchable list of all speakers at the conference
  99  */
 100 public class SpeakersPage extends Page implements ChangeListener<String> {
 101     private static DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("hh:mma EEE");
 102     private static final Pattern HYPERLINK_PATTERN = Pattern.compile("http(s)?://\\S+");
 103     private static final int PIC_SIZE = 48;
 104     private static final int GAP = 6;
 105     private static final int IMG_GAP = 12;
 106     private static final int MIN_HEIGHT = GAP + PIC_SIZE + 10 + GAP;
 107     private static final int TEXT_LEFT = GAP+PIC_SIZE+IMG_GAP;
 108     
 109     private final SpeakerList speakersList = new SpeakerList();
 110     private final SearchBox searchBox = new SearchBox();
 111     private final Map<Speaker,Image> speakerImageCache = new HashMap<>();
 112     
 113     /** 
 114      * index of currently expanded cell. We need to keep tack of the cell that 
 115      * is expanded so that when you scroll away from it and its cell is reused 


 239      * @param show true if the star should be added to the label, false if it 
 240      *             should be removed.
 241      */
 242     private static void updateStar(Label sessionTitle, boolean show) {
 243         if(show) {
 244             ImageView star = new ImageView(STAR);
 245             sessionTitle.setGraphic(star);
 246             sessionTitle.setContentDisplay(ContentDisplay.RIGHT);
 247         } else {
 248             sessionTitle.setGraphic(null);
 249         }
 250     }
 251     
 252     /**
 253      * Custom list for speakers, will all standard CSS removed an using our 
 254      * custom SpeakerListCell.
 255      */
 256     private class SpeakerList extends ListView<Speaker> implements Callback<ListView<Speaker>, ListCell<Speaker>>{
 257         public SpeakerList(){
 258             getStyleClass().setAll("twitter-list-view");
 259 //            skinClassNameProperty().set("javafx.scene.control.skin.ListViewSkin");
 260             setSkin(new ListViewSkin(this));
 261             setCellFactory(this);
 262             // hack workaround for cell sizing
 263             Node node = lookup(".clipped-container");
 264             if (node != null) node.setManaged(true);
 265         }
 266 
 267         @Override public ListCell<Speaker> call(ListView<Speaker> p) {
 268             return new SpeakerListCell();
 269         }
 270     }
 271 
 272     /**
 273      * The main body of the speaker list cell. This is separate from the cell 
 274      * so that it can be cached and not need to be updated while the cells clip 
 275      * is changing during expansion.
 276      */
 277     private final static class SpeakerListCellBody extends Region {
 278         private final Text name = new Text();
 279         private final Text company = new Text();
 280         private final ImageView image = new ImageView();