使用JavaFX TextFlow呈现bug,或者该bug在我的代码中?
环境:Ubuntu 14.10,x86-64;Oracle JDK 1.8.0u25 以下是问题截图: FXML:使用JavaFX TextFlow呈现bug,或者该bug在我的代码中?,java,javafx,rendering,javafx-8,Java,Javafx,Rendering,Javafx 8,环境: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 tr
<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>
在下面称为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"));
}
}
为了突出显示文本,演示者执行以下操作:
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;
}
@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
时,它也会更新
这是渲染错误还是我做错了什么?您建议我如何解决此问题
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;
}
@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);
}