2017-10-04 6 views
1

Mon problème est que j'ai deux barres de défilement horizontales que je veux les faire défiler à l'unisson et j'ai essayé d'utiliser:Synchroniser deux barres de défilement JavaFX

bar1.valueProperty().bindBidirectional(bar2.valueProperty());

Le problème est que je remarque bar1 « s La valeur maximale est 1.0 tandis que la valeur maximale de bar2 est 102.5. Par conséquent, le problème, lorsque je fais défiler bar2, bar1 se déplace beaucoup en raison de la grande différence dans leur valeur. J'ai essayé d'utiliser setMin, setMax, setUnitIncrement, setBlockIncrement avant de lier la propriété value. Mais ça ne marche pas.

public class DynamicTableView extends Application { 
    private Scene scene; 
    private VBox root; 
    private ScrollPane scPane; 
    private static final int N_COLS = 10; 
    private static final int N_ROWS = 10; 
    private Button button; 

    public void start(Stage stage) throws Exception { 

     root = new VBox(); 
     scPane = new ScrollPane(); 
     Label lbl = new Label("Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table Dynamic Table"); 
     scPane.setContent(lbl); 

     root.getChildren().add(scPane); 

     TestDataGenerator dataGenerator = new TestDataGenerator(); 

     TableView<ObservableList<String>> tableView = new TableView<>(); 

     // add columns 
     List<String> columnNames = dataGenerator.getNext(N_COLS); 
     for (int i = 0; i < columnNames.size(); i++) { 
      final int finalIdx = i; 
      TableColumn<ObservableList<String>, String> column = new TableColumn<>(
        columnNames.get(i) 
      ); 
      column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().get(finalIdx))); 
      tableView.getColumns().add(column); 
     } 

     // add data 
     for (int i = 0; i < N_ROWS; i++) { 
      tableView.getItems().add(
        FXCollections.observableArrayList(
          dataGenerator.getNext(N_COLS) 
        ) 
      ); 
     } 

     root.getChildren().add(tableView); 

     tableView.setPrefHeight(200); 

     button = new Button("Delete"); 
     button.setOnAction(event -> { tableView.getItems().clear();}); 

     root.getChildren().add(button); 

     Scene scene = new Scene(root, 600, 600); 
     stage.setScene(scene); 
     stage.show(); 

     for(Node node1: scPane.lookupAll(".scroll-bar")) 
     { 
      if(node1 instanceof ScrollBar) 
      { 
       ScrollBar scrollBar1 = (ScrollBar)node1; 
       if(scrollBar1.getOrientation() == Orientation.HORIZONTAL) 
       { 
        for(Node node2: tableView.lookupAll(".scroll-bar")) 
        { 
         if(node2 instanceof ScrollBar) 
         { 
          ScrollBar scrollBar2 = (ScrollBar)node2; 
          if(scrollBar2.getOrientation() == Orientation.HORIZONTAL) 
          { 
           scrollBar2.valueProperty().bindBidirectional(scrollBar1.valueProperty()); 
           break; 
          } 
         } 
        } 
       } 
      } 
     } 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    private static class TestDataGenerator { 
     private static final String[] LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempus cursus diam ac blandit. Ut ultrices lacus et mattis laoreet. Morbi vehicula tincidunt eros lobortis varius. Nam quis tortor commodo, vehicula ante vitae, sagittis enim. Vivamus mollis placerat leo non pellentesque. Nam blandit, odio quis facilisis posuere, mauris elit tincidunt ante, ut eleifend augue neque dictum diam. Curabitur sed lacus eget dolor laoreet cursus ut cursus elit. Phasellus quis interdum lorem, eget efficitur enim. Curabitur commodo, est ut scelerisque aliquet, urna velit tincidunt massa, tristique varius mi neque et velit. In condimentum quis nisi et ultricies. Nunc posuere felis a velit dictum suscipit ac non nisl. Pellentesque eleifend, purus vel consequat facilisis, sapien lacus rutrum eros, quis finibus lacus magna eget est. Nullam eros nisl, sodales et luctus at, lobortis at sem.".split(" "); 

     private int curWord = 0; 

     List<String> getNext(int nWords) { 
      List<String> words = new ArrayList<>(); 

      for (int i = 0; i < nWords; i++) { 
       if (curWord == Integer.MAX_VALUE) { 
        curWord = 0; 
       } 

       words.add(LOREM[curWord % LOREM.length]); 
       curWord++; 
      } 

      return words; 
     } 
    } 
} 
+1

s'il vous plaît donner un exemple runnable qui illustre le problème (voir https://stackoverflow.com/help/how-to-ask) – kleopatra

+1

Voir aussi « comment créer un [MCVE] ". –

+0

ressemble à la mise à l'échelle est différente: dans scrollPane, il est normalisé à max = 1.0 tandis que dans tableView, ce sont les pixels bruts. Bizarrement, la valeur peut être définie sur n'importe quelle valeur ... mais réinitialisée sur le défilement réel: donc si vous faites défiler la table, le volet est immédiatement à sa limite supérieure (1.0) et si vous faites défiler le volet, la table est immédiatement à son limite inférieure (très proche de 0,0) – kleopatra

Répondre

1

Bidi-liaison de valueProperty d'une barre de défilement dans un scrollpane à celle d'une barre de défilement dans un tableView n'est pas possible parce que le premier est normalisé alors que celui-ci n'est pas. Au lieu de cela, écouter les changements et l'échelle manuellement, comme:

protected void bindScrollBarValues(ScrollBar scrollBarInTable, ScrollBar scrollBarInPane) { 
    // can't use bidi-binding because bar in scrollPane is normalized, bar in table is not 
    // scrollBarInTable.valueProperty().bindBidirectional(scrollBarInPane.valueProperty()); 
    // scale manually 
    scrollBarInTable.valueProperty().addListener((src, ov, nv) -> { 
     double tableMax = scrollBarInTable.getMax(); 
     scrollBarInPane.setValue(nv.doubleValue()/tableMax); 
    }); 

    scrollBarInPane.valueProperty().addListener((src, ov, nv) -> { 
     double tableMax = scrollBarInTable.getMax(); 
     scrollBarInTable.setValue(nv.doubleValue() * tableMax); 
    }); 
}