不规则窗体形状的ToolTip .

前一篇利用层实现ToolTip,利用图形组合实现不规则的ToolTip    是实现不规则窗体的ToolTip的方法,该方法虽然实现了要求,但却有两点不足:
第一:该方法太笨拙,每个需要ToolTip的组件都得重新去设置一次新的ToolTip类;
第二:在ToolTip超出窗体边缘时,没法显示超出部分。
   于是乎觉得这样处理是不正确的,定有其他方法来更好的实现。所以在网上找了下。找了N久,还是在google中找到了比较满意的解决方法。而且该方法能解决上面的两点不足。    
这里说下该方法的思想。
第一用到了
[java] view plaincopyprint?
  1. PopupFactory.setSharedInstance(PopupFactory popu)方法  
[java] view plaincopyprint?
  1. PopupFactory.setSharedInstance(PopupFactory popu)方法  
PopupFactory.setSharedInstance(PopupFactory popu)方法
这里为什么要用该方法呢?原来所有的Popup的获取都会从该PopupFactory中获取,所以在这里调用该方法设置用于获取 Popup 的 PopupFactory后系统的调用Popup就在我们的控制范围内了。
所以我们就必须得重新实现PopupFactory类来拦截对JToolTip的处理。
第二用到了实时截图并实时绘制截图,使得我们呈现出来的JToolTip窗体和其周围的内容没有出入。
先看效果:
                      
下面贴出代码:
自己实现的PopupFactory类,这里主要拦截了JToolTip。
 
[java] view plaincopyprint?
  1. package com.michael.swingx.tooltip;  
  2.   
  3. import java.awt.BorderLayout;  
  4. import java.awt.Color;  
  5. import java.awt.Component;  
  6. import java.awt.Dimension;  
  7. import java.awt.Graphics;  
  8. import java.awt.Graphics2D;  
  9. import java.awt.Insets;  
  10. import java.awt.Polygon;  
  11. import java.awt.Rectangle;  
  12. import java.awt.RenderingHints;  
  13. import java.awt.Robot;  
  14. import java.awt.Shape;  
  15. import java.awt.geom.Area;  
  16. import java.awt.geom.RoundRectangle2D;  
  17. import java.awt.image.BufferedImage;  
  18.   
  19. import javax.swing.JComponent;  
  20. import javax.swing.JToolTip;  
  21. import javax.swing.Popup;  
  22. import javax.swing.PopupFactory;  
  23. import javax.swing.border.Border;  
  24.   
  25. public class NonRectanglePopupFactory extends PopupFactory {  
  26.     private static final int BORDER_PAD = 20;  
  27.     private static Robot robot;  
  28.     static {  
  29.     try {  
  30.         robot = new Robot();  
  31.     } catch (Exception e) {  
  32.     }  
  33.     }  
  34.   
  35.     public NonRectanglePopupFactory() {  
  36.     }  
  37.   
  38.     @Override  
  39.     public Popup getPopup(Component owner, Component contents, int x, int y)  
  40.         throws IllegalArgumentException {  
  41.     if (contents instanceof JToolTip) {  
  42.         ((JToolTip) contents).setBorder(null);  
  43.         Dimension dim = contents.getPreferredSize();  
  44.         Rectangle bound = new Rectangle(x, y, dim.width + 2 * BORDER_PAD,  
  45.             dim.height + 2 * BORDER_PAD);  
  46.         /** 
  47.          * 这是关键创建包含从屏幕中读取的像素的图像。该图像不包括鼠标光标。  
  48.          */  
  49.         BufferedImage backgroundImage = robot.createScreenCapture(bound);  
  50.         NonRectangleFrame frame = new NonRectangleFrame(owner, contents,  
  51.             backgroundImage);  
  52.         return super.getPopup(owner, frame, x, y);  
  53.     } else  
  54.         return super.getPopup(owner, contents, x, y);  
  55.     }  
  56.   
  57.     /** 
  58.      *  
  59.      * @author mengke 
  60.      * @email wqjsir@foxmail.com 
  61.      * @version 1.0 
  62.      */  
  63.     class NonRectangleFrame extends JComponent {  
  64.     public NonRectangleFrame(Component owner, Component content,  
  65.         BufferedImage backgroundImage) {  
  66.         setLayout(new BorderLayout());  
  67.         add(content, BorderLayout.CENTER);  
  68.         setBorder(new NonRectangleBorder(owner, content, backgroundImage));  
  69.     }  
  70.     }  
  71.   
  72.     /** 
  73.      * @author mengke 
  74.      * @email wqjsir@foxmail.com 
  75.      * @version 1.0 
  76.      */  
  77.     class NonRectangleBorder implements Border {  
  78.     private BufferedImage leftImage;  
  79.     private BufferedImage rightImage;  
  80.     private BufferedImage topImage;  
  81.     private BufferedImage bottomImage;  
  82.     private Component content;  
  83.     private Color backColor = new Color(205235235);  
  84.     private Color borderColor = new Color(95145145);  
  85.   
  86.     NonRectangleBorder(Component owner, Component content,  
  87.         BufferedImage backgroundImage) {  
  88.         this.content = content;  
  89.         // backColor = this.content.getBackground();  
  90.         // borderColor  = backColor.darker();  
  91.         generateLeftImage(backgroundImage);  
  92.         generateTopImage(backgroundImage);  
  93.         generateRightImage(backgroundImage);  
  94.         generateBottomImage(backgroundImage);  
  95.     }  
  96.   
  97.     @Override  
  98.     public void paintBorder(Component c, Graphics g, int x, int y,  
  99.         int width, int height) {  
  100.         //绘制图形,这些图形是当前位置的截图图形   
  101.         g.drawImage(leftImage, x, y, c);  
  102.         g.drawImage(rightImage, x + width - BORDER_PAD, y, c);  
  103.         g.drawImage(topImage, x + BORDER_PAD, y, c);  
  104.         g.drawImage(bottomImage, x + BORDER_PAD, y + height - BORDER_PAD, c);  
  105.         Rectangle bounds = new Rectangle(x, y, width, height);  
  106.         Graphics2D g2d = (Graphics2D) g;  
  107.         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  
  108.             RenderingHints.VALUE_ANTIALIAS_ON);  
  109.         g2d.setColor(backColor); // 背景颜色   
  110.         content.setBackground(backColor);//使背景色与填充的多边形颜色一致  
  111.         g2d.fill(getArea(bounds.getSize()));  
  112.         g2d.setColor(borderColor);  
  113.         g2d.draw(getArea(bounds.getSize()));//画边框  
  114.   
  115.         g.setColor(Color.black);  
  116.     }  
  117.   
  118.     /** 
  119.      * 返回画图所需要的区域<br> 
  120.      * 这里主要用到了图形合并共能。通过图形合并我们可以实现各种自定义的图形 
  121.      *  
  122.      * @param dim 
  123.      * @return 
  124.      */  
  125.     private Area getArea(Dimension dim) {  
  126.         int roundX = BORDER_PAD - 2;  
  127.         int roundY = BORDER_PAD - 2;  
  128.         Shape r = new RoundRectangle2D.Float(roundX, roundY, dim.width  
  129.             - roundX * 2, dim.height - roundY * 255); // 圆角矩形  
  130.         Area area = new Area(r);  
  131.         Polygon polygon = new Polygon();// 多边形  
  132.         polygon.addPoint(22, roundY);  
  133.         polygon.addPoint(35, roundY);  
  134.         polygon.addPoint(220);  
  135.         area.add(new Area(polygon)); // 合并图形  
  136.         return area;  
  137.     }  
  138.   
  139.     @Override  
  140.     public Insets getBorderInsets(Component c) {  
  141.         return new Insets(BORDER_PAD, BORDER_PAD, BORDER_PAD, BORDER_PAD);  
  142.     }  
  143.   
  144.     @Override  
  145.     public boolean isBorderOpaque() {  
  146.         return true;  
  147.     }  
  148.   
  149.     private void generateLeftImage(BufferedImage backgroundImage) {  
  150.         leftImage = backgroundImage.getSubimage(00, BORDER_PAD,  
  151.             backgroundImage.getHeight());  
  152.     }  
  153.   
  154.     private void generateTopImage(BufferedImage backgroundImage) {  
  155.         topImage = backgroundImage.getSubimage(BORDER_PAD, 0,  
  156.             backgroundImage.getWidth() - 2 * BORDER_PAD, BORDER_PAD);  
  157.     }  
  158.   
  159.     private void generateRightImage(BufferedImage backgroundImage) {  
  160.         rightImage = backgroundImage.getSubimage(backgroundImage.getWidth()  
  161.             - BORDER_PAD, 0, BORDER_PAD, backgroundImage.getHeight());  
  162.     }  
  163.   
  164.     private void generateBottomImage(BufferedImage backgroundImage) {  
  165.         bottomImage = backgroundImage.getSubimage(BORDER_PAD,  
  166.             backgroundImage.getHeight() - BORDER_PAD,  
  167.             backgroundImage.getWidth() - 2 * BORDER_PAD, BORDER_PAD);  
  168.     }  
  169.     }  
  170. }  
[java] view plaincopyprint?
  1.    
 
测试类: 
[java] view plaincopyprint?
  1. package com.michael.swingx.tooltip;  
  2.   
  3. import java.awt.Dimension;  
  4.   
  5. import javax.swing.JButton;  
  6. import javax.swing.JFrame;  
  7. import javax.swing.JLabel;  
  8. import javax.swing.JPanel;  
  9. import javax.swing.PopupFactory;  
  10. import javax.swing.UIManager;  
  11.   
  12. /** 
  13.  *@author michael 
  14.  *@email wqjsir@foxmail.com 
  15.  *@version 1.0 
  16.  */  
  17. public class TestToolTip extends JFrame{  
  18.   
  19.     /***/  
  20.     private static final long serialVersionUID = 1L;  
  21.       
  22.     public TestToolTip(){  
  23.     JButton _btn = new JButton("ToolTip测试");  
  24.     _btn.setToolTipText(_btn.getText());  
  25.       
  26.     JLabel _lb = new JLabel("<html>这是个Label,<br>这里测试ToolTip</html>");  
  27.     _lb.setToolTipText(_lb.getText());  
  28.     JPanel _plBody = new JPanel();  
  29.     _plBody.add(_btn);  
  30.     _plBody.add(_lb);  
  31.     getContentPane().add(_plBody);  
  32.     setLocationRelativeTo(null);  
  33.     setSize(new Dimension(100,300));  
  34.     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  35.     setVisible(true);  
  36.     }  
  37.       
  38.     public static void main(String args[]) {  
  39.     try {  
  40.         /** 
  41.          *设置用于获取 Popup 的 PopupFactory。 
  42.          */  
  43.         PopupFactory.setSharedInstance(new NonRectanglePopupFactory());  
  44.         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());  
  45.     } catch (Exception ex) {  
  46.     }  
  47.     java.awt.EventQueue.invokeLater(new Runnable() {  
  48.         public void run() {  
  49.         new TestToolTip().setVisible(true);  
  50.         }  
  51.     });  
  52.        }  
  53.   
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值