Highlight current row in JTextPane

I'm trying for more than 2 days to implement a specific requirement for a text editor window... unfortunately without success so far :(

The goal is to get a text editor window which will highlight the current row, like other text editors do. With current row I mean the row where currently the cursor/caret is positioned.

I already found two different approaches but unfortunately I'm not able to adopt them so they work as expected.

The first approach is to overwrite the DefaultHighlighter (http://snippets.dzone.com/posts/show/6688). Во втором подходе вместо этого будет перезаписан HighlighterPainter ( http://www.jroller.com/santhosh/date/20050622 ).

Прямо сейчас я пытаюсь применить первый подход в моем проекте, но, как я уже сказал, он не работает должным образом.

В конце этого поста я публикую небольшой пример приложения, демонстрирующего проблему.

  • Если я запустил программу, то каретка ставится в начале первой строки. Однако строка не выделяется.
  • Теперь я ввожу некоторые символы. Эти символы будут выделены, но только эти символы не полная строка
  • Я нажимаю Enter, чтобы перейти к следующей строке. Первая строка больше не выделяется, что правильно. Вторая строка тоже не выделяется, что не так. Опять же, когда я ввожу несколько символов, они будут выделены, но не вся строка.
  • Теперь, когда я возвращаю курсор к первой строке, либо клавишей курсора вверх, либо щелчком мыши, вся первая строка будет выделена, а не только существующие символы. Это то поведение, которое я хочу с самого начала.

Надеюсь, кто-нибудь сможет сказать мне, что я здесь делаю не так ... или объяснить, почему вообще невозможно решить эту проблему. Любые альтернативные решения, позволяющие реализовать выделение линий, также высоко ценятся!

Заранее большое спасибо или объясните, почему вообще невозможно решить эту проблему. Любые альтернативные решения, позволяющие реализовать выделение линий, также высоко ценятся!

Заранее большое спасибо или объясните, почему вообще невозможно решить эту проблему. Любые альтернативные решения, позволяющие реализовать выделение линий, также приветствуются!

Заранее большое спасибо Ура Preachie

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;

public class HighlightProblem extends JFrame {
    private static final long serialVersionUID = 1L;
    private final JTextPane textPane;
    private final Highlighter.HighlightPainter cyanPainter;

    public HighlightProblem() {
        cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN);

        textPane = new JTextPane();
        textPane.setPreferredSize(new Dimension(500, 300));
        textPane.setHighlighter(new LineHighlighter());
        textPane.addCaretListener(new CaretListener() {
            @Override
            public void caretUpdate(CaretEvent e) {
                setHighlight(e);
            }
        });
        getContentPane().add(textPane);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new HighlightProblem();
    }

    public void setHighlight(CaretEvent e) {
        textPane.getHighlighter().removeAllHighlights();
        int currentLine = getLineFromOffset(textPane, e.getDot());
        int startPos = getLineStartOffsetForLine(textPane, currentLine);
        int endOffset = getLineEndOffsetForLine(textPane, currentLine);

        try {
            textPane.getHighlighter().addHighlight(startPos, endOffset, cyanPainter);           
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        textPane.repaint();
    }

    public int getLineFromOffset(JTextComponent component, int offset) {
        return component.getDocument().getDefaultRootElement().getElementIndex(offset);
    }

    public int getLineStartOffsetForLine(JTextComponent component, int line) {
        return component.getDocument().getDefaultRootElement().getElement(line).getStartOffset();
    }

    public int getLineEndOffsetForLine(JTextComponent component, int line) {
        return component.getDocument().getDefaultRootElement().getElement(line).getEndOffset();
    }

    public class LineHighlighter extends DefaultHighlighter {
        private JTextComponent component;

        @Override
        public final void install(final JTextComponent c) {
            super.install(c);
            this.component = c;
        }

        @Override
        public final void deinstall(final JTextComponent c) {
            super.deinstall(c);
            this.component = null;
        }

        @Override
        public final void paint(final Graphics g) {
            final Highlighter.Highlight[] highlights = getHighlights();
            final int len = highlights.length;
            for (int i = 0; i < len; i++) {
                Highlighter.Highlight info = highlights[i];
                if (info.getClass().getName().indexOf("LayeredHighlightInfo") > -1) {
                    // Avoid allocing unless we need it.
                    final Rectangle a = this.component.getBounds();
                    final Insets insets = this.component.getInsets();
                    a.x = insets.left;
                    a.y = insets.top;
                    // a.width -= insets.left + insets.right + 100;
                    a.height -= insets.top + insets.bottom;
                    final Highlighter.HighlightPainter p = info.getPainter();
                    p.paint(g, info.getStartOffset(), info.getEndOffset(), a, this.component);
                }
            }
        }

        @Override
        public void removeAllHighlights() {
            textPane.repaint(0, 0, textPane.getWidth(), textPane.getHeight());
            super.removeAllHighlights();
        }
    }
}

9
задан Manoj 23 March 2011 в 13:22
поделиться