2015-07-02 3 views
11

В Swing я создал собственный документ, который смог определить и ограничить количество строк в TextArea, была ли линия обернута или была нажата строка. Я надеялся найти что-то подобное в FX, но не смог. Любые предложения о том, как справляться с ограничением количества строк?JavaFX - Лимитные строки TextArea?

Редактировать: Вот как я пытался выяснить, сколько завернутых строк находится в TextArea. Самая большая проблема заключается в том, чтобы получить точную ширину, чтобы перейти в setWrappingWidth, потому что, кажется, есть некоторое дополнение к содержимому TextArea вместе с границами.

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

не '.setPrefRowCount (10);' работу? с wrapText установлено значение true? также textarea уважает его область, поэтому он пытается ее заполнить, если вы не ограничиваете его maxsize или чем-то – Elltz

+0

Насколько я знаю, setPrefRowCount и setPrefColCount учитывают только предпочтительный размер TextArea, а не ограничение содержимого. – Tommo

+0

Это не имеет никакого смысла. Вы не можете ожидать, что линии будут ограничены, пока вы е. г. сделайте текстовую область меньшей. Это кошмар юзабилити. Какой прецедент для этого? – Roland

ответ

6

Каждый TextInputControl получил TextFormatter для выполнения этой задачи, так как Java 8 Update 40.

Он имеет две функциональные возможности которых это можно использовать для вашей задачи:

Фильтр (getFilter()), которые могут перехватывать и изменять пользовательский ввод. Это помогает сохранить текст в нужном формате.

Это очень примитивная попытка решить эту проблему:

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); 
    } 
} 

Это успешно предотвращает пользователю вводить более 10 строк. Но вы должны улучшить это решение, например, для обработки:

  • текст был заменен
  • текст был удален

TextFormatter действительно мощный и должен быть в состоянии обрабатывать все это.

+0

Я рассмотрю это через несколько часов. Я считаю, что жесткая (er) часть вычисляет количество строк из-за переноса текста в поле, в отличие от пользователя, нажимающего клавишу ввода. На данный момент я не рядом со своим компьютером, но я был близок к решению этой проблемы с помощью узла Text. – Tommo

+0

@Tommo Но теперь вы полностью изменили сферу своего вопроса .. от «Как (какие методы, файлы классов) я могу ограничить количество строк в TextField» на «Как определить количество строк в TextField». – eckig

+0

Ну, они вроде идут рука об руку, не так ли? Определение количества строк - это почти требование ограничить количество строк. – Tommo

-2

Назначенный в TextFormatter через:

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

и метод getWrappedLines:

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

Любая причина для голосования? – Tommo

+1

просто скопируйте/вставьте вместе с этой страницы, никаких исследований, а не ваше решение. – eckig

+0

Предложение TextFormatter было шагом в правильном направлении, однако метод getWrappedLines был тем, что я опубликовал изначально. Сочетание двух решило проблему. – Tommo

Смежные вопросы