2014-11-13 3 views
3

Я хочу выделить части текста, отображаемые в JavaFXTableView. До сих пор я использую Text объектов в TextFlow объектов. Чтобы выделить определенные части текста, я использую теги, чтобы вырезать текст по частям (javafx.scene.text объектов), чтобы выделить или не выделить с помощью следующего кода.JavaFX TableView с выделенным текстом

col3.setCellValueFactory(new PropertyValueFactory<RegexMatch, String>("text")); 
col3.setCellFactory(new Callback<TableColumn, TableCell>() { 
    @Override 
    public TableCell call(TableColumn param) { 
     TableCell cell = new TableCell() { 
      @Override 
      protected void updateItem(Object text, boolean empty) { 
       if (text != null && text instanceof String) { 
        String str = (String) text; 
        TextFlow flow = new TextFlow(); 
        if (txtSearchField.getText().length() > 3 && str.contains(HIGHLIGHT_START)) { 
         // Something to highlight 
         flow.getChildren().clear(); 
         while (str.contains(HIGHLIGHT_START)) { 
          // First part 
          Text starttext = new Text(str.substring(0, str.indexOf(HIGHLIGHT_START))); 
          starttext.setWrappingWidth(Double.MAX_VALUE); 
          flow.getChildren().add(starttext); 
          str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length()); 
          // Part to highlight 
          Text highlightedText = new Text(str.substring(0, str.indexOf(HIGHLIGHT_END))); 
          highlightedText.setStyle("-fx-text-background-color: yellow;"); 
          highlightedText.setFill(Color.BLUE); 
          highlightedText.setWrappingWidth(Double.MAX_VALUE); 
          flow.getChildren().add(highlightedText); 
          // Last part 
          str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length()); 
          if (!str.contains(HIGHLIGHT_START)) { 
           Text endtext = new Text(str); 
           endtext.setWrappingWidth(Double.MAX_VALUE); 
           flow.getChildren().add(endtext); 
          } 
         } 
        }else if (txtSearchField.getText().length() < 1) { 
         // Remove former highlightings and show simple text 
         str = str.replaceAll(HIGHLIGHT_START, ""); 
         str = str.replaceAll(HIGHLIGHT_END, ""); 
         flow.getChildren().clear(); 
         Text textModule = new Text(str); 
         textModule.setWrappingWidth(Double.MAX_VALUE); 
         flow.getChildren().add(textModule); 
        } else { 
         // show simple text 
         flow.getChildren().clear(); 
         Text textModule = new Text(str); 
         textModule.setWrappingWidth(Double.MAX_VALUE); 
         flow.getChildren().add(textModule); 
        } 
        flow.setPrefHeight(bigIcons ? BIG_SIZE : SMALL_SIZE); 
        setGraphic(flow); 
       } 
      } 
     }; 
     return cell; 
    } 
}); 

К сожалению, подсветка фона не работает, и у меня есть странные линии, как показано на рисунке. Текст не содержит строк.

scrennshot oft table

(Извините за качество изображения, его реальный скриншот :))

Любая помощь приветствуется.

Решение
Как @eckig предложил, используя множественные Labels в HBox является хорошей идеей, потому что каждый «Ярлык» может иметь свой собственный цвет фона, и вы можете использовать столько, сколько Labels в строке в HBox по мере необходимости :

col3.setCellValueFactory(new PropertyValueFactory<RegexMatch, String("excerptLineTable")); 
    col3.setCellFactory(new Callback<TableColumn, TableCell>() { 
    @Override 
    public TableCell call(TableColumn param) { 
     TableCell cell = new TableCell() { 
      @Override 
      protected void updateItem(Object text, boolean empty) { 
       if (text != null && text instanceof String) { 
        HBox hbox = new HBox(); 


        String str = (String) text; 
        if (txtSearchField.getText().length() > 3 && str.contains(HIGHLIGHT_START)) { 
         // Something to highlight 
         hbox.getChildren().clear(); 
         while (str.contains(HIGHLIGHT_START)) { 
          // First part 
          Label label = new Label(str.substring(0, str.indexOf(HIGHLIGHT_START))); 
          hbox.getChildren().add(label); 
          str = str.substring(str.indexOf(HIGHLIGHT_START) + HIGHLIGHT_START.length(), str.length()); 
          // Part to highlight 
          Label label2 = new Label(str.substring(0, str.indexOf(HIGHLIGHT_END))); 
          label2.setStyle("-fx-background-color: blue;"); 
          hbox.getChildren().add(label2); 
          // Last part 
          str = str.substring(str.indexOf(HIGHLIGHT_END) + HIGHLIGHT_END.length(), str.length()); 
          if (!str.contains(HIGHLIGHT_START)) { 
           Label label3 = new Label(str); 
           hbox.getChildren().add(label3); 
          } 
         } 
        } else if (txtSearchField.getText().length() < 1) { 
         // Remove former highlightings and show simple text 
         str = str.replaceAll(HIGHLIGHT_START, ""); 
         str = str.replaceAll(HIGHLIGHT_END, ""); 
         hbox.getChildren().clear(); 
         Label label = new Label(str); 
         hbox.getChildren().add(label); 
        } else { 
         // show simple text 
         hbox.getChildren().clear(); 
         Label label = new Label(str); 
         hbox.getChildren().add(label); 
        } 
        setGraphic(hbox); 
       } 
      } 
     }; 
     return cell; 
    } 
}); 

ответ

3

После двойного чтения вашей проблемы, я думаю, мы сможем возобновить это следующим образом:

  • Довольно длинный текст в TableColumn
  • Пользователь должен иметь возможность фильтровать этот текст
  • Каждый текстовый фрагмент, который соответствует текущему поисковому запросу.

Теперь у вас есть два варианта:

  1. Создать HBox и добавлять метки текста с указанной фрагменты. Ярлык расширяет область и поэтому может иметь фоновый цвет.
  2. Используйте TextFlow и добавьте тексты в виде фрагментов текста. Там вы можете «только» изменить цвет переднего плана.

Ах и пока я не забыл: Для того, чтобы отключить TextFlow текст упаковки не должны вызывать textModule.setWrappingWidth(Double.MAX_VALUE);, но вместо textModule.setPrefWidth(Double.MAX_VALUE);

И еще один намек: Попробуйте переработать как можно больше. Воспроизведение всего TextFlow для каждого обновления не является хорошей идеей (вместо этого сохраните его как переменную-член в ячейке).

+0

К сожалению, 'setPrefWidth' недоступен для' Text'. Я должен перестроить каждый 'TextFlows', потому что выделенные области меняются, так как пользователь хочет выделить другой шаблон. – alex

+0

Во-первых: я имел в виду setPrefWidth в TextFlow, а не Text. А во-вторых: вы можете хранить TextFlow и перестраивать только содержащиеся в нем текстовые элементы. – eckig

+0

1) Не меняет anythink, текст обертывается как прежде 2) Да, чтобы сохранить элемент TextFlow, но так как я должен удалить все текстовые файлы и создавать новые, я сомневаюсь в улучшении производительности с помощью этого ... – alex

2

Согласно this, Text не имеет фоновых свойств, допускающих применение стиля, именно поэтому изменение -fx-text-background-color не оказывает никакого влияния на него.

Возможным обходным путем для этого является перенос этого текстового узла в HBox, где вы можете легко установить его фон на желтый. Но у этого есть несколько недостатков, таких как текстовый поток, теряющий способность управлять контентом.

Если вам действительно нужно выделить, другим возможным решением может быть стиль фона текстового потока, поиск границ текста и установка правильных вставок.

Это пример, я быстро сделал с Живописный Builder и некоторые CSS:

.textflow { 
    -fx-background-color: yellow; 
    -fx-background-insets: 2 139.3 10 200; 
} 

Highlighted text

Я принял во внимание ширину TextFlow (510) и ширины различные текстовые узлы, использующие локальные границы: 200, 170,7 и 129. Таким образом, правая вставка 510-200-170,7 = 139,3, а левая вставка задается с ширины первого узла, 200.

Теперь задача адаптировать это в вашем методе ...

+0

В итоге я использовал ярлыки в HBox как @eckig, и вы предложили, спасибо! – alex

+0

Хорошая идея с вставками, но она может работать только с 1 совпадением на ячейку, не так ли? – Joffrey

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