3

I found these examples:

http://www.jeasyui.com/tutorial/datagrid/datagrid21.php\

Can a table row expand and close?

Basically I want to create a JavaFX table which I can expand in order to see more data. Is there any similar example written in JavaFX?

Community
  • 1
  • 1
Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • I answered a similar question [here](http://stackoverflow.com/a/20198220/2855515) . It doesn't span, but there's there's code for that as well on the internet. It would be easier to just change the column widths but may not look as good. – brian Jan 14 '14 at 22:02

1 Answers1

0

EDIT

So, after reworking the problem with tableView specifics, I (sort of) quickly hacked together this example. Keep in mind, I didn't use the animation mentioned in the original answer, although it would be easy enough to adapt, and I didn't replicate the provided example exactly at all, since I honestly, didn't have time. But this gives the basic accordion feel, where you would just need to spend time messing around with various width and height properties of different fields to achieve something that was exactly that. (in the handler you might want to even insert a row where the first column has a huge width and a nested table view to achieve sort of exactly what they were doing). again, this is with 1 column, and it shows the basics of adding a bit of added information on expansion, you could take this as far as you want:

fileChooserExample.java: 

package filechooserexample;

import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.*;
import javafx.util.Callback;

public class FileChooserExample extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(final Stage stage) {
    stage.setTitle("People");
//    stage.getIcons().add(new Image("http://icons.iconarchive.com/icons/icons-land/vista-people/72/Historical-Viking-Female-icon.png"));  // icon license: Linkware (Backlink to http://www.icons-land.com required)

    // create a table.
    final TableView<Person> table = new TableView<>(
      FXCollections.observableArrayList(
        new Person("Jacob", "Smith"),
        new Person("Isabella", "Johnson"),
        new Person("Ethan", "Williams"),
        new Person("Emma", "Jones"),
        new Person("Michael", "Brown")
      )
    );

    // define the table columns.

    TableColumn<Person, Boolean> actionCol = new TableColumn<>("Action");
    actionCol.setSortable(false);

     actionCol.setPrefWidth(1000);
    // define a simple boolean cell value for the action column so that the column will only be shown for non-empty rows.
    actionCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person, Boolean>, ObservableValue<Boolean>>() {
      @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Person, Boolean> features) {
        return new SimpleBooleanProperty(features.getValue() != null);
      }
    });

    // create a cell value factory with an add button for each row in the table.
    actionCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, TableCell<Person, Boolean>>() {
      @Override public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> personBooleanTableColumn) {
        return new AddPersonCell(stage, table);
      }
    });

    table.getColumns().setAll(actionCol);
    table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);

    stage.setScene(new Scene(table));
    stage.show();
  }

  /** A table cell containing a button for adding a new person. */
  private class AddPersonCell extends TableCell<Person, Boolean> {
    // a button for adding a new person.
    final Button addButton       = new Button("Add");
    // pads and centers the add button in the cell.
    final VBox paddedButton = new VBox();
    final HBox mainHolder = new HBox();
    // records the y pos of the last button press so that the add person dialog can be shown next to the cell.
    final DoubleProperty buttonY = new SimpleDoubleProperty();

    /**
     * AddPersonCell constructor
     * @param stage the stage in which the table is placed.
     * @param table the table to which a new person can be added.
     */
    AddPersonCell(final Stage stage, final TableView table) {
      paddedButton.setPadding(new Insets(3));
      paddedButton.getChildren().add(addButton);
      mainHolder.getChildren().add(paddedButton);
      addButton.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          buttonY.set(mouseEvent.getScreenY());
          if (getTableRow().getPrefHeight() == 100){
              getTableRow().setPrefHeight(35);
              paddedButton.getChildren().remove(1);
              getTableRow().autosize();
          }
          else{
            getTableRow().setPrefHeight(100);
            Label myLabel = new Label();
            myLabel.setText("This is new label text!");
            myLabel.setTextFill(Color.BLACK);
            paddedButton.getChildren().add(myLabel);
            getTableRow().autosize();
          }
        }
      });
      addButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent actionEvent) {
          table.getSelectionModel().select(getTableRow().getIndex());
        }
      });
    }

    /** places an add button in the row only if the row is not empty. */
    @Override protected void updateItem(Boolean item, boolean empty) {
      super.updateItem(item, empty);
      if (!empty) {
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        setGraphic(paddedButton);
      }
    }
  }


}

Person.java:

package filechooserexample;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Person {
  private StringProperty firstName;
  private StringProperty lastName;

  public Person(String firstName, String lastName) {
    setFirstName(firstName);
    setLastName(lastName);
  }

  public final void setFirstName(String value) { firstNameProperty().set(value); }
  public final void setLastName(String value) { lastNameProperty().set(value); }
  public String getFirstName() { return firstNameProperty().get(); }
  public String getLastName() { return lastNameProperty().get(); }

  public StringProperty firstNameProperty() {
    if (firstName == null) firstName = new SimpleStringProperty(this, "firstName");
    return firstName;
  }
  public StringProperty lastNameProperty() {
    if (lastName == null) lastName = new SimpleStringProperty(this, "lastName");
    return lastName;
  }
}

Again, pardon the seemingly hackery of adding the various buttons with the named columns that do nothing, It just got super busy here so I borrowed the main table structure from :

original SO table dynamic row addition question

Who did a wonderful job of adding additional rows to a table.

again, if this is not at all what you need let me know, and I'll try to help as best I can.

Community
  • 1
  • 1
WillBD
  • 1,919
  • 1
  • 18
  • 26
  • Did you accidentally respond to the wrong question? This seems to have nothing at all to do with TableViews and rows... – James_D Jan 14 '14 at 18:42
  • Not at all, it would be quite straightforward to adapt this to a tableView and allow for the expanding of rows. This is just a higher level version that happens to address the expansion of stages. I'll work on a complete example using tables and post it up as an edit – WillBD Jan 14 '14 at 19:17
  • Can you show us a quick example if you think that this code can be adapted? – Peter Penzov Jan 14 '14 at 19:26
  • As I understand it, the question is about putting additional content into the table row, not really about animating the display of that content (I guess animation would be a nice feature, but it seems to be relatively easy...). Is my interpretation of the question correct? – James_D Jan 14 '14 at 19:28
  • Hmm, I suppose I could have misinterpreted, I thought the trouble he was having was dynamically changing the size of the table row, giving an 'accordian' type expansion when a button was clicked, which is where the motiviation for the above example came, as you would attach that type of animation (with a 0 timer if you didn't care about the animation) to a listener to a button in the cell, or a listener on an imageview, thus giving the needed expansion to allow for the additional content. Perhaps I misunderstood, if I did I'll happily delete my answer :) – WillBD Jan 14 '14 at 19:33
  • @James_D Yes I would like to get this result: http://www.jeasyui.com/tutorial/datagrid/datagrid22_demo.html – Peter Penzov Jan 14 '14 at 19:35
  • In the interest of a lack of confusion, I'll go ahead and delete my asnwer and re-answer with it being table-view specific, since it would make a good sized edit, keep an eye out for it, just got busy at work. – WillBD Jan 14 '14 at 19:42
  • Yes but I don't see data object into the table. – Peter Penzov Jan 14 '14 at 22:05