Java 从行边距中选择行-鼠标标记事件无法跟上选择处理

Java 从行边距中选择行-鼠标标记事件无法跟上选择处理,java,swing,awt,Java,Swing,Awt,我正在构建一个文本编辑器,并尝试添加使用行号边距选择行的功能。我目前的方法是使用mouseDragged来更新选定的行。当鼠标移动缓慢时,这种方法可以很好地工作,但是当鼠标移动较快时,选择无法跟上,只是停止更新 我已经尝试使用一个新线程来处理所选范围,但它仍然冻结 更新:更改为两个值(最小值/最大值)的鼠标范围,而不是每行-这解决了问题 鼠标标记法 private void mouseDragged(MouseEvent event, Mouse mouse) { int eventY

我正在构建一个文本编辑器,并尝试添加使用行号边距选择行的功能。我目前的方法是使用mouseDragged来更新选定的行。当鼠标移动缓慢时,这种方法可以很好地工作,但是当鼠标移动较快时,选择无法跟上,只是停止更新

我已经尝试使用一个新线程来处理所选范围,但它仍然冻结

更新:更改为两个值(最小值/最大值)的鼠标范围,而不是每行-这解决了问题

鼠标标记法

private void mouseDragged(MouseEvent event, Mouse mouse) {
    int eventY = event.getY();
    int currentLineNumber = this.getLineNumber(eventY);

    mouse.endRange(currentLineNumber);

    if(mouse.getRange()[0] != mouse.getRange()[1]) {
        this.selectLineRange(mouse);
    } else {
        this.selectLineForOffset(eventY);
    }
}
鼠标状态

private class Mouse {
    int mouseY = -1;
    int[] range = new int[2];

    private void resetMouse(boolean resetBeginLine) {
        this.mouseY = -1;
        this.range = new int[2];
    }

    void endRange(int lineNumber) {
        range[1] = lineNumber;
    }

    void beginRange(int lineNumber) {
        range[0] = lineNumber;
    }

    int[] getRange() {
        return range;
    }

    boolean validRange() {
        return ((range[0] | range[1]) > 0);
    }
}
最后是选线范围法

private void selectLineRange(Mouse mouse) {
        if (mouse.validRange()) {
            int minLine = Math.min(mouse.getRange()[0], mouse.getRange()[1]);
            int maxLine = Math.max(mouse.getRange()[0], mouse.getRange()[1]);;

            Element root = editor.getDocument().getDefaultRootElement();
            int startSelection = root.getElement(minLine).getStartOffset();
            int endSelection = root.getElement(maxLine).getEndOffset();

            //editor.setCaretPosition(mouse.mouseDirection == Direction.UP ? startSelection : endSelection - 1);
            editor.select(startSelection, Math.max(endSelection - 1, 0));
        }
    }

在同一个函数中使用既知道鼠标概念又知道文档概念的代码会导致灾难。将代码拆分为多个函数,每个函数在不同的抽象级别上工作

您所需要的只是知道鼠标在哪个Y点落下,以及鼠标当前在哪个Y点。由此,您可以在任何给定时刻重新计算选定线的范围。首先将viewport-Y转换为workspace-Y,然后将workspace-Y转换为行号,瞧,每个行号都有


这:
selectedlinenumber.add(当前行号)假定您将在每行上接收鼠标事件。如果您没有,那么您的列表将包含空白。你不会,因为当你移动鼠标太快的时候,鼠标事件很少而且相隔很远。这就是为什么
selectedlinenumber
应该是一个范围(startingLineNumber,endingLineNumber),而不是一个不同行号的列表。

编辑器不滚动吗?如何处理这种情况,当文本需要滚动时,在这种情况下,鼠标可能会到达最终位置。将不再出现移动事件。不确定其他事件,但我自己需要一个有效的文件来理解您的代码、问题和疑问。@thst编辑器确实会滚动。这是我需要解决的另一个问题。我还没想好怎么处理这件事。我知道我需要一个单独的线程来不断更新选择,如果鼠标通过了行号边界,但我还没有弄清楚细节。