Pannable ListView in JavaFX 1.3

So I installed JavaFX 1.3, and my code is compiling just fine, but my items in my listview don't appear to be "pannable"... Can anyone decipher what's going on?
Here is my code:
ListView {
    layoutInfo: LayoutInfo {width: 150 height: 350 }
    items: ["Andy", "Davis", "Is", "Awesome"]
    pannable: true
}I am using NetBeans 6.8.
Edited by: Xystus on Apr 23, 2010 1:48 PM
Edited by: Xystus on Apr 23, 2010 1:49 PM

The List is pannable -- if you add enough items. With a ListView that tall and only 4 items, there is nothing to pan. Try adding a few more:
ListView {
    layoutInfo: LayoutInfo {width: 150 height: 350 }
    items: for (i in [1..10]) ["Andy", "Davis", "Is", "Awesome"]
    pannable: true
}

Similar Messages

  • How to display the contents of an array list to a listview?

    Hi. How do I display the contents of an arraylist to a listview?
    Here is my current code:
    var c: Control= new Control();
    var simpleList: ArrayList = c.ListResult; //ListResult is an ArrayList containing strings
    var simpleListView : ListView = ListView {
            translateX: 0
            translateY: 0
            layoutX: 20
            layoutY: 80
            height: 130
            width: 200
            items: bind simpleList;
    Stage {
        title: "Trial app"
        width: 240
        height: 320
        style: StageStyle.TRANSPARENT
        scene: Scene {
            content: [ simpleListView
    } [http://img341.imageshack.us/img341/133/listview.jpg]
    My code generates the result in this screenshot above. It shows that all the contents on the arraylist is displayed in one row/item.
    It should be displayed as (see bottom image) ...
    [http://img707.imageshack.us/img707/3745/listview1.jpg]
    Do you guys have any idea on this? Thank you very much for your replies

    For your listbox data to bind the listbox requires a Sequence. This is something that you can sort out at the entrypoint of your code.
    In the example below I have used an ArrayList to simmulate the data you have entering your FX code, but then I put that list into a Sequence, in your case instead of having an ArrayList in your FX code, you simple supply the list on entry, as I have marked in the following code.
    * Main.fx
    * Created on 12-Feb-2010, 10:24:46
    package uselists;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.text.Text;
    import javafx.scene.text.Font;
    import java.util.ArrayList;
    import javafx.scene.control.ListView;
    import javafx.animation.Timeline;
    import javafx.animation.KeyFrame;
    * @author robert
    //Simmulate your data with an ArrayList
    var simpleList: ArrayList = new ArrayList;
    simpleList.add("Hello");
    simpleList.add("World");
    // *** This is what your entry point would become, just load the simpleList.toArray() into your sequence ***
    var simpleSequence = [];
    simpleSequence = simpleList.toArray();
    //after some time add some items, to show that our binding is working
    Timeline {
        repeatCount: 1
        keyFrames: [
            KeyFrame {
                time: 5s
                canSkip: true
                action: function () {
                    //you can work on the Sequence to add or remove
                    insert "Another item" into simpleSequence;
                    //if you at some point want to have your array reflect the changes
                    //then perform your changes on that too
                    simpleList.add("Another item");
                    //remember depending on your app
                    //you may keep the update of simpleList
                    //until you are finished with this view and do it in a single update
            KeyFrame {
                time: 10s
                action: function () {
                    //Alternatly, to keep your ArrayList correct at all times
                    //add items to it and then update your Sequence
                    simpleList.add("Added to array");
                    simpleSequence = simpleList.toArray();
    }.play();
    Stage {
        title: "Application title"
        scene: Scene {
            width: 250
            height: 80
            content: [
                ListView {
                    items: bind simpleSequence
    }You can bind to a function rather than the data, which I am sure would be needed some cases, for example if the listBox data was a named part of a hash value for example, all that is required is that your function returns a sequence.

  • Drag and Drop objects with JavaFX properties

    Has anyone tried to implement drag and drop functionality with objects containing JavaFX properties? The issue I'm running into is that the objects appear to need to be serializable, and the JavaFX properties are not serializable. I can implement Externalizable instead of Serializable, and basically serialize the values contained by the FX properties, but of course I lose any bindings by doing this (as the listeners underlying the bindings are not serialized).
    The [url http://docs.oracle.com/javafx/2/api/javafx/scene/input/Clipboard.html]javadocs for Clipboard state "In addition to the common or built in types, you may put any arbitrary data onto the clipboard (assuming it is either a reference, or serializable. See more about references later)" but I don't see any further information about references (and at any rate, this doesn't really make sense since anything that's serializable would be a reference anyway). Is there a special DataFormat I can use to specify a reference in the local JVM so the reference gets passed without serialization?
    I know this might not make sense without a code example; I just thought someone might have come across this closely enough to recognize the problem. I'll try to post a code example tonight...

    Here's pretty much the simplest example I can come up with. I have a real-world example of needing to do this, but the object model for the real example is quite a bit more complex.
    For the toy example, imagine we have a list of projects, some employees, and we want to assign each project to one or more employees. I have a Project class with a title and assignee. (In real life you can imagine other properties; due date, status, etc.) I'll keep a ListView with a bunch of unassigned projects (titles but assignees equal to null) and then a ListView for each of the employees.
    To assign a project to an employee, the user should be able to drag from the "master" list view to one of the employee list views. When the project is dropped, we'll create a new project, set the assignee, and bind the title of the new project to the title of the project which was dragged. (Remember we want to be able to assign a single project to multiple employees.)
    So here's the first shot:
    A couple of simple model classes
    Project.java
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    public class Project {
         private final StringProperty title ;
         private final ObjectProperty<Employee> assignee ;
         public Project(String title) {
              this.title = new SimpleStringProperty(this, "title", title);
              this.assignee = new SimpleObjectProperty<Employee>(this, "assignee");
         public Project() {
              this("");
         public StringProperty titleProperty() {
              return title ;
         public String getTitle() {
              return title.get() ;
         public void setTitle(String title) {
              this.title.set(title);
         public ObjectProperty<Employee> assigneeProperty() {
              return assignee ;
         public Employee getAssignee() {
              return assignee.get();
         public void setAssignee(Employee assignee) {
              this.assignee.set(assignee);
         @Override
         public String toString() {
              String t = title.get();
              Employee emp = assignee.get();
              if (emp==null) {
                   return t;
              } else {
                   return String.format("%s (%s)", t, emp.getName()) ;
    }Employee.java
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    public class Employee {
         private StringProperty name ;
         public Employee(String name) {
              this.name = new SimpleStringProperty(this,"name", name);
         public StringProperty nameProperty() {
              return name ;
         public String getName() {
              return name.get();
         public void setName(String name) {
              this.name.set(name);
    }and the application
    DnDExample.java
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.control.TextField;
    import javafx.scene.input.ClipboardContent;
    import javafx.scene.input.DataFormat;
    import javafx.scene.input.DragEvent;
    import javafx.scene.input.Dragboard;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.input.TransferMode;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class DnDExample extends Application {
         private static final DataFormat PROJECT_DATA_FORMAT = new DataFormat("com.example.project"); // is there something special I can use here?
         @Override
         public void start(Stage primaryStage) {
              final HBox root = new HBox(5);
              final ListView<Project> allProjects = new ListView<Project>();
              final Employee fred = new Employee("Fred");
              final Employee ginger = new Employee("Ginger");
              final ListView<Project> fredsProjects = new ListView<Project>();
              final ListView<Project> gingersProjects = new ListView<Project>();
              final VBox employeeLists = new VBox(5);
              employeeLists.getChildren().addAll(new Label("Fred's Projects"), fredsProjects, new Label("Ginger's Projects"), gingersProjects);
              root.getChildren().addAll(allProjects, employeeLists);
              allProjects.setCellFactory(new Callback<ListView<Project>, ListCell<Project>>() {
                   @Override
                   public ListCell<Project> call(ListView<Project> listView) {
                        return new AllProjectListCell();
              allProjects.setEditable(true);
              final EventHandler<DragEvent> dragOverHandler = new EventHandler<DragEvent>() {
                   @Override
                   public void handle(DragEvent dragEvent) {
                        if (dragEvent.getDragboard().hasContent(PROJECT_DATA_FORMAT)) {
                             dragEvent.acceptTransferModes(TransferMode.COPY);
              fredsProjects.setOnDragOver(dragOverHandler);
              gingersProjects.setOnDragOver(dragOverHandler);
              fredsProjects.setOnDragDropped(new DragDropHandler(fred, fredsProjects.getItems()));
              gingersProjects.setOnDragDropped(new DragDropHandler(ginger, gingersProjects.getItems()));
              allProjects.getItems().addAll(new Project("Implement Drag and Drop"), new Project("Fix serialization problem"));
              Scene scene = new Scene(root, 600, 400);
              primaryStage.setScene(scene);
              primaryStage.show();
         public static void main(String[] args) {
              launch(args);
         private class DragDropHandler implements EventHandler<DragEvent> {
              private final Employee employee ;
              private final ObservableList<Project> itemList;
              DragDropHandler(Employee employee, ObservableList<Project> itemList) {
                   this.employee = employee ;
                   this.itemList = itemList ;
              @Override
              public void handle(DragEvent event) {
                   Dragboard db = event.getDragboard();
                   if (db.hasContent(PROJECT_DATA_FORMAT)) {
                        Project project = (Project) db.getContent(PROJECT_DATA_FORMAT);
                        Project assignedProject = new Project();
                        assignedProject.titleProperty().bind(project.titleProperty());
                        assignedProject.setAssignee(employee);
                        itemList.add(assignedProject);
         private class AllProjectListCell extends ListCell<Project> {
              private TextField textField ;
              private final EventHandler<MouseEvent> dragDetectedHandler ;
              AllProjectListCell() {               
                   this.dragDetectedHandler = new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                             Dragboard db = startDragAndDrop(TransferMode.COPY);
                             ClipboardContent cc = new ClipboardContent();
                             cc.put(PROJECT_DATA_FORMAT, getItem());
                             db.setContent(cc);
                             event.consume();
                   this.setEditable(true);
              @Override
              public void updateItem(final Project project, boolean empty) {
                   super.updateItem(project, empty);
                   if (empty) {
                        setText(null);
                        setGraphic(null);
                        setOnDragDetected(null);
                   } else if (isEditing()) {
                        if (textField != null) {
                             textField.setText(getItem().getTitle());
                        setText(null) ;
                        setOnDragDetected(null);
                        setGraphic(textField);                    
                   } else {
                        setText(project.getTitle());
                        setOnDragDetected(dragDetectedHandler);
              @Override
              public void startEdit() {
                   super.startEdit();
                   if (!isEmpty()) {
                        textField = new TextField(getItem().getTitle());
                        textField.setMinWidth(this.getWidth()-this.getGraphicTextGap());
                        textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
                             @Override
                             public void changed(
                                       ObservableValue<? extends Boolean> observable,
                                       Boolean oldValue, Boolean newValue) {
                                  if (! newValue) {
                                       getItem().setTitle(textField.getText());
                                       commitEdit(getItem());
                        setText(null);
                        setGraphic(textField);
                        setOnDragDetected(null);
              @Override
              public void cancelEdit() {
                   super.cancelEdit();
                   if (!isEmpty()) {
                        setText(getItem().getTitle());
                        setGraphic(null);
                        setOnDragDetected(dragDetectedHandler);
                   } else {
                        setText(null);
                        setGraphic(null);
                        setOnDragDetected(null);
              @Override
              public void commitEdit(Project project) {
                   super.commitEdit(project);
                   if (!isEmpty()) {
                        setText(getItem().getTitle());
                        setGraphic(null);
                        setOnDragDetected(dragDetectedHandler);
    }If you try to drag from the list on the left to one of the lists on the right, it will fail pretty quickly and tell you that the data need to be Serializable.
    Simply adding "implements Serializable" to the Project and Employee classes doesn't work, as you find that SimpleStringProperty and SimpleObjectProperty are not Serializable. So instead I can use Externalizable:
    public class Project implements Externalizable {
    @Override
         public void writeExternal(ObjectOutput out) throws IOException {
              out.writeObject(title.get());
              out.writeObject(assignee.get());
         @Override
         public void readExternal(ObjectInput in) throws IOException,
                   ClassNotFoundException {
              setTitle((String)in.readObject());
              setAssignee((Employee)in.readObject());
    }and
    public class Employee implements Externalizable {
         @Override
         public void writeExternal(ObjectOutput out) throws IOException {
              out.writeObject(name.get());
         @Override
         public void readExternal(ObjectInput in) throws IOException,
                   ClassNotFoundException {
              setName((String) in.readObject());
    }This makes the drag and drop work, but if you drop a project on one of the employee lists, then edit the project title in the master list, the binding is not respected. This is because deserialization creates a new SimpleStringProperty for the title, which is not the property to which the title of the new Project object is bound.
    What I really want to do is to be able to drag and drop an object within the same JVM simply by passing the object by reference, rather than by serializing it. Is there a way to do this? Is there some DataFormat type I need?

  • Feature or bug? (ListView/SelectionModel)

    I attach a short program which illustrates a phenomenon I have observed. Basically, I am trying to repeatedly delete the first item displayed in a ListView. I select that item using SelectionModel.select(0) or SelectionModel.selectFirst() and then delete SelectionModel.getSelectedItem() from the underlying item list. The first time round it works. The second time round, SelectionModel.getSelectedItem() still returns the item from the first iteration. I would have expected the call to SelectionModel.select(0) to update selectedItemProperty. Have I misunderstood something? Should I be doing something different?
    Interestingly, a similar thing occurs if you replace select(0) with selectLast().
    But if you call select(1) everything works as I had expected (selectedItemProperty is updated).
    Feature or bug?
    Steve
    package selectionbug;
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    public class SelectionBug extends Application {
        public SelectionBug() { }
        public static void main(String[] args) {
            Application.launch(SelectionBug.class, args);
        @Override
        public void start(Stage primaryStage) {
            final ListView<String> list = new ListView<String>();
            ObservableList<String> items =
                FXCollections.observableArrayList("abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx");
            list.setItems(items);
            list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
                    System.out.println("*** ChangeListener: "+oldValue+" -> "+newValue);
            Button button = new Button("Go");
            button.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent t) {
                        list.getSelectionModel().select(0);
                        //list.getSelectionModel().selectFirst();
                        //list.getSelectionModel().selectLast();
                        String string = list.getSelectionModel().getSelectedItem();
                        System.out.println(string);
                        if (list.getItems().remove(string)) {
                            System.out.println("removed");
                        } else {
                            System.out.println("oops");
            VBox vBox = new VBox();
            vBox.getChildren().addAll(list, button);
            Scene scene = new Scene(vBox);
            primaryStage.setScene(scene);
            primaryStage.show();
    }Edited by: winnall on 16-Mar-2012 00:35

    Hi, I'm the engineer behind the selection model API.
    There are a few things to note first:
    1) It is totally valid for the selectedItem to represent an item that is not actually part of the ListView.items list. It just means that if the selectedItem is set to a non-existent item, and when the item is added to the listview.items list, the selectedIndex will update to point to this selectedItem.
    2) Events don't fire when the property value doesn't change. So the first time you select(0) you end up with the selected index event firing as the new value is 0. If nothing else changes and you call select(0) again, you'll get no event fired.
    Now, I would argue that if the selected item / index is removed from the ListView.items list, it should be removed from the selection. This does not appear to be happening. There may be various reasons why this doesn't happen (selection models can have a LOT of nuances that all need to be keep balanced like a man with his spinning plates), but you should file a bug so I can investigate deeper.
    Thanks,
    -- Jonathan

  • Bug with ListView!?

    Can someone please run the following code and tell me what is wrong? We have the following problem:
    If some cell is selected, and then you select another cell, the previously selected cell becomes partly blank (only the text element).
    If I mouse over the previously cell, the text appears again.
    A few things to notice:
    - If I remove from.setTextFill(Color.RED); from the code, it behaves as a normal list, without the bug.
    - I wonder why the text Label is highlighted white, while the text2 Label is not highlighted, while focussed.
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class TestApp3 extends Application {
        public static void main(String[] args) throws Exception {
            launch(args);
        private ObservableList<Double> items = FXCollections.observableArrayList();
        public void start(Stage stage) throws Exception {
            VBox root = new VBox(4);
            final ListView<String> listView = new ListView<String>();
            listView.setItems(FXCollections.observableArrayList(
                    "Row 1", "Row 2", "Long Row 3", "Row 4", "Row 5", "Row 6",
                    "Row 7", "Row 8", "Row 9", "Row 10", "Row 11", "Row 12", "Row 13",
                    "Row 14", "Row 15", "Row 16", "Row 17", "Row 18", "Row 19", "Row 20"
            listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
                @Override
                public ListCell<String> call(ListView<String> stringListView) {
                    final CellItem cellItem = new CellItem();
                    final ListCell<String> cell = new ListCell<String>() {
                        @Override
                        protected void updateItem(String item, boolean empty) {
                            super.updateItem(item, empty);
                            if (item != null) {
                                cellItem.setItem(item);
                    cell.setGraphic(cellItem);
                    return cell;
            root.getChildren().add(listView);
            Scene scene = new Scene(root, 800, 600);
            scene.getStylesheets().add("styles.css");
            stage.setScene(scene);
            stage.show();
        class CellItem extends HBox {
            private Label from;
            private Label text;
            private Label text2;
            public CellItem() {
                super();
                text = new Label();
                text2 = new Label();
                from = new Label();
                text.setMaxWidth(Double.MAX_VALUE);
                HBox.setHgrow(text, Priority.ALWAYS);
                getChildren().add(from);
                getChildren().add(text);
                getChildren().add(text2);
            public void setItem(String item) {
                if (item != null) {
                    text.setText(item);
                    text2.setText("Text");
                    from.setText("Bla");
                    from.setTextFill(Color.RED);
                } else {
                    text.setText(null);
    }

    Hi,
    Actually it's some kind of bug because the ListCell doesn't convert the color of textfill when the cell is select except for the "Black" filled text. The listcell must render the text fill color of all text inside it with different color to "white" when they are selected.
    @csh
    Any way for currently you can do things like this:
    First make public access to your Label:"from" variable of CellItem as getFrom().
    And add this line in ListCell factory of ListView
                   cellItem.setItem(item);
    // New Code [start]
    cell.selectedProperty().addListener(new ChangeListener<Boolean>(){
         @Override
         public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
              CellItem it = (CellItem)cell.getGraphic();
              if(it!=null){
                   if(t1.booleanValue()){
                        it.getFrom().setTextFill(Color.WHITE);
                   }else{
                                    //you own color which you want
                        it.getFrom().setTextFill(Color.RED);
    // New Code [end]
    cell.setGraphic(cellItem);
    return cell;
    //.....I know this is not a perfect but it's just for working currently.I wish JavaFX Control devs will listen this thread.
    Thanks.
    Narayan

  • Layout items in ListView

    Hello,
    I want to use a ListView as a scrollable gallery to view several large resizable nodes. I would like my ListView to fit its items to its width, similar to the behavior known from ScrollPane.setFitToWidth(true).
    How do i do this?
    If there is no simple solution that I may have overlooked, I assume that I have to set a custom CellFactory and bind some properties. But i am not sure which ones, since nothing i tried so far was successful.
    Many thanks,
    l2p

    Not sure if I'm missing something in your requirements, but this basically seems to do what you're looking for. Obviously your nodes are more complex, but this might provide a starting point.
    import java.text.NumberFormat;
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class ListViewLayoutTest extends Application {
      private static final NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
      @Override
      public void start(Stage primaryStage) {
        ListView<Fruit> fruitList = new ListView<Fruit>();
        fruitList.setItems(FXCollections.observableArrayList(
            new Fruit("Apple",1.99),
            new Fruit("Orange", 2.49),
            new Fruit("Banana", 2.99),
            new Fruit("Mango", 3.99)
        fruitList.setCellFactory(new Callback<ListView<Fruit>, ListCell<Fruit>>() {
          @Override
          public ListCell<Fruit> call(ListView<Fruit> listView) {
            return new ListCell<Fruit>() {
              @Override
              public void updateItem(Fruit item, boolean empty) {
                super.updateItem(item, empty);
                setText(null);
                final AnchorPane pane = new AnchorPane();
                setGraphic(pane);
                if (!empty) {
                  final Label nameLabel = new Label(item.getName());
                  final Label priceLabel = new Label(currencyFormat.format(item.getPrice()));
                  AnchorPane.setLeftAnchor(nameLabel, 5.0);
                  AnchorPane.setRightAnchor(priceLabel, 5.0);
                  pane.getChildren().addAll(nameLabel, priceLabel);
        BorderPane root = new BorderPane();
        root.setCenter(fruitList);
        primaryStage.setScene(new Scene(root, 400, 600));
        primaryStage.show();
      public static void main(String[] args) {
        launch(args);
      public static class Fruit {
        private final String name;
        private final double price;
        public Fruit(String name, double price) {
          this.name = name;
          this.price = price;
        public String getName() {
          return name;
        public double getPrice() {
          return price;
    }

  • JNLP-run JavaFX application hangs in full screen on Mac

    Hi all,
    I am on Mac OS X 10.9 running JDK 7u45.
    I have the JNLP file below:
    <?xml version='1.0' encoding='UTF-8'?>
    <jnlp spec="1.0+" codebase="http://localhost:8080/jnlpTester">
    <information>
    <title>Title</title>
    <vendor>Vendor</vendor>
    </information>
    <resources><jfx:javafx-runtime version="2.1+"/></resources>
    <resources><jar href="lib/jnlpTester.jar" main="true"/></resources>
    <application-desc main-class="application.JNLPTester"/>
    <security><all-permissions/></security>
    </jnlp>
    The jar file (jnlpTester.jar) contains the following JavaFX application:
    package application;
    import javafx.application.Application;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.stage.Stage;
    public class JNLPTester extends Application {
        public static void main(String[] args) {
            launch(args);
        @Override
        public void start(Stage primaryStage) throws Exception {
            Parent root = new ListView<>();
            primaryStage.setTitle("Hello World");
            primaryStage.setScene(new Scene(root, 300, 275));
            primaryStage.show();
    The application starts without any problem (see http://tinypic.com/r/29glonq/5). However, when I click on the full screen icon, the application does not go to full screen and the interface hangs (see http://tinypic.com/r/2mwizk/5). When I run the application from my IDE (eclipse) there is no such problem (see http://tinypic.com/r/2gsleep/5).
    Would anyone have any idea about this?
    Many thanks in advance,
    Hayrettin

    No it's simple, but it's not exactly what you are looking for. What I use this for is just to be able to watch a video like an .avi on my tv while surfing the web or writing a document. I hook up the computer to the tv via HDMI and then set the screens up in extended mode(not mirroring) then just drag the VLC window to the TV screen and choose VLCs full screen once the video has started. The problem is it still acts like one monitor so if you do a desktop or full screen swipe on the MBP both screens swipe resulting in the video missing from the TV. So, as I said not excatly what you want, but works to some extent.

  • Thumbnail view of a TableView populated by an ObservableList

    Hello,
    I'm populating a TableView dynamically with objects in an ObservableList.  I'd like to mark some rows with varying colors depending on their content and would like to display the marked rows in a thumbnail view of the TableView.  The idea is to basically do something like the awesome Beyond Compare app does in the top left side of their window (see http://www.scootersoftware.com/images/TextCompare.png). A click on the thumbnail would basically scroll your tableview to that location.  The square on the thumbnail represents what data is displayed on the screen and is sized proportionally with how long the TableView is and how many rows can be displayed on the screen at that time.
    Perhaps I can bind a ListView to the same ObservableList that's populating the TableView but just show an image (thin colored line) for each row of the TableView that has been marked.  Any ideas on how I could achieve something like this?
    Thanks

    In JavaFX8 you can get a filtered list from the ObservableList, and use that to populate the ListView (or whatever you decide to display). Just call table.getItems().filtered(...).
    In JavaFX 2.x, you can create an new ObservableList for your filtered data. Create a ListChangeListener and register it with table.getItems() and update your filtered data as necessary when the list changes. The tricky part is to update the filtered list when any relevant properties in the elements in the list change. For this you can create an observable list with an extractor.
    Here's an example. Note the way the observable list is created in the createData() method.
    import java.util.Arrays;
    import java.util.List;
    import javafx.application.Application;
    import javafx.beans.Observable;
    import javafx.beans.property.BooleanProperty;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableRow;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.CheckBoxTableCell;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class TableWithThumbnail extends Application {
      @Override
      public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();
        final TableView<Player> table = new TableView<Player>();
        table.setItems(createData());
        final TableColumn<Player, String> firstNameColumn = new TableColumn<>("First Name");
        final TableColumn<Player, String> lastNameColumn = new TableColumn<>("Last Name");
        final TableColumn<Player, Boolean> injuredColumn = new TableColumn<>("Injured");
        firstNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("firstName"));
        lastNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("lastName"));
        injuredColumn.setCellValueFactory(new PropertyValueFactory<Player, Boolean>("injured"));
        injuredColumn.setCellFactory(CheckBoxTableCell.forTableColumn(injuredColumn));
        injuredColumn.setEditable(true);
        table.setEditable(true);
        table.getColumns().addAll(Arrays.asList(firstNameColumn, lastNameColumn, injuredColumn));
        table.setRowFactory(new Callback<TableView<Player>, TableRow<Player>>() {
          @Override
          public TableRow<Player> call(TableView<Player> table) {
            return new PlayerTableRow();
        // Create a filtered list: only the injured players appear:
        final ObservableList<Player> injuredList = FXCollections.observableArrayList();
        buildInjuredList(table.getItems(), injuredList);
        table.getItems().addListener(new ListChangeListener<Player>() {
          @Override
          public void onChanged(ListChangeListener.Change<? extends Player> cahnge) {
            // Just rebuild injured list from scratch.
            // Might need to be more efficient: e.g. examine change(s) and update injuredList accordingly
            injuredList.clear();
            buildInjuredList(table.getItems(), injuredList);
        ListView<Player> injuredListView = new ListView<>(injuredList);
        // select and scroll in the table when selection changes in the list view:
        injuredListView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Player>() {
          @Override
          public void changed(ObservableValue<? extends Player> observable, Player oldSelection,
              Player newSelection) {
            if (newSelection != null) {
              final int index = table.getItems().indexOf(newSelection);
              table.scrollTo(index);
              table.getSelectionModel().select(index);
        root.setCenter(table);
        root.setRight(injuredListView);
        final Scene scene = new Scene(root, 800, 250);
        scene.getStylesheets().add(getClass().getResource("tableWithThumbnail.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();  
      private void buildInjuredList(final ObservableList<Player> fullList, ObservableList<Player> injuredList) {
        for (Player player : fullList) {
          if (player.isInjured()) {
            injuredList.add(player);
      public static void main(String[] args) {
        launch(args);
      private ObservableList<Player> createData() {
        List<Player> players = Arrays.asList(
            new Player("Hugo" ,"Lloris", false),
            new Player("Brad", "Friedel", false),
            new Player("Kyle", "Naughton", false),
            new Player("Younes", "Kaboul", true),
            new Player("Benoit", "Assou-Ekotto", false),
            new Player("Jan", "Vertonghen", false),
            new Player("Michael", "Dawson", false),
            new Player("William", "Gallas", true),
            new Player("Kyle", "Walker", false),
            new Player("Scott", "Parker", false),
            new Player("Mousa", "Dembele", false),
            new Player("Sandro", "Cordeiro", true),
            new Player("Tom", "Huddlestone", false),
            new Player("Gylfi","Sigurdsson", false),
            new Player("Gareth", "Bale", false),
            new Player("Aaron", "Lennon", false),
            new Player("Paulinho", "Maciel", false),
            new Player("Jermane", "Defoe", false),
            new Player("Emmanuel", "Adebayor", true)
        // Note use of "extractor": this list will notify ListChangeListeners when the list changes, or when the
        // injuredProperty of any elements change
        ObservableList<Player> data =  FXCollections.<Player>observableArrayList(new Callback<Player, Observable[]>() {
          @Override
          public Observable[] call(Player player) {
            return new Observable[] {player.injuredProperty()};
        data.addAll(players);
        return data ;
      private static class PlayerTableRow extends TableRow<Player> {
        final String INJURED_STYLE_CLASS = "injured";
        final ChangeListener<Boolean> injuryListener = new ChangeListener<Boolean>() {
          @Override
          public void changed(ObservableValue<? extends Boolean> observable,
              Boolean oldValue, Boolean newValue) {
            if (newValue && !getStyleClass().contains(INJURED_STYLE_CLASS)) {
              getStyleClass().add(INJURED_STYLE_CLASS);
            } else {
              getStyleClass().remove(INJURED_STYLE_CLASS);
        @Override
        protected void updateItem(Player player, boolean empty) {
          if (getItem() != null) {
            getItem().injuredProperty().removeListener(injuryListener);
          super.updateItem(player, empty);
          if (player != null) {
            player.injuredProperty().addListener(injuryListener);
            if (player.isInjured()) {
              if (! getStyleClass().contains(INJURED_STYLE_CLASS)) {
                getStyleClass().add(INJURED_STYLE_CLASS);
            } else {
              getStyleClass().remove(INJURED_STYLE_CLASS);
          } else {
            getStyleClass().remove(INJURED_STYLE_CLASS);
      public static class Player {
        private final StringProperty firstName ;
        private final StringProperty lastName ;
        private final BooleanProperty injured ;
        Player(String firstName, String lastName, boolean international) {
          this.firstName = new SimpleStringProperty(this, "firstName", firstName);
          this.lastName = new SimpleStringProperty(this, "lastName", lastName);
          this.injured = new SimpleBooleanProperty(this, "injured", international);
        public String getFirstName() { return firstName.get(); }
        public void setFirstName(String firstName) { this.firstName.set(firstName);}
        public StringProperty firstNameProperty() { return firstName ; }
        public String getLastName() { return lastName.get(); }
        public void setLastName(String lastName) { this.lastName.set(lastName); }
        public StringProperty lastNameProperty() { return lastName ; }  
        public boolean isInjured() { return injured.get(); }
        public void setInjured(boolean international) { this.injured.set(international); }
        public BooleanProperty injuredProperty() { return injured ; }
        @Override
        public String toString() {
          return firstName.get() + " " + lastName.get();
    Here's the (very minimal) css file:
    @CHARSET "US-ASCII";
    .injured .table-cell {
    -fx-background-color: red;

  • Audio player problem !!

    Hey amigoses ^^
    I'm a little bit stuck again with this time trying to make a mere mp3 player !!
    Probabilly the most simple one !!
    I have a list view that will contain the music titles but again, nothing comes that esay ^^
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    package audioplayer;
    import java.io.File;
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ListView;
    import javafx.scene.control.Slider;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    * @author Minedun6
    public class AudioPlayer extends Application {
        ListView list = new ListView();
        Button btn_load = new Button("Load File");
        Button btn_play = new Button("play");
        Button btn_stop = new Button("Stop");
        Button btn_pause = new Button("Pause");
        ObservableList<String> array;
        FileChooser chooser = null;
        File file;
        Media media;
        MediaPlayer player;
        Slider longeur;
        @Override
        public void start(Stage primaryStage) {
            list.setLayoutX(210);
            list.setLayoutY(10);
            list.setPrefSize(160, 260);
            btn_load.setLayoutX(295);
            btn_load.setLayoutY(260);
            btn_stop.setLayoutX(50);
            btn_pause.setLayoutX(100);
            longeur.setPrefSize(150,10);
            longeur.setLayoutX(5);
            longeur.setLayoutY(50);
            btn_load.setOnMouseClicked(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent t) {
                   chooser = new FileChooser();
                   ExtensionFilter mp3 = new ExtensionFilter("MP3 Files(*.mp3)", "*.mp3");
                   ExtensionFilter aac = new ExtensionFilter("AAC Files(*.aac)", "*.aac");
                   chooser.getExtensionFilters().addAll(mp3,aac);
                    file = chooser.showOpenDialog(null);
                   String fi = file.getAbsoluteFile().toURI().toString();
                   String name = file.getName().toString();
                   list.getItems().add(name);
                    array = FXCollections.observableArrayList();
                    array.addAll(fi);
                    System.out.println(array);
            btn_play.setOnMouseClicked(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent t) {
                    media = new Media(array.get(list.getSelectionModel().getSelectedIndex()).toString());
                    player = new MediaPlayer(media);
                    player.play();
            btn_stop.setOnMouseClicked(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent t) {
                    player.stop();
            btn_pause.setOnMouseClicked(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent t) {
                    player.pause();
            Group root = new Group();
            root.getChildren().addAll(list,btn_load,btn_play,btn_stop,btn_pause,longeur);
            Scene scene = new Scene(root, 400, 300);
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
         * The main() method is ignored in correctly deployed JavaFX application.
         * main() serves only as fallback in case the application can not be
         * launched through deployment artifacts, e.g., in IDEs with limited FX
         * support. NetBeans ignores main().
         * @param args the command line arguments
        public static void main(String[] args) {
            launch(args);
    }I really tried to do something very simple but seems no !!
    And by the way, the pause button, when i press on it, it should only pauses the play but seems it's making the player stop not pause ^^

    Thx again !!
    For the images/text, i'll be trying myself to do something and i hope this time i'll do it without yur help !!
    As for the Mp3 Player, here is the code, would be nice of to see if there is something that can be added, perfectionized !!
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    package audioplayer;
    import java.io.File;
    import javafx.application.Application;
    import javafx.beans.InvalidationListener;
    import javafx.beans.Observable;
    import javafx.beans.binding.Bindings;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListView;
    import javafx.scene.control.Slider;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.LinearGradient;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    * @author Minedun6
    public class AudioPlayer extends Application {
    //Creating the GUI Form
        Button btn_play = new Button("Play");
        Button btn_pause = new Button("Pause");
        Button btn_stop = new Button("Stop");
        Button btn_previous = new Button("Prev");
        Button btn_next = new Button("Next");
        Button btn_load = new Button("Load");
        ListView list = new ListView();
        ObservableList array = FXCollections.observableArrayList();
        FileChooser choose;
        File file;
        Media media;
        MediaPlayer player;
        Slider status = new Slider();
        Slider volume = new Slider();
    //End of GUI
        @Override
        public void start(Stage stage) throws Exception {
            //Styling btn_previous
            btn_previous.setPrefSize(80, 30);
            btn_previous.setLayoutX(10);
            btn_previous.setLayoutY(330);
            //end of btn_previous
            //Styling btn_pause
            btn_pause.setPrefSize(80, 30);
            btn_pause.setLayoutX(100);
            btn_pause.setLayoutY(330);
            //end of btn_pause
            //Styling btn_play
            btn_play.setPrefSize(80, 30);
            btn_play.setLayoutX(190);
            btn_play.setLayoutY(330);
            //end of btn_play
            //Styling btn_stop
            btn_stop.setPrefSize(80, 30);
            btn_stop.setLayoutX(280);
            btn_stop.setLayoutY(330);
            //end of btn_stop
            //Styling btn_next
            btn_next.setPrefSize(80, 30);
            btn_next.setLayoutX(370);
            btn_next.setLayoutY(330);
            //end of btn_next
            //Styling list
            list.setPrefSize(280, 300);
            list.setLayoutX(500);
            list.setLayoutY(10);
            //end of list
            //Styling btn_load
            btn_load.setPrefSize(80, 30);
            btn_load.setLayoutX(600);
            btn_load.setLayoutY(330);
            //end of btn_load
            //Styling status slider
            status.setPrefSize(450, 10);
            status.setLayoutX(10);
            status.setLayoutY(290);
            //end of status slider
            //Styling volume slider
            volume.setPrefSize(100, 10);
            volume.setLayoutX(350);
            volume.setLayoutY(310);
            volume.setValue(100.0);
            volume.setMin(0.0);
            volume.setMax(100.0);
            //end of volume slider
            btn_play.disableProperty().bind(Bindings.isEmpty(list.getSelectionModel().getSelectedItems()));
            btn_next.disableProperty().bind(Bindings.isEmpty(list.getSelectionModel().getSelectedItems()));
            btn_previous.disableProperty().bind(Bindings.isEmpty(list.getSelectionModel().getSelectedItems()));
            btn_pause.disableProperty().bind(Bindings.isEmpty(list.getSelectionModel().getSelectedItems()));
            btn_stop.disableProperty().bind(Bindings.isEmpty(list.getSelectionModel().getSelectedItems()));
            list.setOnKeyReleased(new EventHandler< KeyEvent>(){
                @Override
                public void handle(KeyEvent t) {
                    if(t.getCode() == KeyCode.DELETE){
                        list.getItems().remove(list.getSelectionModel().getSelectedIndex());
                        array.remove(list.getSelectionModel().getSelectedIndex());
            btn_load.setOnMouseClicked(new EventHandler<MouseEvent>() {
                //Evenement associé au clic du bouton Load
                @Override
                public void handle(MouseEvent t) {
                    //Ajout des Filtres de choix !!
                    ExtensionFilter mp3 = new ExtensionFilter("MP3 Files(*.mp3)", "*.mp3");
                    ExtensionFilter aac = new ExtensionFilter("AAC Files(*.aac)", "*.aac");
                    choose = new FileChooser();
                    choose.getExtensionFilters().addAll(mp3, aac);
                    file = choose.showOpenDialog(null);
                    if (file != null) {
                        //Ajout à la liste pour stocker les titres chansons !!
                        String fi = file.getAbsoluteFile().toURI().toString();
                        String name = file.getName().toString().substring(0, file.getName().toString().lastIndexOf("."));
                        list.getItems().add(name);
                        array.add(fi);
            btn_play.setOnMouseClicked(new EventHandler<MouseEvent>() {
                //Evenement associé au click du button play
                @Override
                public void handle(MouseEvent t) {
                    if (!(list.getItems().isEmpty())) {
                        //player.stop();
                        media = new Media(array.get(list.getSelectionModel().getSelectedIndex()).toString());
                        player = new MediaPlayer(media);
                        player.play();
                        player.setOnReady(new Runnable() {
                            @Override
                            public void run() {
                                status.setMin(0.0);
                                status.setValue(0.0);
                                status.setMax(player.getTotalDuration().toSeconds());
                                volume.setValue(100.0);
                                player.setVolume(100.0 / 100);
                                player.currentTimeProperty().addListener(new ChangeListener<Duration>() {
                                    @Override
                                    public void changed(ObservableValue<? extends Duration> ov, Duration t, Duration t1) {
                                        status.setValue(t1.toSeconds());
            status.valueProperty().addListener(new InvalidationListener() {
                @Override
                public void invalidated(Observable o) {
                    if (status.isValueChanging()) {
                        player.seek(Duration.seconds(status.getValue()));
            volume.valueProperty().addListener(new InvalidationListener() {
                @Override
                public void invalidated(Observable o) {
                    if (volume.isValueChanging()) {
                        //le volume doit être divisé par 100 pour ressentir la dégradation du volume
                        //sinon ça passe trop vite
                        player.setVolume(volume.getValue() / 100);
            btn_next.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent t) {
                    if ((list.getItems().size() != 0) || (list.getItems().get(list.getItems().size() + 1) != null)) {
                        player.stop();
                        list.getSelectionModel().selectNext();
                        media = new Media(array.get(list.getSelectionModel().getSelectedIndex()).toString());
                        player = new MediaPlayer(media);
                        player.play();
                        player.currentTimeProperty().addListener(new ChangeListener<Duration>() {
                                    @Override
                                    public void changed(ObservableValue<? extends Duration> ov, Duration t, Duration t1) {
                                        status.setValue(t1.toSeconds());
            btn_previous.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent t) {
                    if ((list.getItems().size() != 0) || (list.getItems().get(-1) != null)) {
                        player.stop();
                        list.getSelectionModel().selectPrevious();
                        media = new Media(array.get(list.getSelectionModel().getSelectedIndex()).toString());
                        player = new MediaPlayer(media);
                        player.play();
                        player.currentTimeProperty().addListener(new ChangeListener<Duration>() {
                                    @Override
                                    public void changed(ObservableValue<? extends Duration> ov, Duration t, Duration t1) {
                                        status.setValue(t1.toSeconds());
            Group root = new Group();
            root.getChildren().addAll(btn_play, btn_previous,
                    btn_pause, btn_stop, btn_next, btn_load, list,
                    status, volume);
            Scene scene = new Scene(root, 800, 450);
            stage.setScene(scene);
            scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
            stage.setTitle("Audio Player");
            stage.show();
        public void disableAll(){
            if(list.getItems().isEmpty()){
            btn_play.setDisable(true);
            btn_pause.setDisable(true);
            btn_next.setDisable(true);
            btn_previous.setDisable(true);
            btn_stop.setDisable(true);
        public static void main(String[] args) {
            launch(args);
    }

  • What exactly is the "cell factory?"

    So I've been seeing this term a lot on the forums, as well as http://docs.oracle.com/javafx/2/ui_controls/table-view.htm and on the ensemble, but I'm not 100% sure what it is.... It seems like just a method to set data into your tables, like the table model? Anyone have a more in depth explanation than the one in the docs, I would appreciate it!!!
    Thanks,
    ~KZ

    Cell factories create cells. A cell is a Labeled Node which contains some extra properties and methods for maintaining an editing and selection state and a link back to a cell value. Cells are used in a few places in JavaFX, for example in ListViews and TableViews, as well as TreeTables and ComboBoxes. The Cell is the visual representation (Node) which corresponds to a backing data item. The trick is that there is not necessarily a static one to one correspondence between cells and data values.
    Let's take an example. Here is an empty ListView in a Scene. When I run the app, it displays the ListView at it's preferred height, with 17 rows.
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    public class ListViewSample extends Application {
      @Override public void start(Stage stage) {
        ListView listView = new ListView();
        VBox layout = new VBox();
        VBox.setVgrow(listView, Priority.ALWAYS);
        layout.getChildren().addAll(listView);
        stage.setScene(new Scene(layout));
        stage.show();
      public static void main(String[] args) { launch(args); }
    }Each one of those 17 rows is empty. No Cell Factory has been set, yet you can see alternating light and dark shaded rows. Each one of these rows in the ListView corresponds to a Cell and each cell has been generated by the default ListView cell factory. When I drag the stage's bottom border to increase the size of the stage, the list view increases in size. When I drag the stage's bottom border to decrease the size of the stage, the list view decreases in size. When the list view increases in size, more rows are visible. Each of the new cells for the larger list view are generated by the cell factory on an as needed basis; i.e. the cells were not created when the app was first run but only created as there was a greater visible area available to the ListView in which the ListView could display more cells.
    Now everything is pretty boring so far. Let's add some data, using the following line of code:
    listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));Now you will see the strings "apple", "orange" and "pear" rendered in the first three cells of the ListView again by using the default cell factory for the ListView. Again this is pretty boring.
    What we will do now is add some mutators which will change the observable list backing the list view in response to some user actions:
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.event.*;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    import java.util.Collections;
    import java.util.Comparator;
    public class ListViewSample extends Application {
      @Override public void start(Stage stage) {
        final ListView<String> listView = new ListView<>();
        listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));
        ListViewSorter listViewSorter = new ListViewSorter(listView).invoke();
        VBox layout = new VBox(10);
        VBox.setVgrow(listView, Priority.ALWAYS);
        listView.setMinHeight(0);
        layout.getChildren().addAll(
            listView,
            HBoxBuilder
                .create()
                .spacing(10)
                .children(
                    guavaCreator(listView),
                    listViewSorter.getSorter(),
                    listViewSorter.getReverser()
                .build()
        stage.setScene(new Scene(layout));
        stage.show();
      private Button guavaCreator(final ListView<String> listView) {
        final Button guavatron = new Button("Add Guava");
        guavatron.setOnAction(new EventHandler<ActionEvent>() {
          @Override public void handle(ActionEvent actionEvent) {
            listView.getItems().add("guava");
            guavatron.setDisable(true);
        return guavatron;
      public static void main(String[] args) { launch(args); }
      private class ListViewSorter {
        private final ListView<String> listView;
        private Button sorter;
        private Button reverser;
        public ListViewSorter(ListView<String> listView) {
          this.listView = listView;
        public Button getSorter() {
          return sorter;
        public Button getReverser() {
          return reverser;
        public ListViewSorter invoke() {
          sorter = new Button("Sort");
          sorter.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              Collections.sort(listView.getItems());
          final Comparator<String> REVERSE_SORT = new Comparator<String>() {
            @Override  public int compare(String s1, String s2) {
              return -1 * s1.compareTo(s2);
          reverser = new Button("Reverse Sort");
          reverser.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              Collections.sort(listView.getItems(), REVERSE_SORT);
          return this;
    }OK, now we have some extra buttons, the "Add guava" button will create a new item ("guava"), the "Sort" and "Reverse Sort", buttons will change the sort order of the backing list. Now to understand what happens behind the scenes when we use these buttons, let's take a look at the source code for the default list cell factory.
    new ListCell() {
       @Override public void updateItem(Object item, boolean empty) {
         super.updateItem(item, empty);
         if (empty) {
           setText(null);
           setGraphic(null);
         } else if (item instanceof Node) {
           setText(null);
           Node currentNode = getGraphic();
           Node newNode = (Node) item;
           if (currentNode == null || ! currentNode.equals(newNode)) {
             setGraphic(newNode);
         } else {
           setText(item == null ? "null" : item.toString());
           setGraphic(null);
    };This code is doing one of three things. If the list cell is empty, it sets the text and graphic to null, so you end up with a blank cell (the alternating light and dark grey bars are generated by the ListCell's parent setting differing style classes on alternate cells). If the item is a node, it sets the graphic to the node - this is the mechanism which allow you to place nodes directly in the backing list for the ListView and have the ListView display them OK. Otherwise a toString is called on the item to set the item's text (this is the case which is occurring for our simple example of Strings in the backing list).
    Now the important thing to note about the ListCell implementation is that the clever logic of translating the backing item for the cell to a visual representation is occurring in an updateItem call. This updateItem method is invoked by the JavaFX system on the ListCell whenever the backing item for the cell has been invalidated, for example the item has been edited, a new item added, or the items in the list have been reordered.
    So when somebody presses, the "Add Guava" button, a new ListCell is not created, instead updateItem is called on an already existing empty cell. This is because when we started the application, there was space for 17 rows, so 17 cells were already created, it is just that most of them were empty because we only had 3 items in the backing list for the ListView.
    Now, if we press one of the sort buttons to reorder the backing list, it will cause the existing list cells to become invalidated, and updateItem will be called on each of the cells according to the change permutations in the ObservableList. Note that as each item is updated, a new Labeled display node for the item is not created, instead the setText method is invoked which changes the text for the existing Labeled.
    There are a couple of extra cases to understand. Our backing list currently maxes out at 4 items. Let's say we drag the bottom of our stage up so that the available space for the ListView was made really small (e.g. only 2 rows high). In this case, you will two rows (cells) and a scrollbar you can use to scroll up and down. As you scroll up and down it seems that some rows are scrolling off the screen and some are scrolling on the screen. What is actually happening though is that the same two cells are remaining on screen and their contents being continually updated and replaced as backing items come in and out of view. This is the magic of how the ListView is able to achieve it's efficiency when dealing with potentially very large collections or collections where not all of the required data is available on the client at the current time. Instead of creating visual cells for all of the possible items which can be placed in the list, instead the ListView creates cells only for the visible items and updates the content of those cells on an as needed basis. This concept is known in the List Cell creators jargon as a Virtual Flow in a Virtualized control.
    OK, so that was a little more interesting, but there have been a lot of words so far, and no custom cell factory. This was partly on purpose - there is lot you can do with the default cell factory without needing to create your own custom cell factory.
    But sometimes you do actually want to create your own cell factory when you want fine control over the look or behaviour of the cells.
    Let's say you want to show each item in the list with a capitalized friendly name "Apple", "Orange" and "Pear" and an icon - a picture of the corresponding fruit. To do this you would create a cell factory - something that can produce the visual representation of these things from the corresponding data values.
    import javafx.application.Application;
    import javafx.collections.*;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class ListViewCustomCellFactorySample extends Application {
      ObservableMap<String, Image> iconMap = FXCollections.observableHashMap();
      @Override public void init() {
        iconMap.put(
          "apple", 
          new Image(
            "http://uhallnyu.files.wordpress.com/2011/11/green-apple.jpg",
            0, 32, true, true
        iconMap.put(
          "orange",
          new Image(
            "http://i.i.com.com/cnwk.1d/i/tim/2011/03/10/orange_iStock_000001331357X_540x405.jpg",
            0, 32, true, true
        iconMap.put(
          "pear",  
          new Image(
            "http://smoothiejuicerecipes.com/pear.jpg",
            0, 32, true, true
      @Override public void start(Stage stage) {
        final ListView<String> listView = new ListView<>();
        listView.setItems(FXCollections.observableArrayList("apple", "orange", "pear"));
        listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
          @Override public ListCell<String> call(ListView<String> stringListView) {
            return new LabeledIconListCell();
        VBox layout = new VBox(10);
        VBox.setVgrow(listView, Priority.ALWAYS);
        listView.setMinHeight(0);
        layout.getChildren().addAll(
            listView
        stage.setScene(new Scene(layout));
        stage.show();
      public static void main(String[] args) { launch(args); }
      private class LabeledIconListCell extends ListCell<String> {
        @Override protected void updateItem(String item, boolean empty) {
          super.updateItem(item, empty);
          if (item != null) {
            String friendlyText = item.toString();
            if (item.length() > 0) {
              friendlyText = item.substring(0, 1).toUpperCase() + item.substring(1);
            setText(friendlyText);
            setGraphic(
                StackPaneBuilder
                    .create()
                    .prefWidth(55)
                    .children(
                        new ImageView(
                            iconMap.get(item)
                    .build()
          } else {
            setText("");
            setGraphic(null);
    }Here what the cell factory has done is to check what value of the backing item for the cell is whenever that item has been updated, and set some customized label text and graphic representation for the cell.
    As a minor point, for efficiency, and because there are only a few of them, the required images are loaded and scaled up front so that they don't been to be reloaded every time the cell is updated with a different value (which if the image loading was within the cell's updateItem call could mean that the same image could potentially get loaded multiple times.
    My personal take on this is that it is powerful but complicated. Often people will gravitate towards using the complex ListView and TableView APIs when they don't necessarily need all of the functionality and virtualization efficiency capabilities that the virtualized controls offer. In many cases, simple layout mechanisms such VBoxes and Grids can be a better choice. However, if you have a need for the virtualized functions, then it's good to know that things like ListView and TableView are there if you can work out how to use them well in your case.
    Also note that JavaFX 2.2+ has numerous convenience methods for creating different kinds of cells which you may be able to use in standard cases to avoid some of the overhead in creating your own, for example the CheckBoxListCell, the ComboBoxListCell and the TextFieldListCell. And there are many more such simplifying higher level abstractions in the DataFX library.
    One other point worth observing is that if you have a list of mutatable objects, for example Person objects with a changable last name field, then you need to make the object an Observable object with an invalidation implementation if you want the updateItem call in the cell factory to be invoked automatically whenever the object is mutated.
    A cell factory and a cell value factory are different things, but that is probably a topic for a different post.
    I realize this was a round about and lengthy explanation - hopefully it served some purpose and helped to explain some of the mysteries of cell factories.
    http://docs.oracle.com/javafx/2/api/javafx/scene/control/Cell.html
    http://www.javafxdata.org
    http://docs.oracle.com/javafx/2/ui_controls/list-view.htm

  • Strange layout behaviour with TilePane

    here is the demo
    1.rootLayout have 2 child,controlbox and contentLayout
    2.3 button on controlbox
    3.contentLayout will add content,when press deffrent button on controlbox
    4.watch button "Add TilePane" , strange layout behaviour , what is the matter?
    layout picture
    |--------------------------------|                 
    |           |                    |                 
    |           |                    |                 
    |           |                    |                 
    |           |                    |                 
    |controlbox |  contentLayout     |                 
    | (VBox)    |   (StackPane)      |                 
    |           |                    |                 
    |           |                    |                 
    |           |                    |                 
    |           |                    |                 
    |--------------------------------|               
                                            the code
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.geometry.Pos;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListView;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.layout.TilePane;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    public class testTilePaneLayout  extends Application {
         StackPane contentLayout = new StackPane();
         //add content with 2 Button
         public void addContent(){
              VBox vbox = new VBox();
              contentLayout.getChildren().clear();
              contentLayout.getChildren().add(vbox);
              StackPane.setAlignment(vbox,Pos.CENTER);
              Button btn = new Button("Button1");     
              Button btn2= new Button("Button2");
              vbox.getChildren().add(btn);
              vbox.getChildren().add(btn2);
         //add content with 2 Button & 1 ListView
         public void addListViewContent(){
              VBox vbox = new VBox();
              contentLayout.getChildren().clear();
              contentLayout.getChildren().add(vbox);
              StackPane.setAlignment(vbox,Pos.CENTER);
              Button btn = new Button("Button1");     
              Button btn2= new Button("Button2");     
              vbox.getChildren().add(btn);
              vbox.getChildren().add(btn2);
              @SuppressWarnings("rawtypes")
              ListView listView = new ListView();
              vbox.getChildren().add(listView);
         //add content with 2 Button & 1 TilePane
         public void addTilePaneContent(){
              VBox vbox = new VBox();
              contentLayout.getChildren().clear();
              contentLayout.getChildren().add(vbox);
              StackPane.setAlignment(vbox,Pos.CENTER);
              Button btn = new Button("Button1");     
              Button btn2= new Button("Button2");     
              vbox.getChildren().add(btn);
              vbox.getChildren().add(btn2);
              TilePane tilePane = new TilePane();
              tilePane.setMaxSize(100,100);
              Label lbl = new Label("Label on TilePane");
              tilePane.getChildren().add(lbl);
              vbox.getChildren().add(tilePane);
         public void start(Stage stage) {
              stage.setResizable(false);
              stage.centerOnScreen();
              Group root = new Group();
              Scene scene = new Scene(root,800,600);     
              stage.setScene(scene);
              //root  Layout =  StackPane
              StackPane rootLayout = new StackPane();
              root.getChildren().add(rootLayout);
              rootLayout.setMinSize(800,600);
              rootLayout.setMaxSize(800,600);
              //content  StackPane
              rootLayout.getChildren().add(contentLayout);
              contentLayout.setMinSize(100, 100);
              contentLayout.setMaxSize(200, 200);
              StackPane.setAlignment(contentLayout,Pos.CENTER);
              //control  VBox
              VBox controlBox = new VBox();
              rootLayout.getChildren().add(controlBox);     
              controlBox.setMaxSize(100, 200);
              StackPane.setAlignment(controlBox,Pos.CENTER_LEFT);
              //3 control  button
              Button btn1 = new Button("Add button");     
              Button btn2= new Button("Add Listview");
              Button btn3= new Button("Add TilePane");
              controlBox.getChildren().add(btn1);
              controlBox.getChildren().add(btn2);
              controlBox.getChildren().add(btn3);
              btn1.setOnMousePressed(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent arg0) {
                        addContent();     
              btn2.setOnMousePressed(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent arg0) {
                        addListViewContent();     
              btn3.setOnMousePressed(new EventHandler<MouseEvent>() {
                   @Override
                   public void handle(MouseEvent arg0) {
                        addTilePaneContent();     
              stage.show();
         public static void main(String[] args) {
              Application.launch(args);
    }Edited by: noregister on Oct 4, 2011 11:30 AM
    Edited by: noregister on Oct 4, 2011 11:31 AM

    Oh, my bad. I'm actually using a JToggleButton and not a JButton, so the getRootPane().setDefaultButton() doesn't apply because it only takes JButton as an input param. I wonder why it wasn't implemented to take AbstractButton. hmmm.

  • ComboBox: width of list initially too small

    Hi everybody,
    I've written a littlle application which contains a ComboBox. The ComboBox contents will be set asynchronously. When the contents are set and I expand the list, the width of the list is initially too small. After I close the list and expand it again, the width of the list is correct. Did I make anything wrong???
    Sample:
    package combotest;
    import java.util.ArrayList;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.property.ListProperty;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleListProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.control.SingleSelectionModel;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Pane;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.stage.WindowEvent;
    import javafx.util.Callback;
    public class ComboTest extends Application implements EventHandler<WindowEvent>
    private ComboBox<Test> combo = null;
    private ObservableList<Test> observableTests = FXCollections.observableArrayList();
    private ListProperty<Test> tests = new SimpleListProperty<Test>(observableTests);
    private ObjectProperty<SingleSelectionModel<Test>> selectedTest = null;
    public class Test
    private String label;
    public Test(String label)
    this.label = label;
    public String getLabel()
    return label;
    public class TestListCell extends ListCell<Test>
    @Override
    protected void updateItem(Test arg0,
    boolean arg1)
    super.updateItem(arg0, arg1);
    if((arg0 == null) || arg1)
    setText("");
    else
    setText(arg0.getLabel());
    @Override
    public void start(Stage arg0) throws Exception
    VBox vbox = new VBox();
    vbox.getChildren().add(createComboPane());
    arg0.setScene(new Scene(vbox, 400, 200, Color.WHITE));
    arg0.setTitle("ComboTest");
    initialize();
    arg0.setOnCloseRequest(this);
    arg0.show();
    public static void main(String[] args)
    launch(args);
    @Override
    public void handle(WindowEvent arg0)
    System.exit(0);
    private Pane createComboPane()
    HBox hbox = new HBox();
    hbox.setPadding(new Insets(5));
    hbox.setSpacing(15);
    hbox.setAlignment(Pos.CENTER_LEFT);
    VBox.setMargin(hbox, new Insets(5));
    Label label = new Label("A combo");
    combo = new ComboBox<>();
    combo.setEditable(false);
    combo.setMaxWidth(Double.MAX_VALUE);
    combo.setButtonCell(new TestListCell());
    combo.setCellFactory(new Callback<ListView<Test>, ListCell<Test>>()
    @Override
    public ListCell<Test> call(ListView<Test> arg0)
    return new TestListCell();
    combo.valueProperty().addListener(new ChangeListener<Test>()
    @Override
    public void changed(ObservableValue<? extends Test> arg0, Test arg1, final Test arg2)
    HBox.setHgrow(combo, Priority.ALWAYS);
    hbox.getChildren().addAll(label, combo);
    return hbox;
    private void initialize()
    combo.itemsProperty().bind(tests);
    selectedTest = new SimpleObjectProperty<SingleSelectionModel<Test>>(combo.getSelectionModel());
    combo.selectionModelProperty().bindBidirectional(selectedTest);
    new Thread(new Runnable()
    @Override
    public void run()
    try
    Thread.sleep(3000);
    final ArrayList<Test> testList = new ArrayList<>();
    testList.add(new Test("Test entry 1"));
    tests.set(FXCollections.observableArrayList(testList));
    Platform.runLater(new Runnable()
    @Override
    public void run()
    selectedTest.get().selectFirst();
    catch(InterruptedException e)
    }).start();
    }

    There is a bug: https://javafx-jira.kenai.com/browse/RT-28876
    ComboBox popup list is wrong width the first time it is shown if the ComboBox is wider than prefWidth.
    This is fixed in javafx8.0 already, but not in javafx2.

  • Issue with a class extending EventHandler MouseEvent

    Hello all,
    I originally had a nested class that was a used for mouseEvents. I wanted to make this it's own class, so I can call it directly into other class objects I have made, but for some reason it isn't working and I'm getting an eror
    here is the code:
    public class MouseHandler implements EventHandler<MouseEvent>
        private double sceneAnchorX;
        private double sceneAnchorY;
        private double anchorAngle;
        private Parent parent;
        private final Node nodeToMove ;
       MouseHandler(Node nodeToMove)
           this.nodeToMove = nodeToMove ;
        @Override
        public void handle(MouseEvent event)
          if (event.getEventType() == MouseEvent.MOUSE_PRESSED)
            sceneAnchorX = event.getSceneX();
            sceneAnchorY = event.getSceneY();
            anchorAngle = nodeToMove.getRotate();
            event.consume();
          else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED)
              if(event.isControlDown())
                  nodeToMove.setRotationAxis(new Point3D(sceneAnchorY,event.getSceneX(),0));
                  nodeToMove.setRotate(anchorAngle + sceneAnchorX -  event.getSceneX());
                  sceneAnchorX = event.getSceneX();
                  sceneAnchorY = event.getSceneY();
                  anchorAngle = nodeToMove.getRotate();
                  event.consume();
              else
                double x = event.getSceneX();
                double y = event.getSceneY();
                nodeToMove.setTranslateX(nodeToMove.getTranslateX() + x - sceneAnchorX);
                nodeToMove.setTranslateY(nodeToMove.getTranslateY() + y - sceneAnchorY);
                sceneAnchorX = x;
                sceneAnchorY = y;
                event.consume();
          else if(event.getEventType() == MouseEvent.MOUSE_CLICKED)
            //  nodeToMove.setFocusTraversable(true);
               nodeToMove.requestFocus();
               event.consume();
                         nodeToMove.setOnKeyPressed((KeyEvent)
    ->{
         if(KeyCode.UP.equals(KeyEvent.getCode()))
             nodeToMove.setScaleX(nodeToMove.getScaleX()+ .1);
             nodeToMove.setScaleY(nodeToMove.getScaleY()+ .1);
             nodeToMove.setScaleZ(nodeToMove.getScaleZ()+ .1);
             System.out.println("kaw");
             KeyEvent.consume();
         if(KeyCode.DOWN.equals(KeyEvent.getCode()))
             if(nodeToMove.getScaleX() > 0.15)
             nodeToMove.setScaleX(nodeToMove.getScaleX()- .1);
             nodeToMove.setScaleY(nodeToMove.getScaleY()- .1);
             nodeToMove.setScaleZ(nodeToMove.getScaleZ()- .1);
             System.out.println(nodeToMove.getScaleX());
             KeyEvent.consume();
         nodeToMove.setOnScroll((ScrollEvent)
                 ->{
             if(nodeToMove.isFocused())
                        if(ScrollEvent.getDeltaY() > 0)
                            nodeToMove.setTranslateZ(10+nodeToMove.getTranslateZ());
                        else
                            nodeToMove.setTranslateZ(-10+nodeToMove.getTranslateZ());
           ScrollEvent.consume();
    }This is the class where I call it.
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.Box;
    * @author Konrad
    public class Display extends Pane
        Box b;
        PhongMaterial pm = new PhongMaterial(Color.GRAY);
        public Display(Double x, Double y,Double width, Double height)
             super();
             b = new Box(width, height,10);
             setPrefSize(width,height);
             relocate(x, y);
             b.setMaterial(pm); 
             b.addEventFilter(MouseEvent.ANY, new MouseHandler(this));
             getChildren().add(b);
    }There is no red dot stating the class doesn't exist, or anything is wrong, but when I run it I get an error.
    here is the error:
    C:\Users\Konrad\Documents\NetBeansProjects\3D\src\3d\Display.java:29: error: cannot find symbol
             b.addEventFilter(MouseEvent.ANY, new MouseHandler(this));
      symbol:   class MouseHandler
      location: class DisplayThis is another class from the one that it was originally "nested" in(sorry if I'm not using correct terms). The other class, as well as this, produce the same error(this one was just smaller and eaiser to use as an example).
    The code is exactly the same.
    Originally I thought that the MouseEvent class wasn't an FX class, so I switched it and thought it worked, tried it on the Display class it didn't, tried it on the first one and yeah still didn't, so not too sure what happened there :(.
    Thanks,
    ~KZ
    Edited by: KonradZuse on Jun 7, 2013 12:15 PM
    Edited by: KonradZuse on Jun 7, 2013 12:38 PM
    Edited by: KonradZuse on Jun 7, 2013 12:39 PM

    Last time that was the issue I was having for a certain case; however this seems to be different, here is the list of imports for each class.
    MouseHandler:
    import javafx.event.EventHandler;
    import javafx.geometry.Point3D;
    import javafx.scene.Node;
    import javafx.scene.Parent;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.MouseEvent;Display:
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.Box;draw:
    import java.io.File;
    import java.sql.*;
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.geometry.Rectangle2D;
    import javafx.scene.Group;
    import javafx.scene.PerspectiveCamera;
    import javafx.scene.PointLight;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.control.Menu;
    import javafx.scene.control.MenuBar;
    import javafx.scene.control.MenuItem;
    import javafx.scene.control.TextField;
    import javafx.scene.input.ClipboardContent;
    import javafx.scene.input.DataFormat;
    import javafx.scene.input.DragEvent;
    import javafx.scene.input.Dragboard;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.input.TransferMode;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.TriangleMesh;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Screen;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import jfxtras.labs.scene.control.window.Window;
    import org.controlsfx.dialogs.Action;
    import org.controlsfx.dialogs.Dialog;Edited by: KonradZuse on Jun 7, 2013 2:27 PM
    Oddly enough I tried it again and it worked once, but the second time it error-ed out again, so I'm not sure what the deal is.
    then I ended up getting it to work again in the draw class only but when I tried to use the event I get this error.
    J a v a M e s s a g e : 3 d / M o u s e H a n d l e r
    java.lang.NoClassDefFoundError: 3d/MouseHandler
         at shelflogic3d.draw.lambda$5(draw.java:331)
         at shelflogic3d.draw$$Lambda$16.handle(Unknown Source)
         at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
         at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
         at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
         at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
         at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
         at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
         at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
         at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
         at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
         at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
         at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
         at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
         at javafx.event.Event.fireEvent(Event.java:202)
         at javafx.scene.Scene$DnDGesture.fireEvent(Scene.java:2824)
         at javafx.scene.Scene$DnDGesture.processTargetDrop(Scene.java:3028)
         at javafx.scene.Scene$DnDGesture.access$6500(Scene.java:2800)
         at javafx.scene.Scene$DropTargetListener.drop(Scene.java:2771)
         at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler$3.run(GlassSceneDnDEventHandler.java:85)
         at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler$3.run(GlassSceneDnDEventHandler.java:81)
         at java.security.AccessController.doPrivileged(Native Method)
         at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler.handleDragDrop(GlassSceneDnDEventHandler.java:81)
         at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleDragDrop(GlassViewEventHandler.java:595)
         at com.sun.glass.ui.View.handleDragDrop(View.java:664)
         at com.sun.glass.ui.View.notifyDragDrop(View.java:977)
         at com.sun.glass.ui.win.WinDnDClipboard.push(Native Method)
         at com.sun.glass.ui.win.WinSystemClipboard.pushToSystem(WinSystemClipboard.java:234)
         at com.sun.glass.ui.SystemClipboard.flush(SystemClipboard.java:51)
         at com.sun.glass.ui.ClipboardAssistance.flush(ClipboardAssistance.java:59)
         at com.sun.javafx.tk.quantum.QuantumClipboard.flush(QuantumClipboard.java:260)
         at com.sun.javafx.tk.quantum.QuantumToolkit.startDrag(QuantumToolkit.java:1277)
         at javafx.scene.Scene$DnDGesture.dragDetectedProcessed(Scene.java:2844)
         at javafx.scene.Scene$DnDGesture.process(Scene.java:2905)
         at javafx.scene.Scene$DnDGesture.access$8500(Scene.java:2800)
         at javafx.scene.Scene$MouseHandler.process(Scene.java:3564)
         at javafx.scene.Scene$MouseHandler.process(Scene.java:3379)
         at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3331)
         at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1612)
         at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2399)
         at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:312)
         at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:237)
         at java.security.AccessController.doPrivileged(Native Method)
         at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:354)
         at com.sun.glass.ui.View.handleMouseEvent(View.java:514)
         at com.sun.glass.ui.View.notifyMouse(View.java:877)
         at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
         at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
         at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:101)
         at java.lang.Thread.run(Thread.java:724)
    Caused by: java.lang.ClassNotFoundException: shelflogic3d.MouseHandler
         at java.net.URLClassLoader$1.run(URLClassLoader.java:365)
         at java.net.URLClassLoader$1.run(URLClassLoader.java:354)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.net.URLClassLoader.findClass(URLClassLoader.java:353)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
         ... 50 more
    Exception in thread "JavaFX Application Thread" E..........After the E comes a bunch of random stuff with drag and drop and such (since I'm dragging an item, and then creating it and giving it the event in question).
    Line 331 is                      b.addEventHandler(MouseEvent.ANY, new MouseHandler(b));

  • Why do I get Memory Leaks in case 1, but not in case 2?

    I recently investigated into memory leaks, since we got some when a Window is opened/closed several times.
    I discovered the following behavior with ListView:
    If I make several instances of a Window, which contains a ListView which uses a fix list as items, there are leaks. (Case 1)
    If I make several instances of the ListView directly there are no leaks. (Case 2).
    For me both cases seems equal, there's just another wrapper (the window) around the ListView in case 1.
    Can someone explain what's going on?
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    public class TestApp3 extends Application {
        public static void main(String[] args) throws Exception {
            launch(args);
        ObservableList<String> items = FXCollections.observableArrayList("Item1", "Item2");
        public void start(final Stage stage) throws Exception {
            VBox root = new VBox();
            for (int i = 0; i < 100; i++) {
                SubStage subStage = new SubStage(); // Case 1
                subStage.show();
                subStage.hide();
    //            ListView<String> listView = new ListView<String>(); // Case 2
    //            listView.setItems(items);
            System.gc();
            System.out.println((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 + " KB");
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();
        private class SubStage extends Stage {
            public SubStage() {
                ListView<String> listView = new ListView<String>();
                listView.setItems(items);
                Scene scene = new Scene(listView);
                setScene(scene);
    }EDIT: If I use a TableView in the Substage, there are NO leaks. So is this an issue of the ListView?
    Edited by: csh on 10.09.2012 07:40

    There is file activity if Open Config Data.vi is being called.  The error is just due to not being able to find the configuration/.ini file.  Root cause could be a few things: the INI file was deleted/not moved/invalid path/whatever.  And the "create file if necessary" input to your use of Open Config Data.vi must be set to False for whatever reason.
    Side note:
    There were a couple changes to the Config VI's between v6 and v7.
    If you were relying on using the default FALSE in Close Config Data.vi in LV6.1, you have to change your code.
    From LV7 Upgrade Notes:
    <snip>
    • The configuration file path input of the Open Config Data VI is a required input. You must specify the configuration file path even if you open a reference to a configuration data object.
    • The default of the write configuration file? input of the Close Config Data VI is TRUE. In LabVIEW 6.1 and earlier, the default is FALSE.
    <snip>
    =====================================================
    Fading out. " ... J. Arthur Rank on gong."
    Attachments:
    OpenConfigData_v7Help.jpg ‏19 KB

  • Check if component is visible

    I implemented a gallery displaying some images. This worked fine for the few images, I had in my example. However as soon as there are more images (>100) memory becomes an issue, as all images are initialized when the gallery is loaded.
    Is there an easy way to implement lazy loading? I figure it would suffice to know which component (e.g. HBox) is visible, everything above and below could be loaded when it becomes visible (or I could load on or two rows that are not visible to improve scrolling)

    I implemented a quick test with the ListView and a CellFactory:
    package javafxtest.image;
    import java.io.File;
    import java.net.MalformedURLException;
    import java.util.ArrayList;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.ListView;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.image.ImageViewBuilder;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class ImageGallery extends Application {
        @Override
        public void start(Stage primaryStage) {
            ListView<String> imageNames = new ListView<>();
            File dir = new File("/home/andi/Pictures");
            ArrayList<String> list = new ArrayList<>();
            for (File f : dir.listFiles()) {
                try {
                    list.add(f.toURI().toURL().toExternalForm());
                } catch (MalformedURLException ex) {
                    Logger.getLogger(ImageGallery.class.getName()).log(Level.SEVERE, null, ex);
            ObservableList<String> names = FXCollections.observableArrayList(list);
            imageNames.setItems(names);
            imageNames.setCellFactory(new Callback<ListView<String>,
                ListCell<String>>() {
                    @Override
                    public ListCell<String> call(ListView<String> list) {
                        return new ImageListCell();
            StackPane root = new StackPane();
            root.getChildren().add(imageNames);
            Scene scene = new Scene(root, 500, 600);
            primaryStage.setTitle("Image Gallery");
            primaryStage.setScene(scene);
            primaryStage.show();
        public static void main(String[] args) {
            launch(args);
        private static class ImageListCell extends ListCell<String> {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    Image img = new Image(item);
    System.out.println("Update timestamp: "+System.currentTimeMillis()+" load image "+item);
                    ImageView imageView = ImageViewBuilder.create()
                            .image(img).build();
                    setGraphic(imageView);
    }Checking this piece of code with the profiler shows that the memory usage increases constantly the more I scroll through the list. Perhaps I'm missing here something? If the cell would be reused, the GC should be able to collect all the image instances that are no longer visible and thereby keep the memory usage more or less at the same level.
    Taking a look at the memory results, I can see that there are some ImageListCell instances, but the big part of the memory is consumed by byte arrays. I suppose the image data goes into those arrays.

Maybe you are looking for