环境:Ubuntu 14.10,x86-64; Oracle JDK 1.8.0u25。
以下是问题截图:
FXML:
<TabPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.github.parboiled1.grappa.debugger.tracetab.TraceTabUi">
<Tab text="Parse tree" closable="false">
<SplitPane dividerPositions="0.5">
<SplitPane dividerPositions="0.5" orientation="VERTICAL">
<TreeView fx:id="parseTree" editable="false"/>
<!-- TODO: replace with something else -->
<TextArea fx:id="parseNodeDetails" editable="false"
style="-fx-font-family: monospace"/>
</SplitPane>
<ScrollPane>
<!-- HERE -->
<TextFlow fx:id="inputText"/>
</ScrollPane>
</SplitPane>
</Tab>
<!-- Two other tabs defined -->
</TabPane>
该字段在fxml文件中声明为经典TextFlow
,其原始内容为:
"A valid \"quoted string\" inside"
在下面名为ui
的“JavaFX控制器”文件中,它被声明为:
@FXML
TextFlow inputText;
现在,左上角是TreeView
;它使用CellFactory
定义如下:
// ui.parseTree is the TreeView
ui.parseTree.setCellFactory(param -> new ParseNodeCell(ui));
// and...
private static final class ParseNodeCell
extends TreeCell<ParseNode>
{
private ParseNodeCell(final TraceTabUi ui)
{
setEditable(false);
setOnMouseClicked(event -> {
final ParseNode node = getItem();
ui.parseNodeShowEvent(node);
});
}
@Override
protected void updateItem(final ParseNode item, final boolean empty)
{
super.updateItem(item, empty);
setText(empty ? null : String.format("%s (%s)", item.getRuleName(),
item.isSuccess() ? "SUCCESS" : "FAILURE"));
}
}
parseNodeShowEvent()
方法只是委托给另一个类:
// The NotFXML annotation is mine; just for the heck of it
@NotFXML
void parseNodeShowEvent(final ParseNode node)
{
presenter.handleParseNodeShow(node);
}
为了突出显示文本,演示者执行此操作:
void handleParseNodeShow(final ParseNode node)
{
// Some non relevant code... Then:
final List<String> fragments = getFragments(node);
view.highlightText(fragments);
}
private List<String> getFragments(final ParseNode node)
{
final int length = buffer.length();
final int start = node.getStart();
final int end = node.getEnd();
final List<String> ret = new ArrayList<>(3);
ret.add(buffer.extract(0, start));
final String match = buffer.extract(Math.min(start, length), end);
ret.add(match.isEmpty() ? "" : '<' + match + '>');
ret.add(buffer.extract(Math.min(end, length), length));
return ret;
}
view.highlightText()
执行此操作:
@Override
public void highlightText(final List<String> fragments)
{
final List<Text> list = new ArrayList<>(3);
Text text;
String fragment;
// Before match
fragment = fragments.get(0);
if (!fragment.isEmpty()) {
text = new Text(fragment);
text.setFill(Color.GRAY);
list.add(text);
}
// Match
fragment = fragments.get(1);
if (!fragment.isEmpty()) {
text = new Text(fragment);
text.setFill(Color.RED);
text.setUnderline(true);
list.add(text);
}
// After match
fragment = fragments.get(2);
if (!fragment.isEmpty()) {
text = new Text(fragment);
list.add(text);
}
ui.inputText.getChildren().setAll(list);
}
现在,问题是TextFlow
正确更新了最终,而不是立即更新。也就是说,它会在几秒钟后更新。当我点击TextFlow
时,它也会更新。
这是渲染错误还是我做错了什么?你有什么建议我来解决这个问题?