2015-05-11 11 views
5

Il mio primo tentativo di giocare con JavaFX e sto cercando di capire un po 'sulla gestione del layout. Come possiamo accedere alla dimensione preferita di un controllo?Qual è la dimensione preferita di un controllo?

Nell'esempio seguente sto tentando di impostare la larghezza massima di 200 pixel superiore alla larghezza preferita. Cioè, voglio consentire al pulsante di crescere (fino ad un massimo) man mano che aumenta la larghezza del frame.

Tuttavia quando si esegue il codice della larghezza preferita è -1, quindi aggiungendo 200 alla larghezza preferito dà una larghezza massima di 199.

import javafx.application.Application; 
import javafx.event.*; 
import javafx.stage.Stage; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.geometry.Insets; 

public class BorderPaneSSCCE extends Application 
{ 
    @Override 
    public void start(Stage primaryStage) 
    { 
     Button button = new Button("Button at PreferredSize"); 
     button.setMaxWidth(button.getPrefWidth() + 200); 
     System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); 

     button.setOnAction(new EventHandler<ActionEvent>() 
     { 
      @Override 
      public void handle(ActionEvent event) 
      { 
       System.out.println("Width: " + button.getWidth()); 
      } 
     }); 

     HBox root = new HBox(); 
     HBox.setHgrow(button, Priority.ALWAYS); 
     root.getChildren().add(button); 

     Scene scene = new Scene(root); 
     primaryStage.setTitle("Java FX"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
     System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); 
    } 

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

Quando si esegue il codice e clicca sul pulsante vedo : Width: 139.0

Dopo che ho ridimensionare la larghezza del telaio in modo che il pulsante è il più grande possibile e cliccare sul pulsante che vedo: Width: 199.0

speravo di vedere Width: 339.0 (cioè 139 + 200).

Quindi, come si accede alla dimensione/larghezza preferita di un controllo?

risposta

4

getPrefWidth() restituisce la bandiera USE_COMPUTED_SIZE (che è -1) per impostazione predefinita.

È possibile utilizzare prefWidth(-1) per ottenere la larghezza preferita calcolata internamente. Tuttavia, la larghezza preferita non verrà calcolata fino a quando il nodo non viene disposto dal riquadro di layout (HBox nell'esempio). Questo succede la prima volta quando viene mostrato lo stage.

Sono disponibili più opzioni, se si desidera che la larghezza massima dipenda dalla larghezza preferita. Uno è quello di impostare la larghezza preferita su un valore fisso con setPrefWidth() prima di impostare la larghezza massima.

Un altro consiste nell'implementare un algoritmo di layout personalizzato - sul nodo o su un riquadro di layout. Ecco un esempio utilizzando un pulsante personalizzato.

// button whose maxWidth is always prefWidth + 200 
Button button = new Button() { 
    @Override 
    protected double computeMaxWidth(double height) 
    { 
     return this.prefWidth(height) + 200.0; 
    } 
}; 
+0

Stai dicendo che 'prefWidth (-1)' restituirà '-1' (o qualche altra larghezza non valida) fino a quando lo schermo non sarà reso? –

+0

Il prefWidth (-1) era il metodo che stavo cercando. Peccato che non abbia un valore finché non viene mostrato lo Stage :(L'override del metodo 'computeMaxWidth (...)' sembra la soluzione migliore per l'esempio dato, ma non sapevo come implementare quel metodo senza il metodo prefWidth (...) (+1). – camickr

+0

@JAtkin, Sì, ho appena cambiato il mio SSCCE per visualizzare il prefWidth (-1) dopo che il pulsante è stato creato e visualizza 0. Quando visualizzo la larghezza dopo il show() metodo mostra 138.238 .... – camickr

1

getPrefWidth() funziona solo dopo il Node è stato mostrato/reso.

È possibile visualizzare prima lo Button o provare a utilizzare Node.prefWidth(-1).

+0

Sì, prefWidth (-1) funziona dopo che è stato mostrato lo stage (+1). GetPrefWidth() non sembra funzionare anche dopo che è stato mostrato lo stage. – camickr

+0

@camickr '' Stage' e 'Button' devono essere mostrati prima che' getPrefWidth() 'funzioni. – eckig

+0

Ho modificato il mio SSCCE per visualizzare 'prefWidth (-1)' e 'getPrefWidth()' quando viene creato il pulsante e dopo che viene mostrato lo stage. Il valore per 'prefWidth (-1)' cambia, ma 'getPrefWidth()' non cambia.Questo ha senso per me sapere che conosco il metodo 'prefWidth (...)'. 'GetPrefWidth()' cambierà solo se si utilizza il metodo 'setPrefWidth (...)'. – camickr

2

-1 è il valore di Region.USE_COMPUTED_SIZE, che indica al componente di determinare la propria dimensione ottimale. Questo perché ogni Node ha un metodo chiamato prefWidth(double height) ed è doppio prefHeight(double width) (lo stesso per min/max dimensioni) che i gestori di layout usano per calcolare il layout dei propri figli. Per ottenere la dimensione pref è necessario utilizzare

button.prefWidth([-1 or Region.USE_COMPUTED_SIZE]) 

(docs)

+0

Grazie, per l'input (+1), ho perso il metodo 'prefWidth()',. Ho esaminato tutti i metodi "getter". Ho ancora Swing nella parte posteriore della mia testa. Dovrò stare più attento la prossima volta. – camickr

Problemi correlati