BlockCaret.java
/*******************************************************************************
* Copyhacked (H) 2012-2020.
* This program and the accompanying materials
* are made available under no term at all, use it like
* you want, but share and discuss about it
* every time possible with every body.
*
* Contributors:
* ron190 at ymail dot com - initial implementation
******************************************************************************/
package com.jsql.view.swing.shell;
import com.jsql.util.LogLevelUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;
import java.awt.*;
/**
* A caret in a block shape.
*/
public class BlockCaret extends DefaultCaret {
/**
* Log4j logger sent to view.
*/
private static final Logger LOGGER = LogManager.getRootLogger();
/**
* Create a caret shaped for terminal.
*/
public BlockCaret() {
this.setBlinkRate(500); // half a second
}
@Override
protected synchronized void damage(Rectangle r) {
if (r == null) {
return;
}
// give values to x,y,width,height (inherited from java.awt.Rectangle)
this.x = r.x;
this.y = r.y;
this.height = r.height;
// A value for width was probably set by paint(), which we leave alone.
// But the first call to damage() precedes the first call to paint(), so
// in this case we must be prepared to set a valid width, or else
// paint()
// will receive a bogus clip area and caret will not get drawn properly.
if (this.width <= 0) {
this.width = this.getComponent().getWidth();
}
//Calls getComponent().repaint(x, y, width, height) to erase
this.repaint();
// previous location of caret. Sometimes one call isn't enough.
this.repaint();
}
@Override
public void paint(Graphics g) {
JTextComponent comp = this.getComponent();
if (comp == null) {
return;
}
int dot = this.getDot();
Rectangle r = null;
char dotChar;
try {
r = comp.modelToView(dot);
if (r == null) {
return;
}
dotChar = comp.getText(dot, 1).charAt(0);
} catch (BadLocationException e) {
LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
return;
}
if (Character.isWhitespace(dotChar)) {
dotChar = '_';
}
if (this.x != r.x || this.y != r.y) {
// paint() has been called directly, without a previous call to
// damage(), so do some cleanup. (This happens, for example, when
// the text component is resized.)
this.damage(r);
return;
}
g.setColor(new Color(0, 255, 0));
// do this to draw in XOR mode
g.setXORMode(comp.getBackground());
this.width = g.getFontMetrics().charWidth(dotChar);
if (this.isVisible()) {
g.fillRect(r.x, r.y, this.width, r.height);
}
}
}