使用JavaFX TextFlow渲染错误,还是我的代码中的错误?

时间:2015-01-18 11:55:53

标签: java javafx rendering javafx-8

环境:Ubuntu 14.10,x86-64; Oracle JDK 1.8.0u25。

以下是问题截图:

enter image description here

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时,它也会更新。

这是渲染错误还是我做错了什么?你有什么建议我来解决这个问题?

0 个答案:

没有答案