我为我的应用程序创建了这个自定义JToolTip。当工具提示完全显示在JFrame中时,没有可见的背景(预期),但是当工具提示显示在JFrame外部时,背景将是可见的。我怎样才能将它删除?
我已尝试setBackground(new Color(255, 255, 255, 0));
使用' 0' alpha值,以确保背景是透明的,但没有做到这一点。
框架内的工具提示,正如所料:
工具提示超出JFrame,带有不需要的背景:
自定义JTooltip:
public class DefaultToolTip extends JToolTip {
public DefaultToolTip() {
setOpaque(false);
setPreferredSize(new Dimension(275, 30));
setBackground(new Color(255, 255, 255, 0));
}
@Override
public void addNotify() {
super.addNotify();
setOpaque(false);
Component parent = this.getParent();
if (parent != null) {
if (parent instanceof JComponent) {
JComponent jparent = (JComponent) parent;
jparent.setOpaque(false);
}
}
}
@Override
public void paint(Graphics g) {
String text = getComponent().getToolTipText();
addNotify();
Graphics2D g2d = drawComponent(g);
drawText(text, g2d);
g2d.dispose();
}
private void drawText(String text, Graphics2D g2d) {
//Draw the text
int cHeight = getComponent().getHeight();
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
if (cHeight > getHeight())
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (getHeight() + fm.getAscent()) / 2 + 2);
else
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (cHeight + fm.getAscent()) / 2 + 2);
}
private Graphics2D drawComponent(Graphics g) {
//Create a round rectangle
Shape round = new RoundRectangle2D.Float(0, 8, getWidth(), getHeight(), 8, 8);
//Draw the background
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fill(round);
//Draw the left triangle
Point p1 = new Point(getWidth() / 2, getHeight() - 30);
Point p2 = new Point(getWidth() / 2 + 8, getHeight() - 20);
Point p3 = new Point(getWidth() / 2 - 8, getHeight() - 20);
int[] xs = {p1.x, p2.x, p3.x};
int[] ys = {p1.y, p2.y, p3.y};
Polygon triangle = new Polygon(xs, ys, xs.length);
g2d.fillPolygon(triangle);
return g2d;
}
}
有些事情发生了变化,工具提示的行为与预期一致。 paint
方法已被paintComponent
方法取代,addNotify
调用已被删除,方法已更新以获取组件的窗口并为其提供透明背景。还需要setBorder(BorderFactory.createEmptyBorder());
来删除组件默认边框。
public class DefaultToolTip extends JToolTip {
public DefaultToolTip() {
setOpaque(false);
setPreferredSize(new Dimension(275, 30));
setBackground(new Color(255, 255, 255, 0));
setBorder(BorderFactory.createEmptyBorder());
}
@Override
public void addNotify() {
super.addNotify();
setOpaque(false);
Component parent = this.getParent();
if (parent != null) {
if (parent instanceof JComponent) {
JComponent jparent = (JComponent) parent;
jparent.setOpaque(false);
}
}
Window window = SwingUtilities.windowForComponent(this);
try {
window.setBackground(new Color(255, 255, 255, 0));
} catch (IllegalComponentStateException e) {
//Do nothing
}
}
@Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
String text = getComponent().getToolTipText();
Graphics2D g2d = drawComponent(g);
drawText(text, g2d);
g2d.dispose();
}
private void drawText(String text, Graphics2D g2d) {
//Draw the text
int cHeight = getComponent().getHeight();
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
if (cHeight > getHeight())
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (getHeight() + fm.getAscent()) / 2 + 2);
else
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (cHeight + fm.getAscent()) / 2 + 2);
}
private Graphics2D drawComponent(Graphics g) {
//Create a round rectangle
Shape round = new RoundRectangle2D.Float(0, 8, getWidth(), getHeight(), 8, 8);
//Draw the background
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fill(round);
//Draw the left triangle
Point p1 = new Point(getWidth() / 2, getHeight() - 30);
Point p2 = new Point(getWidth() / 2 + 8, getHeight() - 20);
Point p3 = new Point(getWidth() / 2 - 8, getHeight() - 20);
int[] xs = {p1.x, p2.x, p3.x};
int[] ys = {p1.y, p2.y, p3.y};
Polygon triangle = new Polygon(xs, ys, xs.length);
g2d.fillPolygon(triangle);
return g2d;
}
}
但请注意,super.paintComponent(g)
已被注释掉,因为它会再次绘制文字。
答案 0 :(得分:1)
不知道其中任何一项是否会有所帮助,但是:
不要覆盖绘画(...)。自定义绘画通过覆盖paintComponent(...)
。
调用super.paintComponent(...)作为第一个语句
不要在绘画方法中调用addNotify()
。绘画方法仅适用于绘画。
使用' 0' alpha值以确保背景透明,
Swing组件不知道如何处理透明背景。只需使组件不透明。
当工具提示与组件重叠时。工具提示实际上在显示之前添加到JWindow。因此,在addNotify()逻辑中,您可以搜索窗口并使其透明。
退房:
Window window = SwingUtilities.windowForComponent(...);