2012-09-16 94 views
0

以我的經驗CONSTRAINED_RESIZE_POLICY被打破,如果TableView中包含了一些固定寬度的列,除非我在這裏做得不對:JavaFX的2 tableview中實現自定義列調整政策

public class JavaFX2Sandbox extends Application 
{ 
    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    @Override 
    public void start(Stage stage) throws Exception 
    { 
     StackPane root = new StackPane(); 
     root.autosize(); 
     Scene scene = new Scene(root); 

     stage.setScene(scene); 
     stage.show(); 

     configureTable(root); 
    } 

    public static class Person 
    { 
     public Person(String firstName, String lastName) 
     { 
      this.fixedValue = "Dr."; 
      this.firstName = firstName; 
      this.lastName = lastName; 
     } 
     public String fixedValue; 
     public String firstName; 
     public String lastName; 
    } 

    private static class CellValueFactory<T> implements Callback<TableColumn.CellDataFeatures<T, Object>, ObservableValue<Object>> 
    { 
     private String mFieldName; 

     public CellValueFactory(String fieldName) 
     { 
      mFieldName = fieldName; 
     } 

     @Override 
     public ObservableValue call(TableColumn.CellDataFeatures<T, Object> p) 
     { 
      try 
      { 
       if (p == null) 
       { 
        return new SimpleObjectProperty(null); 
       } 
       Object o = p.getValue(); 
       if (o == null) 
       { 
        return new SimpleObjectProperty(null); 
       } 
       Object fieldVal = o.getClass().getField(mFieldName).get(o); 
       if (fieldVal == null) 
       { 
        return new SimpleObjectProperty(null); 
       } 

       return new SimpleObjectProperty(fieldVal); 
      } 
      catch (Exception ex) 
      { 
       return new SimpleObjectProperty(ex); 
      } 
     } 
    } 
    private void configureTable(StackPane root) 
    { 

     TableView<Person> table = new TableView<>(); 
     table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 

     ArrayList<Person> teamMembers = new ArrayList<>(); 
     teamMembers.add(new Person("John", "Big")); 
     teamMembers.add(new Person("Frank", "Small")); 

     TableColumn col0 = new TableColumn("fixed-width"); 
     col0.setResizable(false); 
     col0.setCellValueFactory(new CellValueFactory("fixedValue")); 
     TableColumn col1 = new TableColumn("First Name"); 
     col1.setCellValueFactory(new CellValueFactory("firstName")); 
     TableColumn col2 = new TableColumn("Last Name"); 
     col2.setCellValueFactory(new CellValueFactory("lastName")); 
     table.getColumns().setAll(col0, col1, col2); 
     table.setItems(FXCollections.observableList(teamMembers)); 

     root.getChildren().add(table); 
    } 
} 

於是我開始實現自己的大小調整政策其行爲與CONSTRAINED_RESIZE_POLICY略有不同,但我更喜歡我的:-)。除了列的寬度總和不等於TableView的寬度之外,它都可以。

這裏是我的大小調整策略類的實現:

static class ColumnResizePolicy implements Callback<TableView.ResizeFeatures, Boolean> 
{ 
    double mTVWidth; 

    @Override 
    public Boolean call(ResizeFeatures arg0) 
    { 
     TableView tv = arg0.getTable(); 
     Double tvWidth = tv.widthProperty().getValue(); 
     if (tvWidth == null || tvWidth <= 0.0) 
     { 
      return false; 
     } 

     if (mTVWidth != tvWidth && arg0.getColumn() == null) 
     { 
      mTVWidth = tvWidth; 

      int numColsToSize = 0; 
      double fixedColumnsWidths = 0; 
      for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns())) 
      { 
       if (col.isResizable() && col.isVisible()) 
       { 
        ++numColsToSize; 
       } 
       else if (col.isVisible()) 
       { 
        fixedColumnsWidths += col.getWidth(); 
       } 
      } 

      if (numColsToSize == 0) 
       return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0); 

      TableColumn lastCol = null; 
      for (TableColumn col : new ArrayList<TableColumn>(tv.getColumns())) 
      { 
       if (col.isResizable() && col.isVisible()) 
       { 
        double newWidth = (tvWidth - fixedColumnsWidths)/numColsToSize; 
        col.setPrefWidth(newWidth); 
        lastCol = col; 
       } 
      } 
      if (lastCol != null) 
      { 
       lastCol.setPrefWidth(lastCol.getPrefWidth()-2); 
      } 

      return true; 
     } 
     else 
     { 
      return TableView.UNCONSTRAINED_RESIZE_POLICY.call(arg0); 
     } 
    } 
} 

我的問題(後諷刺的是這個長崗)大約是在這個行號2:

lastCol.setPrefWidth(lastCol.getPrefWidth()-2); 

我假設表格寬度包括邊框在內的外部寬度,因此區別,但是如何獲得內部寬度?

+0

可能相關:http://stackoverflow.com/questions/10716811/tableview中,母鹿s-not-always-resize-the-columns – assylias

回答

0

嘗試下一個:

double borderWidth = table.getBoundsInLocal().getWidth() - table.getWidth() 
+0

謝謝你的想法。不幸的是,table.getBoundsInLocal()返回table.getWidth() - 1(至少在我的情況下)這意味着getBoundsInLocal()不是我尋找的函數,因爲在我的情況下,幻數是2 :-) – bjdodo

+0

多一點,根據你的定義它確實工作。由於borderwidth = table.getBoundsInLocal()。getWidth() - table.getWidth(),它是1,並且有2個邊框,一個在左邊,一個在右邊,我需要將邊框寬度乘以2,所以我'd得到我的神奇數字,2。簡單,但讓我感到不舒服,我希望API以更直接的方式暴露這個寬度。 – bjdodo

0

您是否嘗試過得到佔位符節點的寬度?

+0

謝謝你的回答,不幸的是getPlaceholder()返回null。 – bjdodo

0

我有一個問題相同https://community.oracle.com/message/12334734#12334734 而你的implementing custom column resize policy是幫助我。 謝謝!

您的代碼。

if (col.isResizable() && col.isVisible()) { 
    double newWidth = (tvWidth - fixedColumnsWidths)/numColsToSize; 
    col.setPrefWidth(newWidth); 
    lastCol = col; 
} 

我改變

if (col.isResizable() && col.isVisible()) { 
    double newWidth = (tvWidth - fixedColumnsWidths)*col.getPercentWidth(); 
    col.setPrefWidth(newWidth); 
    lastCol = col; 
} 

隨着col

public class PTableColumn<S, T> extends javafx.scene.control.TableColumn<S, T> 

而且getPercentWidth

private DoubleProperty percentWidth = new SimpleDoubleProperty(1);