2016-05-12 10 views
0

Ich sehe ein seltsames Verhalten, wo die bevorzugte Breite von javafx.scene.control.TextField nicht korrekt nach dem Aufruf setPrefColumnCount berechnet wird. Mein spezifischer Anwendungsfall ist für eine Steuerung. Mein Code ist wie folgt:JavaFX TextField.setPrefColumnCount() funktioniert nicht

@FXML 
private Spinner<Integer> mySpinner; 

@Override 
public void initialize(URL location, ResourceBundle resources) { 
    mySpinner.getEditor().setPrefColumnCount(3); 
} 

Nach dem obigen Ausführung, erhalte ich einen Spinner, die kaum groß genug ist für ein einzelnes Zeichen (der Spinner-Wert wird bei 999 im Bild):

Incorrectly Sized Spinner

Kennt jemand die richtige Weise, die Breite eines TextField basierend auf der Anzahl der Stellen einzustellen, die ich anzeigen möchte? Ich verwende JRE 8u77 unter Windows 7 Enterprise SP1 x64, falls es darauf ankommt.

EDIT

ich, dass ein Teil des Problems erkannt habe, ist, dass selbst wenn ich den Text über die Anweisungen here, messe ich immer noch nicht weiß, was Spinner.prefWidth zu setzen. Darüber hinaus scheint es, dass die Einstellung prefWidth auf dem zugrunde liegenden TextField Editor unterscheidet sich nicht davon, als es auf dem Spinner Objekt festlegen. Gibt es eine Möglichkeit, die TextField.padding-Eigenschaft zu erhalten (gibt 0 innerhalb der initialize-Methode zurück, obwohl es schließlich auf jeder Seite auf 7 gesetzt wird)? Wie wäre es mit einer Möglichkeit, die Breite der Pfeile nach oben/unten abzufragen? Wenn ich diese Werte irgendwie berechnen/abfragen könnte, könnte ich die Measure-Text-Technik verwenden. Ohne diese Information kann ich jedoch nicht herausfinden, wie ich vorgehen soll.

+0

Diese Eigenschaft hat auch nie für mich gearbeitet. Ich habe es umgangen, indem ich eine andere Methode zur Bestimmung der relativen Skalierung der Anzeige verwendet habe. Ich habe eine Variable erstellt, die wie ein em-Wert in CSS ist. 'final static double emem = Math.rint (neuer Text (" "). getLayoutBounds(). getHeight());' und dann benutze ich ihn als Basis für die relative Breite und Höhe mit einem Multiplikator. 'navButtons.setButtonMinWidth (5 * em);' – RonSiven

+0

Ich habe versucht, etwas auf der Grundlage von [messing text] (http://stackoverflow.com/a/13020490/960115) zu tun, das die gewünschte Anzahl von Null-Zeichen enthält. Im speziellen Fall des Objekts "Spinner" kämpfe ich jedoch mit der Anwendung dieser Messung. Es scheint, dass die 'prefWidth' des zugrunde liegenden' TextField' auch die 'padding' Eigenschaft berücksichtigen muss (gibt 0 innerhalb der' initialize' Methode zurück, obwohl es am Ende 7 wird) und die hoch/runter Buttons (who Breite kann ich nicht zu bekommen scheinen). –

Antwort

1

Die padding -Eigenschaft gibt 0 zurück, weil die TextField, die zu diesem Zeitpunkt nicht angelegt wurde, keinen CSS-Stil aufweist. Versuchen Sie, die Polsterung zu erhalten, nachdem die TextField zum SceneGraph. hinzugefügt wird

Zu dieser Zeit, die Sie auch in der Lage sind, die Nodeslookup Methode zu verwenden, um die StackPane zu erhalten, die auf die Pfeilschaltfläche enthält:

StackPane upArrow = (StackPane) spnr.lookup(".increment-arrow-button"); 
StackPane downArrow = (StackPane) spnr.lookup(".decrement-arrow-button"); 

es dann sollte möglich sein, die Breite für den Spinner zu berechnen:

double spinnerWidth = calculateWidth("123", spnr.getEditor()) + upArrow.getWidth(); 

private double calculateWidth(String value, TextField textField) { 
     Text text = new Text(value); 
     text.setFont(textField.getFont()); 
     Insets insets = textField.getInsets(); 
     return insets.getLeft() + text.prefWidth(-1) + insets.getRight(); 
    } 
+0

Gibt es ein Ereignis, das ich abonnieren kann, das "ausgelöst wird, nachdem das' TextField' zum 'SceneGraph' hinzugefügt wurde? Wenn nicht, was ist die Standardpraxis, um diese Funktionalität zu erreichen? –

+0

Sie können jede der genannten Methoden verwenden, nachdem der fragliche Knoten an eine 'Szene' in einer' Bühne' angehängt ist, die angezeigt wird. Nachdem Sie 'stage' durch' stage.show() 'angezeigt haben, können Sie die gewünschte Methode aufrufen. – jns

+0

Alle meine JavaFX-Controller haben bereits eine Schnittstelle implementiert, die eine 'setStage'-Methode enthält (so könnte ich den Besitzer für Popup-Dialoge festlegen). Für die Komponenten, die ein "Spinner" -Steuerelement enthalten, habe ich mich für das Ereignis "Stage.onShown" registriert und diese Breitenberechnung in diesem Handler durchgeführt. –

Verwandte Themen