首页 > 解决方案 > 如何在 JavaFX 中合并 TableView 单元格

问题描述

你好 !

我需要一些帮助,我正在使用 JavaFX 中的 TableView 开发一个项目。我需要合并一些像 screen这样的单元格 。

我已经创建了一个带有 TableView 的 Tab,但是我不知道如何合并这个 TableView 的行。

这是我的代码的一部分(但我不知道我是否真的需要它来合并一些单元格):

CellSpanTableView 类:

public class CellSpanTableView<S> extends TableView<S> {
  public CellSpanTableView() {
    super();
    getStyleClass().add(DEFAULT_STYLE_CLASS);
  }

  public CellSpanTableView(ObservableList<S> items) {
    super(items);
    getStyleClass().add(DEFAULT_STYLE_CLASS);
  }

  // --- Span Model
  private ObjectProperty<SpanModel> spanModel 
        = new SimpleObjectProperty<SpanModel>(this, "spanModel");

  public final ObjectProperty<SpanModel> spanModelProperty() {
    return spanModel;
  }
  public final void setSpanModel(SpanModel value) {
    spanModelProperty().set(value);
  }
  public final SpanModel getSpanModel() {
    return spanModel.get();
  }

  private static final String DEFAULT_STYLE_CLASS = "cell-span-table-view";

  private boolean isFirstRun = true;

  @Override protected void layoutChildren() {
    // ugly hack to enable adding the cell-span.css file to the scenegraph
    // without requiring user intervention
    if (isFirstRun) {
      Scene scene = getScene();
      if (scene != null) {
        ObservableList<String> stylesheets = scene.getStylesheets();
        String cssPath = CellSpanTableView.class.getResource("cell- 
                    span.css").toExternalForm();
        if (! stylesheets.contains(cssPath)) {
          stylesheets.add(cssPath);
          isFirstRun = false;
        }
      }
    }
    super.layoutChildren();
  }
}

细胞跨度类:

public final class CellSpan {
  private final int rowSpan;
  private final int columnSpan;

  public CellSpan(int rowSpan, int columnSpan) {
    this.rowSpan = rowSpan;
    this.columnSpan = columnSpan;
  }
  public int getRowSpan() {
    return rowSpan;
  }
  public int getColumnSpan() {
    return columnSpan;
  }

  @Override public String toString() {
    return "CellSpan: [ rowSpan: " + rowSpan + ", columnSpan: " + columnSpan + " ] ";
  }
}

跨度模型类:

public interface SpanModel {
  public CellSpan getCellSpanAt(int rowIndex, int columnIndex);

  public boolean isCellSpanEnabled();
}

以及构建选项卡的主要类:

//Build the tab
private void buildTab(Tab tab) {
  BorderPane borderpane = buildBorderPane(tab);
  CellSpanTableView tableView = (CellSpanTableView) buildBasicTableView(true);
  borderpane.setCenter(tableView);
  //Install the span model
  tableView.setSpanModel(new SpanModel() {
    private final CellSpan spanTwoRows = new CellSpan(2, 1);
    @Override public CellSpan getCellSpanAt(int rowIndex, int columnIndex) {
      return rowIndex % 3 == 0 && columnIndex == 1 ? spanTwoRows : null;
    }
    @Override public boolean isCellSpanEnabled() {
      return true;
    }
  });
}

//Build the borderpane
private BorderPane buildBorderPane(Tab tab) {
  BorderPane borderpane = new BorderPane();
  borderpane.setPadding(new Insets(10, 10, 10, 10));
  tab.setContent(borderpane);
  return borderpane;
}

//Build the tableview
private TableView buildBasicTableView(boolean enableCellSpan) {
  //Column Section
  TableColumn<Row, String> columnSections = new TableColumn<Row, String>("Sections");
  columnSections.setPrefWidth(120);
  columnSections.setCellValueFactory(new PropertyValueFactory<Row, String>("section"));
  columnSections.setCellFactory(column -> EditCell.createStringEditCell());
  columnSections.setOnEditCommit(
    new EventHandler<TableColumn.CellEditEvent<Row, String>>() {
    @Override public void handle(TableColumn.CellEditEvent<Row, String> string) {
      ((Row)string.getTableView().getItems().get(string.getTablePosition().getRow())).setSection(string.getNewValue());
    }
  });

  //Column Item
  TableColumn<Row, String> columnItems = new TableColumn<Row, String>("Items");
  columnItems.setPrefWidth(120);
  columnItems.setCellValueFactory(new PropertyValueFactory<Row, String>("item"));
  columnItems.setCellFactory(column -> EditCell.createStringEditCell());
  columnItems.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Row, String>>() {
    @Override public void handle(TableColumn.CellEditEvent<Row, String> string) {
      ((Row)string.getTableView().getItems().get(string.getTablePosition().getRow())).setItem(string.getNewValue());
    }
  });

  //Column level
  TableColumn<Row, String> columnLevels = new TableColumn<Row, String>("Niveaux");
  columnLevels.setPrefWidth(120);
c  olumnLevels.setCellValueFactory(new PropertyValueFactory<Row, String>("level"));
  columnLevels.setCellFactory(column -> EditCell.createStringEditCell());
  columnLevels.setOnEditCommit(
  new EventHandler<TableColumn.CellEditEvent<Row, String>>() {
    @Override public void handle(TableColumn.CellEditEvent<Row, String> string) {
      ((Row)string.getTableView().getItems().get(string.getTablePosition().getRow())).setLevel(string.getNewValue());
    }
  });

  //Create a TableView
  TableView<Row> tableView = enableCellSpan ? new CellSpanTableView<Row>() : new TableView<Row>();
  tableView.getColumns().addAll(columnSections, columnItems, columnLevels);

  // insert the test data
  tableView.setItems(FXCollections.observableArrayList(
    new Row("section 1", "item 1", "level 1"),
    new Row("section 2", "item 2", "level 2"),
    new Row("section 3", "item 3", "level 3")
  ));

  // for exploration, we enable single cell selection mode, and also print out
  // some debug output to show the currently selected table position
  final TableView.TableViewSelectionModel<Row> sm = tableView.getSelectionModel();
  sm.getSelectedCells().addListener(new ListChangeListener<TablePosition>() {
    @Override public void onChanged(Change<? extends TablePosition> change) {
      if (sm.getSelectedCells().isEmpty()) {
        System.out.println("No selection");
      } else {
        TablePosition tp = sm.getSelectedCells().get(0);
        if (tp == null) return;
        System.out.println("Selection: [ row: " + tp.getRow() + 
               ", column: " + tp.getColumn() + 
               ", column name: " + tp.getTableColumn().getText() + " ] ");
      }
    }
  });
  return tableView;
}
public static void main(String[] args) {
  launch(args);
}

最好的问候, 阿达维

标签: javajavafxtabstableview

解决方案


推荐阅读