【问题标题】:JavaFX 2 Automatic Column WidthJavaFX 2 自动列宽
【发布时间】:2012-04-26 12:37:11
【问题描述】:

我有一个显示联系人详细信息的 JavaFX 2 表,假设有三列:名字、姓氏和电子邮件地址。当我的应用程序启动时,它会在表格中填充几行关于系统中已有人员的数据。

问题是列宽都是一样的。大多数情况下,名字和姓氏会完整显示,但电子邮件地址会被截断。用户可以双击标题中的分隔线来调整列的大小,但这很快就会变得乏味。

一旦表格被预先填充,我想以编程方式调整所有列的大小以显示它们包含的数据,但我不知道如何实现这一点。我可以看到我可以打电话给col.setPrefWidth(x),但这并没有真正的帮助,因为我必须猜测宽度。

【问题讨论】:

    标签: javafx-2


    【解决方案1】:

    如果您的总列数是已知的。您可以在 tableview 的宽度中分配列宽:

    nameCol.prefWidthProperty().bind(personTable.widthProperty().divide(4)); // w * 1/4
    surnameCol.prefWidthProperty().bind(personTable.widthProperty().divide(2)); // w * 1/2
    emailCol.prefWidthProperty().bind(personTable.widthProperty().divide(4)); // w * 1/4
    

    在这段代码中,当 tableview 调整大小时,列的宽度比例保持同步,所以你不需要手动做。 surnameCol 也占据了 tableview 宽度的一半。

    【讨论】:

      【解决方案2】:

      这在 JavaFX 8 中适用于我

      table.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY );
      col1.setMaxWidth( 1f * Integer.MAX_VALUE * 50 ); // 50% width
      col2.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
      col3.setMaxWidth( 1f * Integer.MAX_VALUE * 20 ); // 20% width
      

      在您遇到问题的其他示例中,垂直滚动条宽度被忽略。

      【讨论】:

      • 您在哪里看到可以将百分比传递给 setMaxWidth ?
      • 聪明的技巧 - 足够大的数字,因此需要按比例缩小尺寸以适应实际尺寸。
      • 谢谢,现在使用你的技术。我仍然面临垂直滚动条宽度的问题。当添加了足够多的项目后,垂直滚动条立即出现,导致表头和行的垂直 TableView 行之间出现一点偏移。我可以通过刷新 TableView 来解决这个问题:myTableView.setItems(myObservableList); 之后通过访问应用程序线程来刷新 GUI(图形用户界面):第 1 行:Platform.runLater(new Runnable() { 第 2 行:@Override public void run() { 第 3 行:@987654325 @line#4:}});
      【解决方案3】:

      当我使用 SceneBuider 时,我只是将 MinWidth 和 MaxWidth 定义到某些列和主列,我只是将 PrefWidth 定义为“USE_COMPUTED_SIZE”

      【讨论】:

      • 这个程序化版本只是col.setPrefWidth(Control.USE_COMPUTED_SIZE);
      【解决方案4】:

      3年后,终于找到了解决办法,javafx column in tableview auto fit size

      import com.sun.javafx.scene.control.skin.TableViewSkin;
      import javafx.scene.control.Skin;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      
      public class GUIUtils {
          private static Method columnToFitMethod;
      
          static {
              try {
                  columnToFitMethod = TableViewSkin.class.getDeclaredMethod("resizeColumnToFitContent", TableColumn.class, int.class);
                  columnToFitMethod.setAccessible(true);
              } catch (NoSuchMethodException e) {
                  e.printStackTrace();
              }
          }
      
          public static void autoFitTable(TableView tableView) {
              tableView.getItems().addListener(new ListChangeListener<Object>() {
                  @Override
                  public void onChanged(Change<?> c) {
                      for (Object column : tableView.getColumns()) {
                          try {
                              columnToFitMethod.invoke(tableView.getSkin(), column, -1);
                          } catch (IllegalAccessException | InvocationTargetException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              });
          }
      }
      

      【讨论】:

      • 我找不到或导入 TableViewSkin 类。我正在使用 Java 8,但这个类似乎不存在。
      • 它已经不存在了,这个解决方案不能与较新的JAVA版本一起使用。请看:stackoverflow.com/questions/50583912/…
      • @MindaugasBernatavičius 好久没开发JavaFX了,但是去掉那个方法后,是不是可以双击列分隔符自动适应,如果可以,我们可以找到triggerred的方法
      【解决方案5】:

      如果您有 4 列,并且只有最后一列需要扩展以填充表格的其余部分宽度,并且其他列保持我在 Scene Builder 中设置的大小。

      double width = col1.widthProperty().get();
      width += col2.widthProperty().get();
      width += col3.widthProperty().get();
      
      col4.prefWidthProperty().bind(table.widthProperty().subtract(width));
      

      或者,如果您有 2 列需要扩展。

      double width = col1.widthProperty().get();
      width += col3.widthProperty().get();
      
      col2.prefWidthProperty().bind(table.widthProperty().subtract(width).divide(2));
      col4.prefWidthProperty().bind(table.widthProperty().subtract(width).divide(2));
      

      【讨论】:

        【解决方案6】:

        要通用宽度并使用任意数字并确保宽度为表格宽度的 100%,您可以使用:

        double[] widths = {20, 30, 50, 20, 30, 70, 50};//define the width of the columns
        
        //calculate the sum of the width
        double sum = 0;
        for (double i : widths) {
            sum += i;
        }
        
        //set the width to the columns
        for (int i = 0; i < widths.length; i++) {
            table.getColumns().get(i).prefWidthProperty().bind(
                    table.widthProperty().multiply(sizes[i] / sum));
            //---------The exact width-------------^-------------^
        }
        

        【讨论】:

          【解决方案7】:

          另外,一个基于AnchorPane 的非常简单的技巧将是一个很好的解决方案。

          我们要将TableView 包装成AnchorPane,但我们还要像这样锚定TableView 的左侧和右侧:

          AnchorPane wrapper = new AnchorPane();
          
          AnchorPane.setRightAnchor(table, 10.0);
          AnchorPane.setLeftAnchor(table, 10.0);
          wrapper.getChildren().add(table);
          

          这个简单的代码还将在两个方向(左右)拉伸TableView,它会在添加滚动条时进行调整。

          观看此动画 gif,您可以了解其工作原理。

          现在您可以调整列的大小,添加以下行:

          fnColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
          lnColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 40 ); // 40% width
          emColumn.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
          

          【讨论】:

            【解决方案8】:

            我的想法。

            table.getColumns().add(new TableColumn<>("Num") {
                {
                    // 15%
                    prefWidthProperty().bind(table.widthProperty().multiply(0.15));
                }
            });
            table.getColumns().add(new TableColumn<>("Filename") {{
                // 20%
                prefWidthProperty().bind(table.widthProperty().multiply(.2));
            }});
            table.getColumns().add(new TableColumn<>("Path") {{
                // 50%
                prefWidthProperty().bind(table.widthProperty().multiply(.5));
            }});
            table.getColumns().add(new TableColumn<>("Status") {
                {
                    // 15%
                    prefWidthProperty().bind(table.widthProperty().multiply(.15));
                }
            });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-01-04
              • 2010-11-18
              相关资源
              最近更新 更多