2015-07-02 15 views
11

In Swing habe ich ein benutzerdefiniertes Dokument erstellt, das die Anzahl der Zeilen in einer TextArea bestimmen und begrenzen konnte, ob eine Zeile umgebrochen wurde oder ein Zeilenvorschub gedrückt wurde. Ich hatte gehofft, etwas ähnliches in FX zu finden, aber ich konnte es nicht. Irgendwelche Vorschläge, wie mit der Begrenzung der Anzahl der erlaubten Zeilen umzugehen ist?JavaFX - TextArea Zeilen begrenzen?

Edit: So versuchte ich herauszufinden, wie viele umhüllte Zeilen in der TextArea sind. Das größte Problem besteht darin, die genaue Breite in die setWrappingWidth zu übertragen, da der TextArea-Inhalt anscheinend mit Grenzen gefüllt ist.

Text helper = new Text(); 
helper.setText(text); 
helper.setFont(getFont()); 
helper.wrappingWidthProperty().bind(widthBinding); 
Font font = getFont(); 
FontMetrics fontMetrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(font); 
int preferredHeight = new Double(helper.getLayoutBounds().getHeight()).intValue(); 
int lineHeight = new Double(fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent()).intValue(); 
System.err.println("preferredHeight/lineHeight: " + preferredHeight/lineHeight); 
return preferredHeight/lineHeight; 
+0

nicht '.setPrefRowCount (10);' Arbeit? mit wrapText auf wahr gesetzt? Auch Textarea respektiert seinen Bereich, so dass es versucht, es zu füllen, es sei denn, Sie begrenzen es mit maxsize oder etwas – Elltz

+0

Soweit ich weiß SetFrefRowCount und setPrefColCount nur Faktor in die bevorzugte Größe der TextArea und nicht den Inhalt zu begrenzen. – Tommo

+0

Das ergibt überhaupt keinen Sinn. Sie können nicht erwarten, dass die Linien während Sie e begrenzt sind. G. mache das Textfeld kleiner. Es ist ein Albtraum der Benutzerfreundlichkeit. Was ist der Anwendungsfall dafür? – Roland

Antwort

6

Jeder TextInputControl bekam einen TextFormatter für diese Aufgabe, da Java 8-Update 40.

Es verfügt über zwei Funktionen, von denen dieser kann für Ihre Aufgabe verwendet werden:

Ein Filter (getFilter()) die Benutzereingaben abfangen und ändern kann. Dies hilft, den Text im gewünschten Format zu halten.

Dies ist ein sehr primitiver Versuch, dieses Problem zu lösen:

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 
     BorderPane root = new BorderPane(); 

     final TextArea textArea = new TextArea(); 
     textArea.setTextFormatter(createTextFormatter()); 
     root.setCenter(textArea); 

     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

    private static <T> TextFormatter<T> createTextFormatter() { 

     final IntegerProperty lines = new SimpleIntegerProperty(1); 

     return new TextFormatter<>(change -> { 
      if (change.isAdded()) { 
       if (change.getText().indexOf('\n') > -1) { 
        lines.set(lines.get() + 1); 
       } 
       if (lines.get() > 10) { 
        change.setText(""); 
       } 
      } 
      return change; 
     }); 
    } 

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

Diese erfolgreich die Nutzer von der Eingabe mehr als 10 Zeilen verhindert. Aber Sie sollten diese Lösung verbessern, zum Beispiel zu handhaben:

  • Text
  • Text wurde

Die TextFormatter gelöscht ersetzt wurde wirklich mächtig und sollte all dies zu handhaben können.

+0

Ich werde das in ein paar Stunden untersuchen. Ich glaube, dass der harte (er) Teil die Anzahl der Zeilen berechnet, die durch den Textumbruch in dem Feld verursacht werden, im Gegensatz zu dem Benutzer, der die Eingabetaste drückt. Ich bin im Moment nicht in der Nähe meines PCs, aber ich war kurz davor, dieses Problem mit einem Textknoten zu lösen. – Tommo

+0

@Tommo Aber jetzt haben Sie den Umfang Ihrer Frage vollständig geändert .. von "How (welche Methoden, Klassen-Dateien) kann ich die Anzahl der Zeilen in einem TextField" auf "Wie die Anzahl der Zeilen in einem TextField zu bestimmen". – eckig

+0

Nun, sie gehen Hand in Hand, nicht wahr? Die Bestimmung der Zeilenanzahl ist fast eine Voraussetzung, um die Anzahl der Zeilen begrenzen zu können. – Tommo

-2

die TextFormatter über Assigned:

setTextFormatter(new TextFormatter<>(change -> { 
    if(change.isContentChange()) { 
    if(getWrappedLines(change.getControlText(), change.getControlNewText()) > maxRows) { 
     change.setText(""); 
    } 
    } 
    return change; 
})); 

Und die getWrappedLines Methode:

int getWrappedLines(String oldText, String newText) { 
    Text helper = (Text)lookup(".text"); 
    if(helper != null) { 
    helper.setText(newText); 
    FontMetrics fontMetrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(getFont()); 
    int preferredHeight = new Double(helper.getLayoutBounds().getHeight()).intValue(); 
    int lineHeight = new Double(fontMetrics.getLineHeight()).intValue(); 
    // Initially a line's preferredHeight = 14, however each new line seems to increase the preferredHeight by 
    // 16 instead of 14. 
    preferredHeight = preferredHeight == lineHeight ? preferredHeight : preferredHeight - 2; 
    helper.setText(oldText); 
    return preferredHeight/lineHeight; 
    } 
    else { 
    return 0; 
    } 

}

+0

Irgendein Grund für die Down-Stimmen? – Tommo

+1

kopieren Sie einfach von dieser Seite, keine Forschung, nicht Ihre Lösung. – eckig

+0

Das Vorschlagen eines TextFormatter war ein Schritt in die richtige Richtung, aber die getWrappedLines-Methode war etwas, das ich ursprünglich gepostet habe. Die Kombination der beiden löste das Problem. – Tommo

Verwandte Themen