2012-05-07 14 views
5

Sono nuovo di JavaFX 2 e confuso circa le larghezze predefinite di ComboBox e ListView. Mi aspetto che il ComboBox sia più largo, in modo che il testo "il testo del prompt" sia completamente visibile, per il ListView mi aspetterei che sia più piccolo, solo il più ampio possibile. Codice e screenshot seguenti.Straordinarie larghezze di controllo in JavaFX 2?

1) Come posso ottenere che ComboBox e Listview siano entrambi dimensionati in base alla larghezza di cui hanno bisogno?

2) Come rendere entrambi i controlli della stessa larghezza (quindi il massimo di entrambe le larghezze), è possibile creare un qualche tipo di collegamento tra le larghezze di entrambi? Sono particolarmente alla ricerca di una soluzione elegante per FXML.

Grazie per qualsiasi suggerimento!

@Override 
public void start(Stage primaryStage) { 
    ComboBox<String> comboBox = new ComboBox<String>(); 
    comboBox.setPromptText("the prompt text"); 
    ObservableList<String> items = FXCollections.observableArrayList(); 
    items.addAll("item 1", "item 2"); 
    comboBox.setItems(items); 

    ListView<String> list = new ListView<String>(); 
    ObservableList<String> items2 =FXCollections.observableArrayList (
     "blue", "red"); 
    list.setItems(items2); 

    VBox vBox = new VBox(); 
    vBox.getChildren().addAll(comboBox, list); 

    primaryStage.setScene(new Scene(vBox, 200, 300)); 
    primaryStage.show(); 
} 

enter image description here

risposta

0

1) Prova a impostare minWidth(x), prefWidth(x), maxWidth(x). Questo aiuta, ma non sono sicuro che sia una buona decisione.

2) Utilizzare il metodo void bind(ObservableValue<? extends Number> observable); dal framework di rilegatura. È stato sviluppato solo per questi casi. Es:

someProperty.bind(otherProperty); 

Inoltre è possibile utilizzare il binding bidirezionale per collegarli.

+0

Grazie per la tua risposta, maxWidth è tornato utile/migliore della vecchia situazione, anche se uno deve ancora indovinare i valori): avrei bisogno di alcune regolazioni automatiche fatte da JavaFX): E grazie per le informazioni sulla proprietà! davvero come WPF ;-) –

+0

E meglio usare SceneBuilder se per tali casi e quindi esportare fxml nel tuo progetto. – 4lex1v

8

2) Come rendere entrambi i controlli della stessa larghezza (quindi il massimo di entrambe le larghezze), è possibile creare un qualche tipo di collegamento tra le larghezze di entrambi? Sono particolarmente alla ricerca di una soluzione elegante per FXML.

Sembra che, per impostazione predefinita, ListView abbia la sua larghezza massima illimitata, ma ComboBox ha la sua larghezza massima fissata alla larghezza del suo elenco di articoli iniziale. Per fare in modo che questi controlli abbiano la stessa larghezza, il modo più semplice per farlo è posizionarli in un gestore di layout (come hai fatto tu - VBox) e quindi sbloccare la larghezza massima del comboBox.

Nel codice è possibile fare questo:

comboBox.setMaxWidth(Double.MAX_VALUE); 

Nel FXML aggiungere la seguente attibute definizione vostro elemento ComboBox:

maxWidth="Infinity" 

È possibile utilizzare la soluzione vincolante del John Gray, ma trovo la sopra più elegante.

1) Come posso ottenere che ComboBox e Listview siano entrambi dimensionati in base alla larghezza di cui hanno bisogno?

Penso che quello che chiedi qui è come rendere la casella combinata e listview occupino solo lo spazio necessario e non di più. Questo è, credo, un po 'complicato, e la piattaforma JavaFX non fornisce molto supporto per questo.

Ecco alcuni esempi di codice per fissare le dimensioni della casella di riepilogo al minimo richiesto.

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.scene.*; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Priority; 
import javafx.stage.Stage; 

public class GridControlWidths extends Application { 
    public static void main(String[] args) throws Exception { launch(args); } 
    @Override public void start(Stage stage) { 
    ComboBox<String> comboBox = new ComboBox<String>(FXCollections.observableArrayList("item 1", "item 2")); 
    comboBox.setPromptText("the prompt text"); 

    ListView<String> list = new ListView<String>(FXCollections.observableArrayList ("blue", "red")); 

    // layout the controls in a grid with appropriate constraints. 
    GridPane grid = new GridPane(); 
    grid.add(comboBox, 0, 0); 
    grid.add(list, 0, 1); 
    grid.setVgrow(list, Priority.ALWAYS); // make the list grow vertically as much as possible 

    // unclamp the max width of the combo box. 
    comboBox.setMaxWidth(Double.MAX_VALUE); 

    // display the scene. 
    stage.setScene(new Scene(grid, 200, 300)); 
    stage.show(); 

    // set the prefWidth of the listview based on the list cells (allowing 8 pixels for padding of the cells). 
    double maxWidth = 0; 
    for (Node n: list.lookupAll(".text")) { 
     maxWidth = Math.max(maxWidth, n.getBoundsInParent().getWidth() + 8); 
    } 
    list.setPrefWidth(maxWidth); 
    } 
} 

FWIW, credo che un approccio raccomandato quando solo per un paio di articoli è quello di mettere i tuoi oggetti in un VBox piuttosto che utilizzare un ListView o un ChoiceBox piuttosto che una casella combinata, in questo modo non è necessario per eseguire l'introspezione della cella e aggiornare la larghezza preferita tutto il tempo, in quanto il gestore del layout e i controlli si prenderanno cura di esso per te. Il ListView è ottimizzato per gestire il caso di un elenco virtualizzato che può contenere migliaia di elementi di dimensioni arbitrarie per i quali potresti non essere in grado di calcolare facilmente la larghezza del layout, motivo per cui penso che venga fornito con il comportamento di dimensionamento di controllo predefinito che non ridimensionarlo alla dimensione minima che potrebbe avere. Solitamente quando si utilizza un ListView, si seleziona semplicemente una prefWidth ragionevole per listView e si imposta su listView piuttosto che l'introspezione degli elementi come mostrato nell'esempio sopra.

Inoltre, l'immagine in cui viene ritagliato parte del testo del prompt, sembrerebbe (per me) un bug in JavaFX in cui non calcola correttamente la larghezza preferita per il controllo ComboBox quando il testo del prompt di ComboBox è più largo del testo dell'articolo ComboBox. Dato che ComboBox è attualmente un controllo completamente nuovo e ho riscontrato questo tipo di problemi nelle versioni precedenti dei controlli JavaFX e sono stati corretti, mi aspetto che il calcolo della larghezza preferito per il ComboBox venga risolto ragionevolmente presto.

+0

La ringrazio molto per le spiegazioni sul perché i controlli si comportano in questo modo (anche se non riesco a capire perché JavaFX lo faccia in modo non intuitivo secondo me). L'impostazione di MAX_VALUE è una buona idea, anche se il problema rimane che bisogna indovinare la larghezza corretta per la vbox): [il codice fornito è solo un breve exmaple] –

+0

Risposta aggiornata per rispondere più esaurientemente alla domanda e rispondere ad alcune (alcune) preoccupazioni. – jewelsea

+0

Un'altra cosa interessante da aggiungere che SceneBuilder utilizza maxWidth = "- Infinity" con il segno "-" – 4lex1v