2014-09-30 39 views
0

我想綁定我的TableView的第二列的寬度與我的TableView的寬度。爲什麼TableColumn的寬度綁定不起作用?

我定製的TableView:

public class CustomTableView<T> extends 
     TableView<ObservableList<Pair<String, Object>>> implements Cloneable { 
    private static Logger logger = Logger.getLogger(CustomTableView.class); 

    private double prefWidth; // optionnel 

    private double minWidth; // optionnel 

    private double maxWidth; // optionnel 

    private double height; // optionnel 

    private List<InfoColumnBean> cols; // optionnel 

    private ObservableList<ObservableList<Pair<String, Object>>> data; // optionnel 

    private boolean withContextMenu; // optionnel 

    private ContextMenu menu; // optionnel 

    private String title; // obligatoire 

    private int titleWidth; // optionnel 

    private Label placeHolder; // optionnel 

    @SuppressWarnings("unchecked") 
    public CustomTableView(CustomTableViewBuilder<T> builder) { 
     super(); 

     // apparence tableau 
     this.prefWidth = builder.prefWidth; 
     this.minWidth = builder.minWidth; 
     this.maxWidth = builder.maxWidth; 

     this.height = builder.height; 

     this.title = builder.title; 
     this.titleWidth = builder.titleWidth; 

     this.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 

     this.getStyleClass().add("tableView"); 

     this.setPrefWidth(prefWidth); 
     this.setMinWidth(minWidth); 
     this.setMaxWidth(maxWidth); 

     this.setPrefHeight(height); 

     this.setEditable(false); 

     DropShadow ds = new DropShadow(); 

     ds.setOffsetY(3.0); 
     ds.setOffsetX(3.0); 
     ds.setColor(Color.DARKGRAY); 

     this.setEffect(ds); 

     this.withContextMenu = builder.withContextMenu; 
     this.menu = builder.menu; 

     this.placeHolder = builder.placeHolder; 

     if (placeHolder != null) 
      this.setPlaceholder(placeHolder); 

     // colonnes du tableau 
     this.cols = builder.cols; 

     if (cols != null) { 
      for (final InfoColumnBean col : cols) { 
       @SuppressWarnings("rawtypes") 
       TableColumn ws_col = null; 

       if (col.isColumnWithImage()) { 
        ws_col = new TableColumn<ObservableList<Pair<String, Object>>, Object>(
          col.getName()); 

        ws_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, Object>, ObservableValue<Object>>() { 
         @SuppressWarnings("rawtypes") 
         public ObservableValue<Object> call(
           TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, Object> data) { 
          Object value = data.getValue().get(col.getIndex()) 
            .getValue(); 
          return (value instanceof ObservableValue) ? (ObservableValue) value 
            : new ReadOnlyObjectWrapper<>(value); 
         } 
        }); 
       } 

       if (!col.isColumnWithImage()) { 
        ws_col = new TableColumn<ObservableList<Pair<String, Object>>, String>(
          col.getName()); 

        if (!col.isColumnWithDecimalsManagement()) 
         ws_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, String>, ObservableValue<String>>() { 
          public ObservableValue<String> call(
            TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, String> data) { 
           return new ReadOnlyObjectWrapper<>(data 
             .getValue().get(col.getIndex()) 
             .getKey()); 
          } 
         }); 
        else { 
         ws_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, String>, ObservableValue<String>>() { 
          public ObservableValue<String> call(
            TableColumn.CellDataFeatures<ObservableList<Pair<String, Object>>, String> data) { 
           // gestion des décimales 
           NumberFormat df = DecimalFormat.getInstance(); 
           df.setMaximumFractionDigits(2); 
           df.setMinimumFractionDigits(2); 

           df.setRoundingMode(RoundingMode.HALF_UP); 

           String ret = df.format(
             Double.parseDouble(data.getValue() 
               .get(col.getIndex()).getKey())) 
             .replace(",", "."); 

           return new ReadOnlyObjectWrapper<>(ret); 
          } 
         }); 
        } 
       } 

       if (col.getId() != null && !col.getId().equals("")) { 
        logger.debug("col_name, id = " + col.getName() + " " 
          + col.getId()); 
        ws_col.setId(col.getId()); 
       } 

       ws_col.setPrefWidth(col.getPrefWidth()); 

       ws_col.setMinWidth(col.getMinWidth()); 

       ws_col.setMaxWidth(col.getMaxWidth()); 

       ws_col.getStyleClass().add(col.getStyle()); 

       ws_col.setResizable(col.isResizable()); 

       ws_col.setSortable(col.isSortable()); 

       if (col.getBindPrefWidthWithTable() > 0) 
        ws_col.prefWidthProperty().bind(
          this.widthProperty().subtract(
            col.getBindPrefWidthWithTable())); 

       this.getColumns().add(ws_col); 
      } 

      logger.debug("cols size = " + this.getColumns().size()); 

      // données 
      this.data = builder.data; 

      if (data != null) { 
       // style lignes 
       refresh(); 

       this.setItems(data); 
       logger.debug("data.size = " + data.size()); 
      } else { 
       ObservableList<ObservableList<Pair<String, Object>>> items = FXCollections 
         .observableArrayList(); 

       this.setItems(items); 
      } 

      // menu contextuel ? 
      final CustomTableView<T> current = this; 

      if (withContextMenu) { 
       this.addEventHandler(MouseEvent.MOUSE_CLICKED, 
         new EventHandler<MouseEvent>() { 
          @Override 
          public void handle(MouseEvent event) { 
           if (event.getButton().equals(
             MouseButton.SECONDARY) 
             && current.getItems().size() > 0) { 
            menu.show(current, event.getScreenX(), 
              event.getScreenY()); 
           } 
          } 
         }); 
      } 
     } 
    } 

    /** 
    * @return titre du contrôle 
    * 
    * @since 0.0.8 
    */ 
    public String getTitle() { 
     return title; 
    } 

    /** 
    * @return longueur titre label 
    * 
    * @since 0.0.8 
    */ 
    public int getTitleWidth() { 
     return titleWidth; 
    } 

    /** 
    * refresh tableView 
    * 
    * @since 0.0.8 
    */ 
    public void refresh() { 
     this.setRowFactory(new Callback<TableView<ObservableList<Pair<String, Object>>>, TableRow<ObservableList<Pair<String, Object>>>>() { 
      @Override 
      public TableRow<ObservableList<Pair<String, Object>>> call(
        TableView<ObservableList<Pair<String, Object>>> tableView) { 
       final TableRow<ObservableList<Pair<String, Object>>> row = new TableRow<ObservableList<Pair<String, Object>>>() { 
        protected void updateItem(
          ObservableList<Pair<String, Object>> pair, 
          boolean empty) { 
         super.updateItem(pair, empty); 

         int idx = getIndex(); 

         if (idx >= 0) { 
          if ((idx % 2) == 0) 
           getStyleClass().add("ligne1"); 
          else 
           getStyleClass().add("ligne2"); 
         } 
        } 
       }; 

       return row; 
      } 
     }); 
    } 

    @Override 
    public CustomTableView<T> clone() throws CloneNotSupportedException { 
     CustomTableView<T> cloneObject = new CustomTableView<T>(); 

     cloneObject.setItems(super.getItems()); 

     return cloneObject; 
    } 

    /** 
    * useful for cloning 
    * 
    * @since 0.0.8 
    */ 
    public CustomTableView() { 
     super(); 
    } 

    /** 
    * 
    * Classe : CustomTableViewBuilder 
    * 
    * paramètres contrôle 
    * 
    * @author fmaupin 
    * 
    * @since 0.0.8 
    * 
    */ 
    public static class CustomTableViewBuilder<T> { 
     private double prefWidth = 200; // optionnel 

     private double minWidth = 200; // optionnel 

     private double maxWidth = 200; // optionnel 

     private double height = 200; // optionnel 

     private List<InfoColumnBean> cols = null; // optionnel 

     private ObservableList<ObservableList<Pair<String, Object>>> data = null; // optionnel 

     private boolean withContextMenu = false; // optionnel 

     private ContextMenu menu = null; // optionnel 

     private String title = ""; // obligatoire 

     private int titleWidth = 0; // optionnel 

     private Label placeHolder = null; // optionnel 

     /** 
     * @param title 
     *   : titre label contrôle 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder(String title) { 
      this.title = title; 
     } 

     /** 
     * 
     * longueur titre contrôle 
     * 
     * @param width 
     *   : longueur titre 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> titleWidth(int width) { 
      this.titleWidth = width; 

      return this; 
     } 

     /** 
     * 
     * placeholder 
     * 
     * @param value 
     *   : message pour placeholder 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> setPlaceHolder(String value) { 
      this.placeHolder = new Label(value); 

      return this; 
     } 

     /** 
     * 
     * largeurs tableau 
     * 
     * @param width 
     *   : toutes largeurs tableau 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> with(double width) { 
      this.prefWidth = width; 
      this.minWidth = width; 
      this.maxWidth = width; 

      return this; 
     } 

     /** 
     * 
     * largeur tableau 
     * 
     * @param width 
     *   : largeur tableau 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> prefWith(double width) { 
      this.prefWidth = width; 

      return this; 
     } 

     /** 
     * 
     * largeur minimale tableau 
     * 
     * @param width 
     *   : largeur tableau 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> minWith(double width) { 
      this.minWidth = width; 

      return this; 
     } 

     /** 
     * 
     * largeur maximale tableau 
     * 
     * @param width 
     *   : largeur tableau 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> maxWith(double width) { 
      this.maxWidth = width; 

      return this; 
     } 

     /** 
     * 
     * hauteur tableau 
     * 
     * @param height 
     *   : hauteur tableau 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> height(double height) { 
      this.height = height; 

      return this; 
     } 

     /** 
     * 
     * ajouter colonne(s) dans tableau 
     * 
     * @param infoColumns 
     *   : informations sur colonnes (nom, index, largeur, largeur 
     *   minimum, largeur maximum, style) 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> addColumns(
       List<InfoColumnBean> infoColumns) { 
      this.cols = infoColumns; 

      return this; 
     } 

     /** 
     * 
     * ajouter données dans tableau 
     * 
     * @param data 
     *   : données à ajouter 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> addDATA(
       ObservableList<ObservableList<Pair<String, Object>>> data) { 
      this.data = data; 

      return this; 
     } 

     /** 
     * 
     * avec menu contextuel ? 
     * 
     * @param menu 
     *   : descriptif menu contextuel 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableViewBuilder<T> withContextMenu(ContextMenu menu) { 
      this.withContextMenu = true; 
      this.menu = menu; 

      return this; 
     } 

     /** 
     * construire contrôle 
     * 
     * @since 0.0.8 
     */ 
     public CustomTableView<T> build() { 
      return new CustomTableView<T>(this); 
     } 
    } 
} 

我的自定義TableView中的初始化(InfoColumns包含列的說明):

mytable = new CustomTableView.CustomTableViewBuilder<ObservableList<Pair<String, Object>>>(
      "") 
      .setPlaceHolder(
        "my message !") 
      .addColumns(infoColumns).prefWith(width * 0.4f) 
      .minWith(TABLEVIEW_WIDTH).maxWith(width).height(height * 0.75) 
      .build(); 

我的綁定:

mytable.getColumns().get(1).prefWidthProperty().bind(mytable.widthProperty().subtract(385)); 

不幸的是它不行 !

如果你有一個想法......

感謝您提前

法布里斯

+0

「這是行不通的」?你有錯誤嗎? – Afsa 2014-09-30 07:11:04

+0

沒有錯誤,沒有什麼:綁定不成立 – IBACK 2014-09-30 08:00:11

回答

0

那麼它不工作,請按照下面的例子:你的意思是你

import javafx.application.Application; 
import javafx.beans.property.ReadOnlyObjectWrapper; 
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.layout.BorderPane; 
import javafx.stage.Stage; 

public class TableViewColumnBind extends Application { 
    @Override 
    public void start(Stage stage) throws Exception { 
     BorderPane borderPane = new BorderPane(); 
     Scene scene = new Scene(borderPane, 500, 500); 
     String cssFile = getClass().getResource("tableviewgridline.css").toExternalForm(); 
     scene.getStylesheets().add(cssFile); 
     stage.setScene(scene); 

     TableView<Integer> table = new TableView<>(); 

     ObservableList<Integer> data = FXCollections.observableArrayList(); 
     for (int i = 0; i < 20; i++) { 
      data.add(i); 
     } 
     table.setItems(data); 

     for (int i = 0; i < 10; i++) { 
      TableColumn<Integer,String> column = new TableColumn<>(Integer.toString(i)); 
      column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().toString())); 
      table.getColumns().add(column); 
     } 

     table.getColumns().get(1).prefWidthProperty().bind(table.widthProperty().subtract(400)); 

     borderPane.setCenter(table); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     Application.launch(args); 
    } 
} 
+0

我有一個類似的來源,它不起作用! – IBACK 2014-09-30 08:07:57

+0

你可以發佈一個支持它的['MCVE'](http://stackoverflow.com/help/mcve)嗎? – ItachiUchiha 2014-09-30 08:36:54

+0

我修改了我的問題的根源。 – IBACK 2014-09-30 08:58:02