在JTextPane java swing中填充行的rectange后无法与视图同步
在jtextpane java swing中突出显示特定行时,我遇到了问题。我有一个名为Solution和的主类,我在网上找到它,并对其进行了修改。每当调用sl()函数时,它都会绘制特定的行。这是由于调用了paint方法造成的。我用画法打印了虚拟线。那条虚线经常印刷。这意味着在预定义的时间段之后调用paint方法。在运行代码之后,我发现每当我最大化或最小化窗口时,只有它显示正确的所需行高亮显示。我希望无论何时调用sl函数(sl表示设置行,表示突出显示传递的行号)。我们应该改变或学习什么?谢谢你的阅读 Solution.java文件在JTextPane java swing中填充行的rectange后无法与视图同步,java,swing,jtextpane,highlighting,Java,Swing,Jtextpane,Highlighting,在jtextpane java swing中突出显示特定行时,我遇到了问题。我有一个名为Solution和的主类,我在网上找到它,并对其进行了修改。每当调用sl()函数时,它都会绘制特定的行。这是由于调用了paint方法造成的。我用画法打印了虚拟线。那条虚线经常印刷。这意味着在预定义的时间段之后调用paint方法。在运行代码之后,我发现每当我最大化或最小化窗口时,只有它显示正确的所需行高亮显示。我希望无论何时调用sl函数(sl表示设置行,表示突出显示传递的行号)。我们应该改变或学习什么?谢谢你的
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);
}
}
LinePainter.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()后,高亮显示不会更新。如果有任何建议,请通知我。谢谢您……看起来您是从中获得代码的 该代码的关键是
resetHighlight()
方法。每次更改插入符号位置时都会调用该方法,因此可以在新行绘制高光
您已经注释掉了对该方法的所有调用
所以我认为你需要做两件事:
linePainter.sl(2);
x=sc.nextInt();
linePainter.sl(3);
我不知道这段代码的意义是什么。LinePainter一次只能绘制一行,因此调用该方法两次将导致第三行高亮显示。camickr,x=sc.nextInt()只需等待系统给出整数,然后在它绘制矩形后按enter键即可。@Hiatus_9,很高兴该建议有帮助。别忘了“接受”答案,这样人们就知道问题已经解决了。@camicrk但无法获得正确的输出。仍然有同步问题。无论何时调用方法sl(…),如果我不最大化或最小化窗口,则不会显示更新。请帮帮我。谢谢。当我仔细看我的原始代码时,代码的关键是caretPosition和该位置的线条高度矩形。插入符号在paint()和resetHighlight()方法中引用。因此,我想您需要更改这些方法,以便根据行号访问矩形。我看不出有任何理由保留以前的行号。我还建议您在更改要高亮显示的行号时需要调用resetHighlight()方法。如果这不起作用,我不知道问题出在哪里。