2017-12-17 3 views
2

Ich versuche, eine benutzerdefinierte Größenänderungsrichtlinie zu schreiben, die wie TableView.CONSTRAINED_RESIZE_POLICY funktioniert, indem sie die Gesamtbreite aller sichtbaren Spalten auf die gesamte verfügbare Breite in der Tabelle einstellt , so dass die horizontale Bildlaufleiste erscheint nie.Wie verteilt man die Gesamtbreite auf alle Spalten in der Tabellenkonstruktion? "

ich die Linie double widthAvailable = table.getWidth() - getScrollbarWidth(table); bin mit dazu, um zu versuchen zu tun (vollständigem Code siehe unten).

Leider scheint diese Berechnung 4 zu viele zurückzukehren. Meine Vermutung ist, dass es etwas anderes gibt, das ich auch von der Tabellenbreite subtrahieren sollte, die ich vermisse, die im standardmäßigen JavaFX-Theme 4 Pixel breit ist

Hier ist ein komplettes Programm demonstriert das Problem:

package net.joshuad.hypnos.test; 

import java.util.List; 
import java.util.Locale; 
import java.util.Set; 

import javafx.application.Application; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.collections.FXCollections; 
import javafx.geometry.Orientation; 
import javafx.scene.Node; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.ScrollBar; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class CustomResizeExample extends Application { 

    @SuppressWarnings("unchecked") 
    private Parent getContent() { 
     TableView <Locale> table = new TableView <>(FXCollections.observableArrayList(Locale.getAvailableLocales())); 
     TableColumn <Locale, String> countryCode = new TableColumn <>("CountryCode"); 
     countryCode.setCellValueFactory(new PropertyValueFactory <>("country")); 
     TableColumn <Locale, String> language = new TableColumn <>("Language"); 
     language.setCellValueFactory(new PropertyValueFactory <>("language")); 
     table.getColumns().addAll(countryCode, language); 

     TableColumn <Locale, Locale> local = new TableColumn <>("Locale"); 
     local.setCellValueFactory(c -> new SimpleObjectProperty <>(c.getValue())); 

     table.getColumns().addAll(local); 
     table.setColumnResizePolicy(new CustomResizePolicy()); 

     BorderPane pane = new BorderPane(table); 
     return pane; 
    } 
    @Override 
    public void start (Stage stage) throws Exception { 
     stage.setScene(new Scene(getContent(), 800, 400)); 
     stage.show(); 
    } 

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

} 

@SuppressWarnings ("rawtypes") 
class CustomResizePolicy implements Callback <TableView.ResizeFeatures, Boolean> { 

    @SuppressWarnings("unchecked") 
    @Override 
    public Boolean call (TableView.ResizeFeatures feature) { 

     TableView table = feature.getTable(); 
     List <TableColumn> columns = table.getVisibleLeafColumns(); 
     double widthAvailable = table.getWidth() - getScrollbarWidth (table); 


     double forEachColumn = widthAvailable/columns.size(); 

     for (TableColumn column : columns) { 
      column.setMinWidth(forEachColumn); 
      column.setMaxWidth(forEachColumn); 
     } 

     return true; 

    } 

    private double getScrollbarWidth (TableView table) { 
     double scrollBarWidth = 0; 
     Set <Node> nodes = table.lookupAll(".scroll-bar"); 
     for (final Node node : nodes) { 
      if (node instanceof ScrollBar) { 
       ScrollBar sb = (ScrollBar) node; 
       if (sb.getOrientation() == Orientation.VERTICAL) { 
        if (sb.isVisible()) { 
         scrollBarWidth = sb.getWidth(); 
        } 
       } 
      } 
     } 

     return scrollBarWidth; 
    } 
} 

Sehen Sie, wie die Tabelle ist ein wenig breiter als es sein sollte? Ich möchte in der Lage sein, die Breite der Spalten so festzulegen, dass keine horizontale Bildlaufleiste angezeigt wird.

enter image description here

+0

Was ist 'sb.getWidth() + sb.'? – user1803551

+0

'sb.getWidth()' ist die gesamte Breite. Poste ein [MCVE]. – user1803551

+0

@ user1803551: Ein Tippfehler von mir versucht für Lösungen. Entfernt. – JoshuaD

Antwort

2

Scenic View ist ein nützliches Werkzeug, mit vertraut zu machen. Es gibt Ihnen viele Details zum Szenendiagramm. Der Raum Sie suchen, ist clipped-container:

enter image description here

enter image description here

Beachten Sie, dass eine CustomResizePolicy die Art und Weise Einstellung haben Sie effektiv nicht Spalten der Größe verändert werden lässt, da sie immer einen gleichen Anteil der verfügbaren zugeordnet sind Raum. Hier

ist die Berechnung, die Sie wahrscheinlich suchen:

Region region = null; 
Set<Node> nodes = table.lookupAll(".clipped-container"); 
for (Node node : nodes) { 
    if (node instanceof Region) { 
     region = (Region) node; 
    } 
} 
for (TableColumn<Locale, ?> column : table.getColumns()) { 
    column.setPrefWidth(region.getWidth()/table.getColumns().size()); 
} 

ich nicht ganz verstehen, warum CONSTRAINED_RESIZE_POLICY ist nicht das, was Sie wollen, wie sie den Raum teilt gleichmäßig und nicht zulässt, dass Ändern der Größe der zugewiesenen überschreiten Leerzeichen (daher wird eine horizontale Bildlaufleiste nicht angezeigt). Wenn Sie jedoch eine spezielle Größenänderungsrichtlinie festlegen, sollte das obige Vorgehen hilfreich sein.

+0

Danke. Der vereinfachte Code in meinem Beitrag zeigt nur das Problem. Die eigentliche Größenänderungsrichtlinie ist ähnlich, macht aber ein paar Dinge anders als CONSTRAINED_RESIZE_POLICY. – JoshuaD

Verwandte Themen