swing205图表

本文主要探讨了Java Swing中的PieChart组件,包括如何显示PieChart以及实现选中效果的详细步骤,适合Java图形界面开发的学习者参考。

PieChat显示

在这里插入图片描述

package my;

import javax.swing.*;

public class Swing2
{
	private static void createGUI()
	{
		// JFrame指一个窗口,构造方法的参数为窗口标题
		// 语法:因为MyFrame是JFrame的子类,所以可以这么写
		JFrame frame = new MyFrame("Swing Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		// 设置窗口的其他参数,如窗口大小
		frame.setSize(500, 300);
		
		// 显示窗口
		frame.setVisible(true);
		
		
	}
	
	public static void main(String[] args)
	{
		// 此段代码间接地调用了 createGUI(),具体原理在 Swing高级篇 里讲解
		// 初学者先照抄此代码框架即可
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run()
			{
				createGUI();
			}
		});

	}
}

package my;

import javax.swing.*;
import java.awt.*;

public class MyFrame extends JFrame
{

	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new BorderLayout());

		PieChart chart = new PieChart();
		root.add(chart, BorderLayout.CENTER);
		
		chart.addPart(70, "A", new Color(0x00CDCD));
		chart.addPart(20, "B", new Color(0xFFC1C1));
		chart.addPart(10, "C", new Color(0xEEE8AA));

	}

	
}

package my;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Arc2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PieChart extends JPanel
{
	// 数据:Pie表示每一小块
	private List<Part> partList = new ArrayList<>();
	
	
	// color如果为null,则由内部自动分配
	public void addPart (double amount, Object tag, Color color)
	{		
		if(amount <=0) return;
		
		Part p = new Part();
		p.amount = amount;
		p.tag = tag;
		p.color = color;
		if(color == null)
		{
			int rgb = new Random().nextInt(0xFFFFFF);			
			p.color = new Color( rgb) ;
		}
		
		partList.add( p );
	}
	
	// 根据每一个饼的数值,分配角度比例,自动分配颜色
	private void calculate()
	{
		if(partList.size() == 0) return;
	
		// 求出总数量
		int totalAmount = 0;
		for(Part p : partList) 
			totalAmount += p.amount;
		
		// 分配每一份所占的角度	
		int totalDegrees = 0;
		for(int i=0; i<partList.size();i++)
		{
			Part p = partList.get(i);
			p.degree = (int) (360 * p.amount / totalAmount);
			if(p.degree <3) 
				p.degree = 3; // 有的份额太少。是低分配3度角吧			
			if(i == partList.size() -1)
				p.degree = 360 - totalDegrees; // 确保占满360度			
			
			totalDegrees += p.degree;
		}
		
		// 取得一个最大的正文形
		int width = getWidth();
		int height = getHeight();
		System.out.printf("width: %d, height: %d \n", width, height);
		//Rectangle rect = new Rectangle(0,0,200,200);
		int w = width;
		int h = width;
		if( h > height)
		{
			h = height;
			w = height;
		}
		Rectangle rect = new Rectangle((width-w)/2, (height-h)/2, w, h);		
		rect.grow(-4,-4); // 往里缩一点
		
		// 计算每一个扇形的形状
		int start = 90;
		for(Part p : partList)
		{
			p.shape = new Arc2D.Double(rect, start , p.degree,Arc2D.PIE);
			start += p.degree;
		}
	}
	
	@Override
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		int width = getWidth();
		int height = getHeight();
		Graphics2D g2d = (Graphics2D) g;
		
		// 平滑绘制 ( 反锯齿 )
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		// 计算出每一份额的角度和扇形
		this.calculate();
		
		for(Part p : partList)
		{
			if(p.shape != null) 
			{
				g2d.setPaint( p.color);
				g2d.fill( p.shape );
			}
		}
	}
	
	//////////////////////////////////////
	private static class Part
	{
		double amount;  // 该块区域所代表的数量
		int degree;  // 根据amount经计算得到
		Color color; // 图例颜色 
		Object tag;  // 相关数据对象,由外部指定
		Arc2D shape; // 实际绘制占据的形状
	}
	
}

PieChat选中效果

在这里插入图片描述

package my;

import javax.swing.*;
import java.awt.*;

public class MyFrame extends JFrame
{

	public MyFrame(String title)
	{
		super(title);

		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new BorderLayout());

		PieChart chart = new PieChart();
		root.add(chart, BorderLayout.CENTER);
		
		chart.addPart(70, "A", new Color(0x00CDCD));
		chart.addPart(20, "B", new Color(0xFFC1C1));
		chart.addPart(10, "C", new Color(0xEEE8AA));

		chart.setPartClickedListener(new PieChart.PartClickedListener() {
			@Override
			public void partClicked(Object tag)
			{
				System.out.println("点中了分区: " + tag);
			}
		});
	}

	
}

package my;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Arc2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PieChart extends JPanel
{
	// 数据:Pie表示每一小块
	private List<Part> partList = new ArrayList<>();
	
	public PieChart()
	{
		this.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e)
			{	
				onMouseClicked(e);
			}			
		});
	}
	
	private void onMouseClicked(MouseEvent e)
	{
		// 被选中的分区
		Part activePart = null; 
		
		// 判断点中了哪一个小块
		for(Part p : partList)
		{
			if(p.shape == null) continue;
			if(p.shape.contains(e.getX(), e.getY()))
			{
				p.selected = true;
				activePart = p;
			}
			else
			{
				p.selected = false;
			}
		}
		
		if( activePart != null)
		{
			repaint();
			
			// 调用这个接口
			if(this.partClickedListener != null)
			{
				partClickedListener.partClicked( activePart.tag);
			}
		}		
	}
	
	//////////// 自定义事件处理 /////////////
	public interface PartClickedListener
	{
		public void partClicked(Object tag);
	}
	private PartClickedListener partClickedListener;
	
	public void setPartClickedListener(PartClickedListener listener)
	{
		this.partClickedListener = listener;
	}
	
	
	// color如果为null,则由内部自动分配
	public void addPart (double amount, Object tag, Color color)
	{		
		if(amount <=0) return;
		
		Part p = new Part();
		p.amount = amount;
		p.tag = tag;
		p.color = color;
		if(color == null)
		{
			int rgb = new Random().nextInt(0xFFFFFF);			
			p.color = new Color( rgb) ;
		}
		
		partList.add( p );
	}
	
	// 提供给调用者,可以用于绘制图例
	public List<Part> getPartList()
	{
		return this.partList;
	}
	
	// 根据每一个饼的数值,分配角度比例,自动分配颜色
	private void calculate()
	{
		if(partList.size() == 0) return;
	
		// 求出总数量
		int totalAmount = 0;
		for(Part p : partList) 
			totalAmount += p.amount;
		
		// 分配每一份所占的角度	
		int totalDegrees = 0;
		for(int i=0; i<partList.size();i++)
		{
			Part p = partList.get(i);
			p.degree = (int) (360 * p.amount / totalAmount);
			if(p.degree <3) 
				p.degree = 3; // 有的份额太少。是低分配3度角吧			
			if(i == partList.size() -1)
				p.degree = 360 - totalDegrees; // 确保占满360度			
			
			totalDegrees += p.degree;
		}
		
		// 取得一个最大的正文形
		int width = getWidth();
		int height = getHeight();
		//System.out.printf("calculate: width: %d, height: %d \n", width, height);
		//Rectangle rect = new Rectangle(0,0,200,200);
		int w = width;
		int h = width;
		if( h > height)
		{
			h = height;
			w = height;
		}
		Rectangle rect = new Rectangle((width-w)/2, (height-h)/2, w, h);		
		rect.grow(-4,-4); // 往里缩一点
		
		// 计算每一个扇形的形状
		int start = 90;
		for(Part p : partList)
		{
			p.shape = new Arc2D.Double(rect, start , 0-p.degree,Arc2D.PIE);
			start -= p.degree;
		}
	}
	
	@Override
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		int width = getWidth();
		int height = getHeight();
		Graphics2D g2d = (Graphics2D) g;
		//System.out.printf("* width: %d, height: %d \n", width, height);
		
		// 平滑绘制 ( 反锯齿 )
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		// 计算出每一份额的角度和扇形
		this.calculate();
		
		for(Part p : partList)
		{
			if(p.shape != null) 
			{
				g2d.setPaint( p.color);
				g2d.fill( p.shape );
				
				if(p.selected)
				{
					g2d.setPaint(Color.GRAY);
					g2d.setStroke(new BasicStroke(2));
					g2d.draw(p.shape);
				}
			}
		}
	}
	
	//////////////////////////////////////
	private static class Part
	{
		double amount;  // 该块区域所代表的数量
		int degree;  // 根据amount经计算得到
		Color color; // 图例颜色 
		Object tag;  // 相关数据对象,由外部指定
		Arc2D shape; // 实际绘制占据的形状
		boolean selected;// 是否为选中状态
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值