Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 322|回复: 0

[Swing学习]Swing画3D饼图

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-6 23:56:19 | 显示全部楼层 |阅读模式
    鼠标点击饼图时,被点击的部分会移动出来。

    代码:
    1. package test;   
    2.   
    3. import java.awt.Color;   
    4. import java.awt.FontMetrics;   
    5. import java.awt.Graphics;   
    6. import java.awt.Graphics2D;   
    7. import java.awt.RenderingHints;   
    8. import java.awt.Toolkit;   
    9. import java.awt.event.MouseAdapter;   
    10. import java.awt.event.MouseEvent;   
    11. import java.awt.geom.Arc2D;   
    12. import java.util.ArrayList;   
    13. import java.util.List;   
    14.   
    15. import javax.swing.JFrame;   
    16. import javax.swing.JPanel;   
    17.   
    18. /**  
    19. * 绘制3D效果的饼图  
    20. *   
    21. * @author Biao  
    22. */  
    23. @SuppressWarnings("serial")   
    24. public class Pies3D extends JPanel {   
    25.     // 在饼图中显示的数据   
    26.     private double[] data = { 10.72, 15.38, 3.74, 10.26, 6.56, 5.69, 10.72, 15.38, 6.15, 18.0 };   
    27.     private Color[] defaultColors; // 预定义饼图的颜色   
    28.     private Pie[] pies;   
    29.   
    30.     private int shadowDepth = 8;   
    31.     int selectedIndex = -1; // 鼠标点击是选中的Arc, -1为没有选中   
    32.   
    33.     public Pies3D() {   
    34.         initColors();   
    35.         initPies(data, defaultColors, shadowDepth);   
    36.   
    37.         // 取得鼠标选中的饼图: arc   
    38.         addMouseListener(new MouseAdapter() {   
    39.             @Override  
    40.             public void mouseClicked(MouseEvent e) {   
    41.                 selectedIndex = -1;   
    42.                 for (int i = 0; i < pies.length; ++i) {   
    43.                     if (pies[i].getArc().contains(e.getX(), e.getY())) {   
    44.                         selectedIndex = i;   
    45.                         break;   
    46.                     }   
    47.                 }   
    48.                 repaint();   
    49.             }   
    50.         });   
    51.     }   
    52.   
    53.     private void initColors() {   
    54.         List
    55.    
    56.       colors = new ArrayList
    57.      
    58.       ();   
    59.         colors.add(getColorFromHex("#FF7321"));   
    60.         colors.add(getColorFromHex("#169800"));   
    61.         colors.add(getColorFromHex("#00E500"));   
    62.         colors.add(getColorFromHex("#D0F15A"));   
    63.         colors.add(getColorFromHex("#AA6A2D"));   
    64.         colors.add(getColorFromHex("#BFDD89"));   
    65.         colors.add(getColorFromHex("#E2FF55"));   
    66.         colors.add(getColorFromHex("#D718A5"));   
    67.         colors.add(getColorFromHex("#00DBFF"));   
    68.         colors.add(getColorFromHex("#00FF00"));   
    69.         defaultColors = colors.toArray(new Color[0]);   
    70.     }   
    71.   
    72.     public void initPies(double[] data, Color[] colors, int shadowDepth) {   
    73.         double sum = 0;   
    74.         for (double d : data) {   
    75.             sum += d;   
    76.         }   
    77.   
    78.         // 初始化Pies   
    79.         List< Arc2D> arcList = new ArrayList< Arc2D>();   
    80.         List< Pie> pieList = new ArrayList< Pie>();   
    81.   
    82.         double arcAngle = 0;   
    83.         int x = 50;   
    84.         int y = 50;   
    85.         int w = 380;   
    86.         int h = (int) (w * 0.618);   
    87.         int startAngle = 30;   
    88.         int sumAngle = 0;   
    89.         for (int i = 0; i < data.length; ++i) {   
    90.             arcAngle = data[i] * 360 / sum;   
    91.             if (i + 1 == data.length && sumAngle < 360) {   
    92.                 arcAngle = 360 - sumAngle;   
    93.             }   
    94.   
    95.             Arc2D.Double arc = new Arc2D.Double(x, y, w, h, startAngle, arcAngle, Arc2D.PIE);   
    96.             arcList.add(arc);   
    97.   
    98.             Pie pie = new Pie(arc, colors[i % colors.length], shadowDepth, data[i]);   
    99.             pieList.add(pie);   
    100.   
    101.             sumAngle += arcAngle;   
    102.             startAngle += arcAngle;   
    103.         }   
    104.         pies = pieList.toArray(new Pie[0]);   
    105.     }   
    106.   
    107.     public static Color getColorFromHex(String hex) {   
    108.         try {   
    109.             return new Color(Integer.valueOf(hex.substring(1), 16));   
    110.         } catch (Exception e) {   
    111.             return Color.BLACK;   
    112.         }   
    113.     }   
    114.   
    115.     @Override  
    116.     protected void paintComponent(Graphics g) {   
    117.         super.paintComponent(g);   
    118.         Graphics2D g2d = (Graphics2D) g;   
    119.         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);   
    120.   
    121.         showPies(g2d);   
    122.     }   
    123.   
    124.     private void showPies(Graphics2D g2d) {   
    125.         int startIndex = 0; // 从第几个饼图开始绘制   
    126.         int endIndex = pies.length; // 要画的饼图的数量.   
    127.   
    128.         // 一次性绘制完3D效果,然后再绘制饼图的效果比绘制饼图的同时绘制好   
    129.         for (int i = startIndex; i < endIndex; ++i) {   
    130.             if (i != selectedIndex) {   
    131.                 g2d.setColor(pies[i].getColor().darker());   
    132.                 g2d.fill(pies[i].getFrontWall());   
    133.             }   
    134.         }   
    135.   
    136.         // 第一个和最后一个要特殊处理   
    137.         if (selectedIndex != startIndex) {   
    138.             g2d.setColor(pies[startIndex].getColor().darker());   
    139.             g2d.fill(pies[startIndex].getLeftWall());   
    140.         }   
    141.   
    142.         if (selectedIndex != endIndex - 1) {   
    143.             g2d.setColor(pies[endIndex - 1].getColor().darker());   
    144.             g2d.fill(pies[endIndex - 1].getRightWall());   
    145.         }   
    146.   
    147.         // 绘制选中的Arc前一个与后一个的墙   
    148.         if (selectedIndex != -1) {   
    149.             int previousIndex = selectedIndex > startIndex ? (selectedIndex - 1) : endIndex - 1;   
    150.             int nextIndex = (selectedIndex + 1) >= endIndex ? startIndex : (selectedIndex + 1);   
    151.   
    152.             // 前一个画右墙   
    153.             g2d.setColor(pies[previousIndex].getColor().darker());   
    154.             g2d.fill(pies[previousIndex].getRightWall());   
    155.   
    156.             // 后一个画左墙   
    157.             g2d.setColor(pies[nextIndex].getColor().darker());   
    158.             g2d.fill(pies[nextIndex].getLeftWall());   
    159.         }   
    160.   
    161.         FontMetrics metrics = g2d.getFontMetrics();   
    162.         // 绘制饼图,把不需要的部分隐藏掉   
    163.         for (int i = startIndex; i < endIndex; ++i) {   
    164.             if (i != selectedIndex) {   
    165.                 Pie p = pies[i];   
    166.                 g2d.setColor(p.getColor());   
    167.                 g2d.fill(p.getArc());   
    168.   
    169.                 String value = p.getValue() + "%";   
    170.                 int w = metrics.stringWidth(value) / 2;   
    171.                 g2d.setColor(Color.BLACK);   
    172.                 g2d.drawString(value, (int) (p.getLabelPosition().getX() - w),   
    173.                     (int) (p.getLabelPosition().getY()));   
    174.             }   
    175.         }   
    176.   
    177.         // 绘制被选中的饼图   
    178.         if (selectedIndex != -1) {   
    179.             Pie p = pies[selectedIndex].getSelectedPie();   
    180.             g2d.setColor(p.getColor().darker());   
    181.             g2d.fill(p.getFrontWall());   
    182.             g2d.fill(p.getLeftWall());   
    183.             g2d.fill(p.getRightWall());   
    184.   
    185.             g2d.setColor(p.getColor());   
    186.             g2d.fill(p.getArc());   
    187.   
    188.             String value = p.getValue() + "%";   
    189.             int w = metrics.stringWidth(value) / 2;   
    190.             g2d.setColor(Color.BLACK);   
    191.             g2d.drawString(value, (int) (p.getLabelPosition().getX() - w),   
    192.                 (int) (p.getLabelPosition().getY()));   
    193.         }   
    194.     }   
    195.   
    196.     private static void createGuiAndShow() {   
    197.         JFrame frame = new JFrame("Pie with 3D Effect");   
    198.         frame.getContentPane().add(new Pies3D());   
    199.   
    200.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    201.         int sw = Toolkit.getDefaultToolkit().getScreenSize().width;   
    202.         int sh = Toolkit.getDefaultToolkit().getScreenSize().height;   
    203.         int w = 500;   
    204.         int h = 400;   
    205.         int x = (sw - w) / 2;   
    206.         int y = (sh - h) / 2 - 40;   
    207.         x = x > 0 ? x : 0;   
    208.         y = y > 0 ? y : 0;   
    209.         frame.setBounds(x, y, w, h);   
    210.         frame.setVisible(true);   
    211.     }   
    212.   
    213.     public static void main(String[] args) {   
    214.         createGuiAndShow();   
    215.     }   
    216. }  
    217. package test;   
    218.   
    219. import java.awt.Color;   
    220. import java.awt.geom.Arc2D;   
    221. import java.awt.geom.Area;   
    222. import java.awt.geom.GeneralPath;   
    223. import java.awt.geom.Point2D;   
    224.   
    225. class Pie {   
    226.     private Arc2D arc;   
    227.     private Area frontWall;   
    228.     private Area leftWall;   
    229.     private Area rightWall;   
    230.     private Color color;   
    231.     private int shadowDepth;   
    232.     private Pie selectedPie;   
    233.     private Point2D labelPosition;   
    234.     private double shiftDis = 8; // 被选中的饼图在他的中线上移动的距离   
    235.     private double value;   
    236.   
    237.     public Pie(Arc2D arc, Color color, int shadowDepth, double value) {   
    238.         this.arc = arc;   
    239.         this.color = color;   
    240.         this.value = value;   
    241.         this.shadowDepth = shadowDepth;   
    242.   
    243.         Arc2D arcBottom = new Arc2D.Double(arc.getX(), arc.getY() + shadowDepth, arc.getWidth(),   
    244.             arc.getHeight() + 0, arc.getAngleStart(), arc.getAngleExtent(), Arc2D.CHORD);   
    245.         Point2D[] topPs = getPointsOfArc(arc);   
    246.         Point2D[] bottomPs = getPointsOfArc(arcBottom);   
    247.   
    248.         // Front wall   
    249.         GeneralPath font = new GeneralPath();   
    250.         font.moveTo(topPs[1].getX(), topPs[1].getY());   
    251.         font.lineTo(topPs[2].getX(), topPs[2].getY());   
    252.         font.lineTo(bottomPs[2].getX(), bottomPs[2].getY());   
    253.         font.lineTo(bottomPs[1].getX(), bottomPs[1].getY());   
    254.         font.closePath();   
    255.         this.frontWall = new Area(arcBottom);   
    256.         this.frontWall.add(new Area(font));   
    257.   
    258.         // Left wall   
    259.         GeneralPath left = new GeneralPath();   
    260.         left.moveTo(topPs[0].getX(), topPs[0].getY());   
    261.         left.lineTo(topPs[1].getX(), topPs[1].getY());   
    262.         left.lineTo(bottomPs[1].getX(), bottomPs[1].getY());   
    263.         left.lineTo(topPs[0].getX(), topPs[0].getY());   
    264.         left.closePath();   
    265.         this.leftWall = new Area(left);   
    266.   
    267.         // Right wall   
    268.         GeneralPath right = new GeneralPath();   
    269.         right.moveTo(topPs[0].getX(), topPs[0].getY());   
    270.         right.lineTo(topPs[2].getX(), topPs[2].getY());   
    271.         right.lineTo(bottomPs[2].getX(), bottomPs[2].getY());   
    272.         right.lineTo(topPs[0].getX(), topPs[0].getY());   
    273.         right.closePath();   
    274.         this.rightWall = new Area(right);   
    275.   
    276.         // Label position: 四分之三处   
    277.         Point2D c = getArcCenter();   
    278.         Point2D m = getChordCenter();   
    279.   
    280.         double x = ((m.getX() + c.getX()) / 2 + m.getX()) / 2;   
    281.         double y = ((m.getY() + c.getY()) / 2 + m.getY()) / 2;   
    282.         labelPosition = new Point2D.Double(x, y);   
    283.     }   
    284.   
    285.     // 取得Arc上的三个点,在对Arc: center, left, right.   
    286.     public static Point2D[] getPointsOfArc(Arc2D arc) {   
    287.         Point2D[] points = new Point2D[3];   
    288.         Point2D center = new Point2D.Double(arc.getCenterX(), arc.getCenterY());   
    289.         Point2D left = new Point2D.Double(arc.getStartPoint().getX(), arc.getStartPoint().getY());   
    290.         Point2D right = new Point2D.Double(arc.getEndPoint().getX(), arc.getEndPoint().getY());   
    291.         points[0] = center;   
    292.         points[1] = left;   
    293.         points[2] = right;   
    294.   
    295.         return points;   
    296.     }   
    297.   
    298.     public Pie getSelectedPie() {   
    299.         if (selectedPie == null) {   
    300.             selectedPie = createSeletecdPie();   
    301.         }   
    302.   
    303.         return selectedPie;   
    304.     }   
    305.   
    306.     private Pie createSeletecdPie() {   
    307.         // 沿中线方向移动5个单位   
    308.         Point2D[] ps = getPointsOfArc(arc);   
    309.         Point2D c = ps[0];   
    310.         Point2D m = new Point2D.Double((ps[1].getX() + ps[2].getX()) / 2,   
    311.             (ps[1].getY() + ps[2].getY()) / 2);   
    312.         double dis = Math.sqrt((m.getX() - c.getX()) * (m.getX() - c.getX())   
    313.                 + (m.getY() - c.getY()) * (m.getY() - c.getY()));   
    314.   
    315.         double deltaX = shiftDis * (m.getX() - c.getX()) / dis;   
    316.         double deltaY = shiftDis * (m.getY() - c.getY()) / dis;   
    317.   
    318.         Arc2D shiftArc = (Arc2D) arc.clone();   
    319.         shiftArc   
    320.             .setFrame(arc.getX() + deltaX, arc.getY() + deltaY, arc.getWidth(), arc.getHeight());   
    321.   
    322.         return new Pie(shiftArc, color, shadowDepth, value);   
    323.     }   
    324.   
    325.     public Arc2D getArc() {   
    326.         return arc;   
    327.     }   
    328.   
    329.     public void setArc(Arc2D arc) {   
    330.         this.arc = arc;   
    331.     }   
    332.   
    333.     public Area getFrontWall() {   
    334.         return frontWall;   
    335.     }   
    336.   
    337.     public void setFrontWall(Area frontWall) {   
    338.         this.frontWall = frontWall;   
    339.     }   
    340.   
    341.     public Area getLeftWall() {   
    342.         return leftWall;   
    343.     }   
    344.   
    345.     public void setLeftWall(Area leftWall) {   
    346.         this.leftWall = leftWall;   
    347.     }   
    348.   
    349.     public Area getRightWall() {   
    350.         return rightWall;   
    351.     }   
    352.   
    353.     public void setRightWall(Area rightWall) {   
    354.         this.rightWall = rightWall;   
    355.     }   
    356.   
    357.     public Color getColor() {   
    358.         return color;   
    359.     }   
    360.   
    361.     public void setColor(Color color) {   
    362.         this.color = color;   
    363.     }   
    364.   
    365.     public Point2D getLabelPosition() {   
    366.         return labelPosition;   
    367.     }   
    368.   
    369.     public void setLabelPosition(Point2D labelPosition) {   
    370.         this.labelPosition = labelPosition;   
    371.     }   
    372.   
    373.     public double getValue() {   
    374.         return value;   
    375.     }   
    376.   
    377.     public void setValue(double value) {   
    378.         this.value = value;   
    379.     }   
    380.   
    381.     public Point2D getChordCenter() {   
    382.         Point2D[] ps = getPointsOfArc(arc);   
    383.         Point2D m = new Point2D.Double((ps[1].getX() + ps[2].getX()) / 2,   
    384.             (ps[1].getY() + ps[2].getY()) / 2);   
    385.   
    386.         return m;   
    387.     }   
    388.   
    389.     public Point2D getArcCenter() {   
    390.         Point2D[] ps = getPointsOfArc(arc);   
    391.         return ps[0];   
    392.     }   
    393. }  
    394.      
    395.    
    复制代码

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/6/235619468.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 10:48 , Processed in 0.308567 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表