PieChat显示

package my;
import javax.swing.*;
public class Swing2
{
private static void createGUI()
{
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)
{
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);
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
{
private List<Part> partList = new ArrayList<>();
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;
if(i == partList.size() -1)
p.degree = 360 - totalDegrees;
totalDegrees += p.degree;
}
int width = getWidth();
int height = getHeight();
System.out.printf("width: %d, height: %d \n", width, height);
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;
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);
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
{
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;
}
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;
if(i == partList.size() -1)
p.degree = 360 - totalDegrees;
totalDegrees += p.degree;
}
int width = getWidth();
int height = getHeight();
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;
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;
Color color;
Object tag;
Arc2D shape;
boolean selected;
}
}