2017-02-15 1 views
1

テキストエディタを構築していて、ライン番号マージンを使ってラインを選択する機能を追加しようとしています。私の現在のアプローチは、mouseDraggedを使って選択された行を更新することです。これは、マウスの動きが遅い場合はうまく動作しますが、動きが速い場合は選択が追いつかず、更新が停止します。ラインマージンからラインを選択 - mouseDraggedイベントが選択処理に追いつかない

選択した範囲の処理に新しいスレッドを使用しようとしましたが、まだフリーズしています。

更新:二つの値(最小/最大)のマウスの範囲ではなく、ライン毎に変更 - これは問題を修正

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)); 
     } 
    } 
+1

エディタはスクロールしませんか?ケースをどのように処理しますか?テキストをスクロールする必要がある場合、マウスが最終的な位置に到達する可能性があります。 – thst

+1

他人についてはわかりませんが、コード、問題、質問を理解するには、有効な[mcve]が必要です。 –

+0

@thstエディタはスクロールします。それが私が取り組まなければならない別の問題です。私はこれをどのように処理したいのか分かりませんでした。私は、マウスに行番号のマージンの境界が渡されても、選択肢を継続的に更新するために別のスレッドが必要だが、詳細は分からなかった。 –

答えて

1

マウスの概念とドキュメントの概念の両方を知っている同じ機能のコードを持つことは、災害のためのレシピです。コードを複数の関数に分割し、それぞれの関数が異なる抽象レベルで動作するようにします。

あなたが必要とするのは、どのマウスがYになったのか、どのマウスが現在マウスであるのかを知ることだけです。これにより、選択した線の範囲をいつでも再計算することができます。最初にビューポート-Yをワークスペース-Yに変換し、次にワークスペース-Yをライン番号に変換して、それぞれの行番号を取得します。

selectedLineNumbers.add(currentLineNumber);は、各行にマウスイベントが表示されることを前提としています。そうしないと、リストにギャップが含まれます。マウスをあまりにも速く動かすと、マウスイベントがほとんどまたはまったく離れてくるので、あなたはそうしません。そのため、あなたのselectedLineNumbersは、の範囲、(startingLineNumber、endingLineNumber)のはっきりとした行番号のリストでなければなりません。

関連する問題