This discussion is archived
10 Replies Latest reply: Feb 12, 2013 4:38 AM by edward17 RSS

JavaFX MAC Mystery

edward17 Newbie
Currently Being Moderated
OK, looking for "how the heck do I debug this"

I have a tableview that works fine from Netbeans. But when I package the code, the text does not display in the cells. Standard Strings.
Now I know the data is there, because if I double click on the row it behaves as expected. It's just not showing the text after I have deployed the native package.

Not sure how to even debug this one

I have users describing similar behavior for ListView, but it seems sporadic (meaning not ALL users).
  • 1. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    I feel a little better that it behaves the same on a PC. I hate platform specific issues.

    Still not sure how to attack it though...
  • 2. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    Using standard Cell factories
            nameCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseBean,String>("name"));
            locationCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseBean,String>("location"));
            descrCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseBean,String>("description"));
    public class DatabaseBean implements Comparable{
        private StringProperty dbId = new SimpleStringProperty();
        private StringProperty name = new SimpleStringProperty();
        private StringProperty location = new SimpleStringProperty();
        private StringProperty description = new SimpleStringProperty();
    ...
    
        
        public String getName() {
            return name.getValueSafe();
        }
    ...
    Edited by: edward17 on Feb 8, 2013 6:32 AM
  • 3. Re: JavaFX MAC Mystery
    James_D Guru
    Currently Being Moderated
    Do you have the property-level accessor methods defined in your bean as well? By this I mean
    public class DatabaseBean implements Comparable{
     ...
      public StringProperty nameProperty() {
        return name ;
      }
    ...
    }
    The property value factory will look for methods with these names, and call get() and set() on the returned property. In this case that means the getValueSafe() won't be invoked; however this shouldn't be a problem as TableViews generally handle null values. If you have custom cell factories installed, you may want to make sure these handle null values appropriately.

    If you don't have nameProperty() and its friends installed, then the PropertyValueFactory will fall back on the getName() method. However, it will wrap the result in a ReadOnlyPropertyWrapper (see [url http://docs.oracle.com/javafx/2/api/javafx/scene/control/cell/PropertyValueFactory.html]API docs). This means updates to the property won't be properly observed by the table. I'm going to guess that your DatabaseBean connects to a database. When I create properties that refer to database values, I usually put the calls to a database in a separate thread, and update the property on the FX Application thread when the call is complete. If you use this strategy (and obviously I'm speculating wildly here), and you don't have the nameProperty() method, then whether or not the table sees the correct value is going to depend on how quickly the database call completes in relation to the FX rendering, so errors would appear sporadically.

    So I guess I'd advocate using the nameProperty() method in your DatabaseBean class and taking steps to ensure the TableView handles null values ok.

    Just some ideas... not sure if that's helpful at all.
  • 4. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    DatabaseBean is juts a holder for some parameters about a database connection that need to be displayed in a table (no DB access from it).

    DatabaseBean istelf id NOT a Property - I made the fields WITHIN it Property fileds (SimpleStringProperty)

    Hmm, makes me think, is the issue that DatabaseBean is not Observable?

    But then why would it work exploded (as when called from NetBeans) but not in a jar (as when deployed)
  • 5. Re: JavaFX MAC Mystery
    James_D Guru
    Currently Being Moderated
    OK, so probably not that.

    I guess I'd still ask whether you're exposing the properties, or just the values of the properties? The code snippet you showed shows you exposing the values of the properties. If your DatabaseBean doesn't have a nameProperty() method, I'd try adding it just to see if it made any difference (that's assuming you can reliably reproduce the issue). The point is that if the table somehow got rendered before the property had been set, it wouldn't update correctly without the nameProperty() method. I don't think implementing the DatabaseBean itself as a property would matter.

    I have no idea why it might behave differently under Netbeans than when deployed in a jar: my only conjecture would be that there are threading issues that consistently behave differently in Netbeans to outside of it, but that's already a stretch, and you seem to imply that there aren't any background threads anyway.

    Uh, good luck...
  • 6. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    Thanks, I'll give it a shot
  • 7. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    OK, I refactored the entire DatabaseBean into a SimpleObjectProperty , and while it is a better design, its still doesn't render in a TableView if its packaged. Does fine unpackaged. I wonde rif it could be something with the PropertyValueFactory?

    public final class DatabaseProperty extends SimpleObjectProperty  implements Comparable {
        private StringProperty dbId = new SimpleStringProperty(this, "dbId","");
        private StringProperty fileName = new SimpleStringProperty(this, "fileName","");
        private StringProperty location = new SimpleStringProperty(this, "location","");
        private StringProperty description = new SimpleStringProperty(this, "description","");
    
        public DatabaseProperty() {
        }
    
        public DatabaseProperty(String dbId, String data) {
            String[] arr = data.split("\\|");
            int idx = arr[0].lastIndexOf(File.separator);
            this.fileName.set(arr[0].substring(idx+1));
            this.location.set(arr[0].substring(0,idx+1));
            if(arr.length > 1) {
                this.description.set(arr[1]);
            }
            if(this.dbId.get() != null) {
                this.dbId.set(dbId);
            }
        }
    
        public String getDbId() { return dbId.get(); }
        public void setDbId(String param) { dbId.set(param); }
        public StringProperty dbIdProperty() { return dbId; }
    
        public String getFileName() { return fileName.get(); }
        public void setFileName(String param) { fileName.set(param); }
        public StringProperty fileNameProperty() { return fileName; }
    
        public String getLocation() { return location.get(); }
        public void setLocation (String param) { location.set(param); }
        public StringProperty locationProperty() { return location; }
    
        public String getDescription() { return description.get(); }
        public void setDescription(String param) { description.set(param); }
        public StringProperty descriptionProperty() { return description; }
    ...
    ...
    
            dbIdCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseProperty,String>("dbId"));
            nameCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseProperty,String>("fileName"));
            locationCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseProperty,String>("location"));
            descrCol.setCellValueFactory(
                    new PropertyValueFactory<DatabaseProperty,String>("description"));
    ...
  • 8. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    And oddly enough this works! Guess there is a bug in the PropertyValuefactory

    I wonder if you are NOT supposed to use a Property with a PropertyValueFactory? Is it just for pojos?
            dbIdCol.setCellValueFactory(new Callback<CellDataFeatures<DatabaseProperty, String>, ObservableValue<String>> () {
                @Override
                public ObservableValue<String> call(CellDataFeatures<DatabaseProperty, String> p) {
                    return p.getValue().dbIdProperty();
                }
            });
            nameCol.setCellValueFactory(new Callback<CellDataFeatures<DatabaseProperty, String>, ObservableValue<String>> () {
                @Override
                public ObservableValue<String> call(CellDataFeatures<DatabaseProperty, String> p) {
                    return p.getValue().fileNameProperty();
                }
            });
            locationCol.setCellValueFactory(new Callback<CellDataFeatures<DatabaseProperty, String>, ObservableValue<String>> () {
                @Override
                public ObservableValue<String> call(CellDataFeatures<DatabaseProperty, String> p) {
                    return p.getValue().locationProperty();
                }
            });
            descrCol.setCellValueFactory(new Callback<CellDataFeatures<DatabaseProperty, String>, ObservableValue<String>> () {
                @Override
                public ObservableValue<String> call(CellDataFeatures<DatabaseProperty, String> p) {
                    return p.getValue().descriptionProperty();
                }
            });
  • 9. Re: JavaFX MAC Mystery
    JonathanGiles Journeyer
    Currently Being Moderated
    Sounds like you may have found a bug. This is in my code, so if you could file a 'runtime' / 'controls' bug in Jira that would be much appreciated!.

    Thanks,
    -- Jonathan
  • 10. Re: JavaFX MAC Mystery
    edward17 Newbie
    Currently Being Moderated
    Done

    http://javafx-jira.kenai.com/browse/RT-28350

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points