打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用层来模拟ToolTip的部分功能,可以做出不规则形状
CSDN中一位XD想要一个类似QQ上的ToolTip效果(就像有人发言那样的不规则形状)
我一开始用继承JToolTip的方法做了一个,但是由于JToolTip不能设置透明,所以不规则形状做不出来,只好放弃,现在是继承JPanel后用层来实现的。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.text.View;
import com.sun.java.swing.SwingUtilities2;
/**
* 用层来模拟ToolTip的部分功能,可以做出非规则形状
* @author 五斗米 <如转载请保留作者和出处>
* @blog http://blog.csdn.net/mq612
*/
public class Test {
private JFrame frame = null;
private Box box = null; // 为了将MyButton放到一个合适的位置,采用这个比较麻烦的Box来管理
private MyButton button = null;
private MyToolTip tip = null;
public Test() {
frame = new JFrame("MyToolTip");
box = Box.createVerticalBox();
button = new MyButton("Button");
tip = new MyToolTip(frame.getLayeredPane(), "向Java战友问好!");
button.setMyToolTip(tip);
box.add(Box.createVerticalGlue());
Box box_ = Box.createHorizontalBox();
box_.add(Box.createHorizontalGlue());
box_.add(button);
box_.add(Box.createHorizontalGlue());
box.add(box_);
box.add(Box.createVerticalGlue());
frame.getContentPane().add(box, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(360, 220);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String args[]) {
new Test();
}
/**
* 继承JButton,实现了MouseListener接口,当鼠标移动到该按钮上,显示MyToolTip
* @author 五斗米
http://blog.csdn.net/mq612
*/
class MyButton extends JButton implements MouseListener {
private static final long serialVersionUID = -6373246716080645309L;
private MyToolTip tip = null;
// JButton的构造很多,都可以适用
public MyButton(String text) {
super(text);
this.addMouseListener(this);
}
// 设置MyToolTip
public void setMyToolTip(MyToolTip tip) {
this.tip = tip;
}
public MyToolTip getMyToolTip() {
return tip;
}
public void mouseClicked(MouseEvent e) {
}
// 当鼠标进入时显示,也可以加一个定时器来延时显示
public void mouseEntered(MouseEvent e) {
Point p = getLocationOnScreen();
SwingUtilities.convertPointFromScreen(p, frame.getContentPane());
tip.setLocation(new Point(p.x - tip.getWidth() + 10, p.y - tip.getHeight() + 10));
tip.setVisible(true);
}
// 鼠标离开即消失
public void mouseExited(MouseEvent e) {
tip.setVisible(false);
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
/**
* 继承JPanel,因为可以设置透明,所以我们很容易就可以做出不规则形状来,但是很遗憾,它的缺点是位置不能超出JFrame,否则超出部分无法显示
* @author 五斗米
http://blog.csdn.net/mq612
*/
class MyToolTip extends JPanel {
private static final long serialVersionUID = -1405474493135741335L;
private String text = null; // 将要显示的字符串
private JLayeredPane lp = null; // 我们要用到的层
public MyToolTip(JLayeredPane lp, String text) {
this.lp = lp;
this.text = text;
this.setOpaque(false);
lp.add(this, new Integer(JLayeredPane.POPUP_LAYER)); // 将组件放在弹出层中,这样就可以浮现在其它组件之上
this.setSize(this.getPreferredSize());
this.setVisible(false); // 设置组件不可视
}
public void setText(String text) {
this.text = text;
this.setSize(this.getPreferredSize()); // 改变文字后需要重新计算Size
}
public String getText() {
return text;
}
public JLayeredPane getLp() {
return lp;
}
public void setLp(JLayeredPane lp) {
this.lp = lp;
}
// 画背景和文字
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d
.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(205, 235, 235)); // 背景颜色
g2d.fill(this.getArea(this.getSize()));
g2d.setColor(new Color(40, 130, 180)); // 文字颜色
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.drawString(text, 25 / 2, (getHeight() - 10) / 2 + 5);
}
// 画边框
protected void paintBorder(Graphics g) {
super.paintBorder(g);
Graphics2D g2d = (Graphics2D) g;
g2d
.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(95, 145, 145)); // 边线颜色
g2d.draw(this.getArea(this.getSize()));
}
/**
* 返回适合的Size
*/
public Dimension getPreferredSize() {
Font font = getFont();
FontMetrics fm = getFontMetrics(font);
Insets insets = getInsets();
Dimension prefSize = new Dimension(insets.left + insets.right, insets.top
+ insets.bottom);
if ((text == null) || text.equals("")) {
text = "";
} else {
View v = (this != null) ? (View) getClientProperty("html") : null;
if (v != null) {
prefSize.width += (int) v.getPreferredSpan(View.X_AXIS);
prefSize.height += (int) v.getPreferredSpan(View.Y_AXIS);
} else {
prefSize.width += SwingUtilities2.stringWidth(this, fm, text) + 25; // 25为多加的部分
prefSize.height += fm.getHeight() + 10; // 10为多加的部分
}
}
return prefSize;
}
// 返回画图所需要的区域
private Area getArea(Dimension dim) {
Shape r = new RoundRectangle2D.Float(0, 0, dim.width - 1, dim.height - 10, 5, 5); // 圆角矩形
Area area = new Area(r);
Polygon polygon = new Polygon(); // 多边形
polygon.addPoint(dim.width - 15, dim.height - 10);
polygon.addPoint(dim.width - 5, dim.height - 10);
polygon.addPoint(dim.width, dim.height);
area.add(new Area(polygon)); // 合并
return area; // 返回
}
}
}
最新修改(2007-03-09):
一、上面代码中鼠标一进入按钮就会显示MyToolTip,当初没有加延时显示功能,现在补上,替换MyButton类的代码:
class MyButton extends JButton implements MouseListener, ActionListener {
private static final long serialVersionUID = -6373246716080645309L;
private Timer timer = null;
private MyToolTip tip = null;
// JButton的构造很多,都可以适用
public MyButton(String text) {
super(text);
timer = new Timer(1000, this); // 构造定时器,这里使用的是javax.swing.Timer
this.addMouseListener(this);
}
// 设置MyToolTip
public void setMyToolTip(MyToolTip tip) {
this.tip = tip;
}
public MyToolTip getMyToolTip() {
return tip;
}
public void mouseClicked(MouseEvent e) {
}
// 当鼠标进入时显示,也可以加一个定时器来延时显示
public void mouseEntered(MouseEvent e) {
timer.start(); // 启动定时器
}
// 鼠标离开即消失
public void mouseExited(MouseEvent e) {
tip.setVisible(false);
timer.stop();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void actionPerformed(ActionEvent e) {
timer.stop();
Point p = getLocationOnScreen();
SwingUtilities.convertPointFromScreen(p, frame.getContentPane());
tip.setLocation(new Point(p.x - tip.getWidth() + 10, p.y - tip.getHeight() + 10));
tip.setVisible(true);
}
}
二、上面的代码中使用了com.sun.java.swing包中的SwingUtilities2类,使用1.6版本JDK可以使用下面方法替代:
SwingUtilities.computeStringWidth(fm, text) + 25; // 25为多加的部分
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
鼠标控制小球
Java右键菜单实现文本组件内容的的复制、粘贴、剪切功能
Java局域网远程控制
设置背景图,并在上面添加可随意拖动的图片标签
Java Swing根据图片创建不规则窗体(二)
swing组件的paint问题_技术专辑
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服