Reputation: 31
I am designing a chat application.
For the chat box which is a JTextPane
, I used a custom shape other than the default rectangle shape as shown in the first image. But when this window which is a JInternalFrame
is hovered over another window(JInternalFrame
), the border line of the custom JTextPane
show dragged lines as shown in the second image.
Please why is this happening?
What I did was to write a set JTextpane
's border to a subclass of AbstractBorder
. Attached too is the subclass of AbstractBorder
used. However I've noticed that when I remove the graphic.setclip(area)
and graphic.setclip(null)
under the if(parent != null)
block of paintBorder()
method, the problem goes away.
How do I solve this line problem and still have my fancy text box?
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;
public class TextBubbleBorder1 extends AbstractBorder {
private Color color;
private int thickness = 4;
private int radii = 8;
private int pointerSize = 7;
private Insets insets = null;
private BasicStroke stroke = null;
private int strokePad;
private int pointerPad = 4;
private boolean left = true;
int xi, yi;
RenderingHints hints;
JPanel pane;
boolean right;
TextBubbleBorder1(
Color color, int thickness, int radii, int pointerSize) {
this.thickness = thickness;
this.radii = radii;
this.pointerSize = pointerSize;
this.color = color;
stroke = new BasicStroke(thickness);
strokePad = thickness / 2;
hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int pad = radii + strokePad;
int bottomPad = pad + pointerSize + strokePad;
insets = new Insets(-2,16,0,0);
}
TextBubbleBorder1(
Color color,int thickness,int radii,int pointerSize,bolean left, boolean right, int x, int y) {
this(color, thickness, radii, pointerSize);
this.left = left;
this.xi = x;
this.yi = y;
this.right = right;
}
@Override
public Insets getBorderInsets(Component c) {
return insets;
}
@Override
public Insets getBorderInsets(Component c, Insets insets) {
return getBorderInsets(c);
}
@Override
public void paintBorder(
Component c,
Graphics g,
int x, int y,
int width, int height) {
Graphics2D g2 = (Graphics2D) g;
int bottomLineY = height - thickness - pointerSize + 10 ;
RoundRectangle2D.Double bubble = null;
Area area = null;
Polygon pointer = null;
if(!right){
bubble = new RoundRectangle2D.Double(
10,
0,
!left ? width-9 : width - 25,
bottomLineY,
radii,
radii);
area = new Area(bubble);
pointer = new Polygon();
if(!left){
// left point
pointer.addPoint(11, 3);
pointer.addPoint(11, 14);
pointer.addPoint(0, 8);
}else{
pointer.addPoint(width-17, 2);
pointer.addPoint(width-23, 16);
pointer.addPoint(width-5, 6);
}
area.add(new Area(pointer));
}else{
bubble = new RoundRectangle2D.Double(
0,
-2,
width,
bottomLineY+5,
radii,
radii);
area = new Area(bubble);
}
g2.setRenderingHints(hints);
// Paint the BG color of the parent, everywhere outside the clip
// of the text bubble.
Component parent = c.getParent();
if (parent!=null) {
Color bg = parent.getBackground();
Rectangle rect = new Rectangle(0,0,width, height);
Area borderRegion = new Area(rect);
borderRegion.subtract(area);
g2.setClip(borderRegion);
g2.setColor(bg);
g2.fillRect(0, 0, width, height);
g2.setClip(null);
}
g2.setColor(color);
g2.setStroke(stroke);
g2.draw(area);
}
}
Upvotes: 1
Views: 327
Reputation: 57421
You can store original clip and set it back
E.g.
Shape oldCLip=g2.getClip();
...your code here...
g2.setClip(oldClip);
Clip is not rectangle but could be custom shape. When you set it to null you destroy it for parent as well because Graphics instance goes from parent to children. So you should restore it properly.
Upvotes: 1