Can't populate a TableView with Jruby/Jrubyfx

47 views Asked by At

I'm trying to make a Jruby app with a TableView but I haven't been able to populate the table with data or even find some sample code to do so. Here's the relevant part of my fxml:

<TableView prefHeight="400.0" prefWidth="200.0" id="table">
  <columns>
    <TableColumn prefWidth="75.0" text="name">
      <cellValueFactory>
        <PropertyValueFactory property="name" />
      </cellValueFactory>
    </TableColumn>
    <TableColumn prefWidth="75.0" text="address">
      <cellValueFactory>
        <PropertyValueFactory property="address" />
      </cellValueFactory>
    </TableColumn>
  </columns>
</TableView>

And here's the relevant ruby code:

class Person
  attr_accessor :name, :address

  def initialize
    @name = 'foo'
    @address = 'bar'
  end
end

class HelloWorldApp < JRubyFX::Application
  def start(stage)
    with(stage, title: "Hello World!", width: 800, height: 600) do
      fxml HelloWorldController
      @data = observable_array_list
      @data.add Person.new
      stage['#table'].set_items @data
      show
    end
  end
end

Can someone suggest what I'm doing wrong or point me to a working sample code?

1

There are 1 answers

1
byteit101 On BEST ANSWER

See the contrib/fxmltableview sample; I think that is exactly what you want to do. The issue you are running into is the fact that PropertyValueFactory is a Java class, and it is trying to access a Person which is a JRuby class. By default this won't work as this question shows, but you can easily fix that by calling Person.become_java!. However, even if you do that, it won't work as the PropertyValueFactory expects getter methods of the form [javatype] get[PropertyName]() whereas attr_accessor only generates getter methods of the form [rubytype] [propertyname](). To solve this, use fxml_accessor instead, which generates the proper methods (but doesn't use @ vars, those are the raw property instances):

class Person
  include JRubyFX # gain access to fxml_accessor
  # must specify type as the concrete `Property` implementation
  fxml_accessor :name, SimpleStringProperty
  fxml_accessor :address, SimpleStringProperty

  def initialize
    # note use of self to call the method Person#name= instead of creating local variable
    self.name = 'foo'
    self.address = 'bar'
    # could also technically use @address.setValue('bar'), but that isn't as rubyish
  end
end

# become_java! is needed whenever you pass JRuby objects to java classes 
# that try to call methods on them, such as this case. If you used your own 
# cellValueFactory, this probably would not be necessary on person, but still
# needed on your CVF
Person.become_java!