JavaFX tableview可调整大小和可调整大小的列

时间:2014-09-06 14:04:38

标签: java javafx resize width tableview

我有一个TableView,在这个TableView中,有5列。其中一列只包含TableView中的行号,它只是计算它们。我想要实现以下行为:

  1. 数字列的宽度应符合其内容
  2. 号码列不得调整大小
  3. 其他列应可调整大小
  4. 其他列可以并且应该在它们太长时截断它们的内容,以便它们适合TableView的区域而不会看到水平滚动条
  5. 我有5个TableView列,我这样创建:

    TableColumn numberColumn = new TableColumn("#");
    numberColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Vocable, String>, ObservableValue<String>>() {
        @Override
        public ObservableValue<String> call(TableColumn.CellDataFeatures<Vocable, String> vocableCellDataFeature) {
            return new ReadOnlyObjectWrapper(getItems().indexOf(vocableCellDataFeature.getValue()) + "");
        }
    });
    numberColumn.setResizable(false);
    //numberColumn.setMaxWidth(numberColumn.getMaxWidth()-20);
    
    TableColumn<Vocable, String> firstLanguageColumn = new TableColumn<>(Settings.FIRST_LANGUAGE);
    firstLanguageColumn.setCellValueFactory(new PropertyValueFactory<>("firstLanguageTranslationsAsString"));
    firstLanguageColumn.setMinWidth(100);
    
    TableColumn<Vocable, String> firstLanguagePhoneticScriptColumn = new TableColumn<>(Settings.FIRST_LANGUAGE_PHONETIC_SCRIPT);
    firstLanguagePhoneticScriptColumn.setCellValueFactory(new PropertyValueFactory<>("firstLanguagePhoneticScriptsAsString"));
    firstLanguagePhoneticScriptColumn.setMinWidth(100);
    
    TableColumn<Vocable, String> secondLanguagePhoneticScriptColumn = new TableColumn<>(Settings.SECOND_LANGUAGE_PHONETIC_SCRIPT);
    secondLanguagePhoneticScriptColumn.setCellValueFactory(new PropertyValueFactory<>("secondLanguagePhoneticScriptsAsString"));
    secondLanguagePhoneticScriptColumn.setMinWidth(100);
    
    TableColumn<Vocable, String> secondLanguageColumn = new TableColumn<>(Settings.SECOND_LANGUAGE);
    secondLanguageColumn.setCellValueFactory(new PropertyValueFactory<>("secondLanguageTranslationsAsString"));
    secondLanguageColumn.setMinWidth(100);
    
    getColumns().add(numberColumn);
    getColumns().add(firstLanguageColumn);
    getColumns().add(firstLanguagePhoneticScriptColumn);
    getColumns().add(secondLanguagePhoneticScriptColumn);
    getColumns().add(secondLanguageColumn);
    
    getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    

    所以我的问题是:如何在JavaFX TableView中实现这种行为?有可能吗?

1 个答案:

答案 0 :(得分:0)

将列max和min宽度绑定到TableView宽度的一小部分。使分数加起来为1

    ?Col.maxWidthProperty().bind(tableView.widthProperty().multiply(.25));
    ?Col.minWidthProperty().bind(amountCol.maxWidthProperty());

你应该真的做这样的事情

    ?Col.minWidthProperty().bind(tableView.widthProperty().subtract(20).multiply(.25));

除了导致错误。它说A bound value cannot be set.但这不正确,因为它只有减法问题导致&lt; 0。 .subtract(-10)工作正常,但不是你想要的。

某处的绑定必定存在错误。

编辑:如果您调整大于表格的列的大小,那么您将获得一个滚动条。因此,当一个人变大,其他人必须变小。当所有列都改变了一些百分比时,我觉得这很烦人,但也许这样可以接受。

import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

public class TableTest extends Application {

    @Override
    public void start(Stage stage) {
        ObservableList<LineItem> items = FXCollections.observableArrayList();
        items.addAll(new LineItem(1,"string1","string2",123.45),
                     new LineItem(1,"string1","string2",123.45),
                     new LineItem(1,"string1","string2",123.45));

        TableView<LineItem> tableView = new TableView<>(items);

        TableColumn<LineItem,String> numCol = new TableColumn<>("num");
        TableColumn<LineItem,String> descCol = new TableColumn<>("desc");
        TableColumn<LineItem,String> nameCol = new TableColumn<>("name");
        TableColumn<LineItem, Double> amountCol = new TableColumn<>("amount");

        numCol.setCellValueFactory(new PropertyValueFactory<>("num"));
        descCol.setCellValueFactory(new PropertyValueFactory<>("desc"));
        nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
        amountCol.setCellValueFactory(new PropertyValueFactory<>("amount"));

        tableView.getColumns().addAll(numCol,descCol,nameCol,amountCol);

        //col width logic, or lack thereof
        numCol.setPrefWidth(20);
        numCol.setResizable(false);
        tableView.setColumnResizePolicy((TableView.ResizeFeatures param) -> {
            if (param.getColumn() == null )return false;
            double delta = param.getDelta();
            ObservableList<TableColumn> cols = param.getTable().getColumns();
            int colIdx = cols.indexOf(param.getColumn());
            param.getColumn().setMinWidth(param.getColumn().getWidth() + delta);
            param.getColumn().setMaxWidth(param.getColumn().getWidth() + delta);
            if (colIdx < cols.size() -1){
                cols.get(colIdx+1).setMinWidth(cols.get(colIdx+1).getWidth() - delta);
                cols.get(colIdx+1).setMaxWidth(cols.get(colIdx+1).getWidth() - delta);
            } else {
                stage.setWidth(stage.getWidth() + delta);
            }
            return true;
        });

        Scene scene = new Scene(tableView);
        stage.setScene(scene);
        stage.show();
    }


    public class LineItem {

        private final SimpleIntegerProperty num = new SimpleIntegerProperty();
        private final SimpleStringProperty desc = new SimpleStringProperty();
        private final SimpleStringProperty name = new SimpleStringProperty();
        private final SimpleDoubleProperty amount = new SimpleDoubleProperty();

        public SimpleIntegerProperty numProperty() {return num;}
        public SimpleStringProperty descProperty() {return desc;}
        public SimpleStringProperty nameProperty() {return name;}
        public SimpleDoubleProperty amountProperty() {return amount;}

        public LineItem(int num, String desc, String name, double amount) {
            this.num.set(num); 
            this.desc.set(desc);
            this.name.set(name);
            this.amount.set(amount);
        }
    }
}