使用JSlider实时更新jFreeChart的透明度

编程入门 行业动态 更新时间:2024-10-28 10:35:49
本文介绍了使用JSlider实时更新jFreeChart的透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想问这个问题和解答(从@trashgod看到JFreeChart的外观后,如何更新它的外观?).

I would like to ask a follow up question to this Q&A question (How can I update a JFreeChart's appearance after it's been made visible?) from @trashgod.

我正在尝试为用户提供 JSlider 来控制图形的透明度.我添加了 JSlider 和 ChangeListener 以便在JSlider发生更改时重新绘制.

I am trying to give the user a JSlider to control the transparency of the graphs. I added a JSlider and a ChangeListener to repaint whenever there is a JSlider change.

slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { chartPanel.repaint(); } });

但是,直到用户用鼠标单击"图形,透明度才会更新.为什么这行不通?

However, the transparency is not updated until the user "clicks" the graph with the mouse. Why isn't this working?

这是SSCCE(带有jFreeChart库):

Here's the SSCCE (with jFreeChart library):

import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GradientPaint; import java.math.BigDecimal; import java.math.BigInteger; import java.text.AttributedString; import java.text.DecimalFormat; import java.text.NumberFormat; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.basic.BasicButtonListener; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.labels.PieSectionLabelGenerator; import org.jfree.chart.labels.PieToolTipGenerator; import org.jfree.chart.plot.MultiplePiePlot; import org.jfree.chart.plot.PiePlot; import org.jfree.chart.title.LegendTitle; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.PieDataset; import org.jfree.util.TableOrder; /** * This example is similar to {@link MultiplePieChartDemo1}, but slices the * dataset by column rather than by row. */ public class MultiplePieChart extends JPanel { /** * Creates a sample dataset. * * @return A sample dataset. */ private static CategoryDataset createDataset() { BigInteger topSources_quan = new BigInteger("100"); BigInteger notTopSources_quan = new BigInteger("10"); DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(topSources_quan, "Included Sources", "Sales Quantity"); dataset.addValue(notTopSources_quan, "Not Included Sources", "Sales Quantity"); BigDecimal topSources_total = new BigDecimal("1450.34"); BigDecimal notTopSources_total = new BigDecimal("99.78"); dataset.addValue(topSources_total, "Included Sources", "Sales Total"); dataset.addValue(notTopSources_total, "Not Included Sources", "Sales Total"); return dataset; } /** * Creates a sample chart with the given dataset. * * @param dataset the dataset. * * @return A sample chart. */ private static JFreeChart createChart(CategoryDataset dataset, Dimension size, String chartTitle, boolean includeLegend, final JSlider slider) { JFreeChart chart = ChartFactory.createMultiplePieChart( chartTitle, // chart title dataset, // dataset TableOrder.BY_COLUMN, includeLegend, // include legend true, false ); chart.setBackgroundPaint(new GradientPaint(0, 0, new Color(240,240,240), 0, ((int)size.getHeight() / 2), new Color(200, 200, 200), true)); TextTitle title = new TextTitle(chartTitle == null? "" : chartTitle, new Font("Tahoma", Font.BOLD, 16)); chart.setTitle(title); if(includeLegend) { LegendTitle legend = chart.getLegend(); legend.setBackgroundPaint(new Color(0, 0, 0, 0)); legend.setItemFont(new Font("Tahoma", Font.PLAIN, 12)); legend.setBorder(0, 0, 0, 0); } MultiplePiePlot plot = (MultiplePiePlot) chart.getPlot(); JFreeChart stamper = plot.getPieChart(); if(dataset.getColumnCount() == 1) { stamper.getTitle().setFont(new Font("Tahoma", Font.PLAIN, 0)); } else { stamper.getTitle().setFont(new Font("Tahoma", Font.PLAIN, 12)); } stamper.setBackgroundPaint(new GradientPaint(0, 0, new Color(240,240,240), 0, ((int)size.getHeight() / 2), new Color(200, 200, 200), true)); plot.setOutlineStroke(null); plot.setBackgroundAlpha(.25f); JFreeChart subchart = plot.getPieChart(); final PiePlot p = (PiePlot) subchart.getPlot(); p.setBackgroundAlpha(0f); p.setOutlineStroke(null); p.setSectionPaint("Included Sources", new Color(0,100,255)); p.setSectionPaint("Not Included Sources", new Color(255, 50, 50)); p.setStartAngle(0); p.setLabelFont(new Font("Tahoma", Font.PLAIN, 9)); p.setForegroundAlpha(.6f); if(slider != null) { slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { float value = (float)slider.getValue() / (float)100; System.out.println("Setting foreground alpha:" + value); p.setForegroundAlpha(value); } }); } p.setMaximumLabelWidth(0.20); p.setLabelGenerator(null); PieToolTipGenerator cttg = new PieToolTipGenerator() { @Override public String generateToolTip(PieDataset dataset, Comparable key) { Number val = dataset.getValue(key); if(val instanceof BigDecimal) { DecimalFormat df = new DecimalFormat("$ #,##0.00"); return df.format(val.floatValue()); } else if(val instanceof BigInteger) { DecimalFormat df = new DecimalFormat("#,##0"); return df.format(val.intValue()); } else return val.toString(); } }; p.setToolTipGenerator(cttg); return chart; } /** * Creates a panel for the demo (used by SuperDemo.java). * * @return A panel. */ public static JPanel createPanel(final JFrame parentFrame, CategoryDataset dataset, Dimension size, String chartTitle, boolean includeLegend, JSlider slider) { JFreeChart chart = createChart(dataset, size, chartTitle, includeLegend, slider); final ChartPanel chartPanel = new ChartPanel(chart); chartPanel.setMouseWheelEnabled(true); if(size != null) chartPanel.setPreferredSize(size); if(slider != null) { slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { chartPanel.repaint(); } }); } return chartPanel; } public static void main(String[] args) { JFrame frame = new JFrame(); JSlider slider = new JSlider(); JFrame sliderFrame = new JFrame(); sliderFrame.add(slider); sliderFrame.pack(); JPanel panel = createPanel(frame, createDataset(), new Dimension(800, 500), "Sales", true, slider); frame.add(panel); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); frame.setLocationRelativeTo(null); sliderFrame.setLocation(frame.getLocationOnScreen().x + frame.getWidth() - slider.getWidth(), frame.getLocationOnScreen().y + frame.getHeight()); sliderFrame.setVisible(true); sliderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } static class CustomLabelGenerator implements PieSectionLabelGenerator { public String generateSectionLabel(PieDataset dataset, Comparable key) { if(dataset.getValue(key) instanceof BigInteger) { NumberFormat nf = new DecimalFormat("#,##0"); return nf.format(((BigInteger)dataset.getValue(key)).intValue()); } else if (dataset.getValue(key) instanceof BigDecimal) { NumberFormat nf = new DecimalFormat("$ #,##0.00"); return nf.format(((BigDecimal)dataset.getValue(key)).doubleValue()); } else { return dataset.getValue(key).toString(); } } public AttributedString generateAttributedSectionLabel( PieDataset dataset, Comparable key) { return null; } } }

推荐答案

关键问题是通知图表您已修改"饼图,用于绘制各个饼图."

The critical issue is to notify the chart that you've modified "the pie chart that is used to draw the individual pie plots."

chart.fireChartChanged();

简化的SSCCE:

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.math.BigDecimal; import java.math.BigInteger; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.MultiplePiePlot; import org.jfree.chart.plot.PiePlot; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.util.TableOrder; /** * @see stackoverflow/a/17370398/230513 * This example is similar to {@link MultiplePieChartDemo1}, but slices the * dataset by column rather than by row. */ public class MultiplePieChart extends JPanel { private JSlider slider = new JSlider(); private CategoryDataset createDataset() { BigInteger topSources = new BigInteger("100"); BigInteger notTopSources = new BigInteger("10"); DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(topSources, "Included Sources", "Sales Quantity"); dataset.addValue(notTopSources, "Not Included Sources", "Sales Quantity"); BigDecimal topSourcesTotal = new BigDecimal("1450.34"); BigDecimal notTopSourcesTotal = new BigDecimal("99.78"); dataset.addValue(topSourcesTotal, "Included Sources", "Sales Total"); dataset.addValue(notTopSourcesTotal, "Not Included Sources", "Sales Total"); return dataset; } private JFreeChart createChart() { final JFreeChart chart = ChartFactory.createMultiplePieChart( "Sales", createDataset(), TableOrder.BY_COLUMN, true, true, false); MultiplePiePlot plot = (MultiplePiePlot) chart.getPlot(); JFreeChart subchart = plot.getPieChart(); final PiePlot p = (PiePlot) subchart.getPlot(); p.setForegroundAlpha(0.5f); slider.setValue((int) (p.getForegroundAlpha() * 100)); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { float value = (float) slider.getValue() / (float) 100; p.setForegroundAlpha(value); chart.fireChartChanged(); } }); return chart; } public JPanel createChartPanel() { JFreeChart chart = createChart(); final ChartPanel chartPanel = new ChartPanel(chart) { @Override public Dimension getPreferredSize() { return new Dimension(800, 400); } }; return chartPanel; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { MultiplePieChart mpc = new MultiplePieChart(); JFrame frame = new JFrame(); frame.add(mpc.createChartPanel()); frame.add(mpc.slider, BorderLayout.SOUTH); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } }

更多推荐

使用JSlider实时更新jFreeChart的透明度

本文发布于:2023-06-07 22:10:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/568674.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:透明度   实时   JSlider   jFreeChart

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!