【问题标题】:JavaFX tableview resizeable and unresizeable columnJavaFX tableview 可调整大小和不可调整大小的列
【发布时间】:2014-10-31 07:19:12
【问题描述】:

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

  1. 数字列应具有适合其内容的宽度
  2. 数字列不可调整大小
  3. 其他列应可调整大小
  4. 其他列可以并且应该在内容过长时截断其内容,以便它们适合 TableView 的区域并且不可见水平滚动条

我有 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 中实现这种行为?有可能吗?

【问题讨论】:

    标签: java javafx resize width tableview


    【解决方案1】:

    将列的最大和最小宽度绑定到 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.,但这不是真的,因为它只有减法问题导致.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);
            }
        }
    }
    

    【讨论】:

    • 有趣,我不知道我也可以绑定这些属性!这至少对其他(可调整大小的)宽度有帮助。但是,当我调整应用程序窗口的大小时,此解决方案会导致调整表列的大小。我想以某种方式拥有它,由于内容的原因,它只占用所需的空间,并且从不调整大小。这可能吗?
    • 也许你想要类似 [this. ] (docs.oracle.com/javafx/2/api/javafx/scene/control/…) 。但列不会调整大小。也许您需要一些自定义行为,如果是这样,我认为这是另一个问题。
    • 这将使它们都无法调整大小。我正在寻找一些东西来使 numberColumn 不可调整大小但让其他的可调整大小 - 我知道,非常特别 ;)
    • 这是可行的,问题是调整表格大小或调整其他列的大小以填充空间,这样您就不会得到滚动条。我建议在 columnWidthProperty 上安装一个监听器。我使用这样的一个程序,我讨厌它,所有其他列都会在你不期望的时候调整大小。
    • “当你不期望他们[调整大小]”是什么意思?如果一列始终具有相同的宽度,而另一列像往常一样调整大小,那么意想不到的事情发生在哪里?对我来说,这似乎是相反的:数字列自动调整大小以使数字不完全可见似乎很奇怪,因为您希望应用程序知道必要的宽度,因为它知道行数。此外,数字列不太可能变得很宽,那么为什么要调整它的大小呢? - 我误解了你的评论吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2013-01-17
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多