有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在JTextPane java swing中填充行的rectange后无法与视图同步

在jtextpane java swing中突出显示特定行时,我遇到了问题。我有一个名为Solution和的主类,我在网上找到它,并对其进行了修改。每当调用sl()函数时,它都会绘制特定的行。这是由于调用了paint方法造成的。我用画法打印了虚拟线。那条虚线经常印刷。这意味着在预定义的时间段之后调用paint方法。在运行代码之后,我发现每当我最大化或最小化窗口时,只有它显示正确的所需行高亮显示。我希望无论何时调用sl函数(sl表示设置行,表示突出显示传递的行号)。我们应该改变或学习什么?谢谢你的阅读

解决方案。java文件

import javax.swing.*;
import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        JFrame f = new JFrame("Swing Paint Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTextPane jTextPane=new JTextPane();
        jTextPane.setText("abc\nbcd\nmm\njjjjj");
        LinePainter linePainter=new LinePainter(jTextPane);
        Scanner sc=new Scanner(System.in);
        f.add(jTextPane);
        f.setSize(250,250);
        f.setVisible(true);
        int x=sc.nextInt();
        linePainter.sl(2);
        x=sc.nextInt();
        linePainter.sl(3);
    }
}

线条画家。java文件

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

/*
 *  Track the movement of the Caret by painting a background line at the
 *  current caret position.
 */
public class LinePainter
        implements Highlighter.HighlightPainter, CaretListener, MouseListener, MouseMotionListener
{
    private JTextComponent component;

    private Color color;

    private Rectangle lastView;

    /*
     *  The line color will be calculated automatically by attempting
     *  to make the current selection lighter by a factor of 1.2.
     *
     *  @param component  text component that requires background line painting
     */
    public LinePainter(JTextComponent component)
    {
        this(component, null);
        setLighter(component.getSelectionColor());
    }

    /*
     *  Manually control the line color
     *
     *  @param component  text component that requires background line painting
     *  @param color      the color of the background line
     */
    public LinePainter(JTextComponent component, Color color)
    {
        this.component = component;
        setColor( color );

        //  Add listeners so we know when to change highlighting

        component.addCaretListener( this );
        component.addMouseListener( this );
        component.addMouseMotionListener( this );

        //  Turn highlighting on by adding a dummy highlight

        try
        {
            component.getHighlighter().addHighlight(0, 0, this);
        }
        catch(BadLocationException ble) {}
    }

    /*
     *  You can reset the line color at any time
     *
     *  @param color  the color of the background line
     */
    public void setColor(Color color)
    {
        this.color = color;
    }

    /*
     *  Calculate the line color by making the selection color lighter
     *
     *  @return the color of the background line
     */
    public void setLighter(Color color)
    {
        int red   = Math.min(255, (int)(color.getRed() * 1.2));
        int green = Math.min(255, (int)(color.getGreen() * 1.2));
        int blue  = Math.min(255, (int)(color.getBlue() * 1.2));
        setColor(new Color(red, green, blue));
    }
    public int ln=1;
    public void sl(int l) { ln=l;
        System.out.println("hii"); }
    //  Paint the background highlight

    public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c)
    {
        try
        {
            System.out.println("calling paint");
//            resetHighlight();
            Rectangle r = c.modelToView((c).getDocument().getDefaultRootElement().getElement(ln-1).getStartOffset());
            g.setColor( color );
//            if(lastView != null){
//                g.clearRect(0,lastView.y,c.getWidth(),lastView.height);
//            }
            g.fillRect(0, r.y, c.getWidth(), r.height);

//            if (lastView == null)
//                lastView = r;
        }
        catch(BadLocationException ble) {System.out.println(ble);}
    }

    /*
     *   Caret position has changed, remove the highlight
     */
    private void resetHighlight()
    {
        System.out.println("reset");
        //  Use invokeLater to make sure updates to the Document are completed,
        //  otherwise Undo processing causes the modelToView method to loop.

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {

                    Rectangle currentView = component.modelToView(component.getDocument().getDefaultRootElement().getElement(ln-1).getStartOffset());;

                    //  Remove the highlighting from the previously highlighted line

                    if (lastView.y != currentView.y)
                    {
                        component.repaint(0, lastView.y, component.getWidth(), lastView.height);
                        lastView = currentView;
                    }
                }
                catch(BadLocationException ble) {}
            }
        });
    }

    //  Implement CaretListener

    public void caretUpdate(CaretEvent e)
    {
//        resetHighlight();
    }

    //  Implement MouseListener

    public void mousePressed(MouseEvent e)
    {
//        resetHighlight();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    //  Implement MouseMotionListener

    public void mouseDragged(MouseEvent e)
    {
//        resetHighlight();
    }

    public void mouseMoved(MouseEvent e) {}
}

更新:

我更新了我的LinePainter文件,如下所示

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

/*
 *  Track the movement of the Caret by painting a background line at the
 *  current caret position.
 */
public class LinePainter
        implements Highlighter.HighlightPainter, CaretListener, MouseListener, MouseMotionListener
{
    private JTextComponent component;

    private Color color;

    private Rectangle lastView;

    /*
     *  The line color will be calculated automatically by attempting
     *  to make the current selection lighter by a factor of 1.2.
     *
     *  @param component  text component that requires background line painting
     */
    public LinePainter(JTextComponent component)
    {
        this(component, null);
        setLighter(component.getSelectionColor());
    }

    /*
     *  Manually control the line color
     *
     *  @param component  text component that requires background line painting
     *  @param color      the color of the background line
     */
    public LinePainter(JTextComponent component, Color color)
    {
        this.component = component;
        setColor( color );

        //  Add listeners so we know when to change highlighting

        component.addCaretListener( this );
        component.addMouseListener( this );
        component.addMouseMotionListener( this );

        //  Turn highlighting on by adding a dummy highlight

        try
        {
            component.getHighlighter().addHighlight(0, 0, this);
        }
        catch(BadLocationException ble) {}
    }

    /*
     *  You can reset the line color at any time
     *
     *  @param color  the color of the background line
     */
    public void setColor(Color color)
    {
        this.color = color;
    }

    /*
     *  Calculate the line color by making the selection color lighter
     *
     *  @return the color of the background line
     */
    public void setLighter(Color color)
    {
        int red   = Math.min(255, (int)(color.getRed() * 1.2));
        int green = Math.min(255, (int)(color.getGreen() * 1.2));
        int blue  = Math.min(255, (int)(color.getBlue() * 1.2));
        setColor(new Color(red, green, blue));
    }
    public int ln=1,prev=1;
    public void sl(int l) { prev=ln; ln=l;
        System.out.println("hii");
        //resetHighlight();
    }
    //  Paint the background highlight

    public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c)
    {
        try
        {
//            System.out.println("calling paint");
//            resetHighlight();
            if(prev != ln){
                Rectangle rect=c.modelToView((c).getDocument().getDefaultRootElement().getElement(prev-1).getStartOffset());
               prev=ln;
                System.out.println(rect.y+" " +c.getWidth()+" "+rect.height);
                g.clearRect(0,rect.y,c.getWidth(),rect.height);
            }
            Rectangle r = c.modelToView((c).getDocument().getDefaultRootElement().getElement(ln-1).getStartOffset());
            g.setColor( color );
//            if(lastView != null){
//                g.clearRect(0,lastView.y,c.getWidth(),lastView.height);
//            }
            System.out.println(r.y+" " +c.getWidth()+" "+r.height);
            g.fillRect(0, r.y, c.getWidth(), r.height);

            if (lastView == null)
                lastView = r;
        }
        catch(BadLocationException ble) {System.out.println(ble);}
    }

    /*
     *   Caret position has changed, remove the highlight
     */
    private void resetHighlight()
    {
        System.out.println("reset");
        //  Use invokeLater to make sure updates to the Document are completed,
        //  otherwise Undo processing causes the modelToView method to loop.

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    System.out.println("prev line "+prev+" "+ln);
                    Rectangle currentView = component.modelToView(component.getDocument().getDefaultRootElement().getElement(prev-1).getStartOffset());
                    //  Remove the highlighting from the previously highlighted line
                    if (lastView.y != currentView.y)
                    {
                        component.repaint(0, lastView.y, component.getWidth(), lastView.height);
                        lastView = currentView;
                    }
                    prev=ln;
                }
                catch(BadLocationException ble) {}
            }
        });
    }

    //  Implement CaretListener

    public void caretUpdate(CaretEvent e)
    {
//        resetHighlight();
    }

    //  Implement MouseListener

    public void mousePressed(MouseEvent e)
    {
//        resetHighlight();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    //  Implement MouseMotionListener

    public void mouseDragged(MouseEvent e)
    {
//        resetHighlight();
    }

    public void mouseMoved(MouseEvent e) {}
}

我仍然没有得到我想要的输出。调用sl()后,高亮显示不会更新。如果有任何建议,请通知我。谢谢你


共 (1) 个答案

  1. # 1 楼答案

    看起来你从Line Painter得到了代码

    该代码的关键是resetHighlight()方法。每次更改插入符号位置时都会调用该方法,因此可以在新行绘制高光

    您已经注释掉了对该方法的所有调用

    所以我认为你需要做两件事:

    1. 你的sl(…)方法需要调用resetHighlight()方法
    2. 您需要修改resetHighlight()方法,以根据行号而不是插入符号位置计算要重新绘制的矩形

      linePainter.sl(2);
      x=sc.nextInt();
      linePainter.sl(3);
      

    我不知道这段代码的意义是什么。LinePainter一次只能绘制一行,因此调用该方法两次将导致高亮显示第三行