2013-06-28 53 views
2

我想問一個關於此Q的後續問題@trashgod的一個問題(How can I update a JFreeChart's appearance after it's been made visible?)。使用JSlider實時更新jFreeChart的透明度

我想給用戶一個JSlider來控制圖的透明度。我添加了一個JSlider和一個ChangeListener來重繪任何時候有一個JSlider更改。

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

但是,直到用戶用鼠標點擊圖形,纔會更新透明度。爲什麼這不起作用?

這裏的SSCCE(使用JFreeChart庫):「用來繪製單個餅圖地塊pie chart

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; 
     } 

    } 
} 

回答

3

的關鍵問題是,通知你已經修改了圖表

chart.fireChartChanged(); 

image

簡體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 http://stackoverflow.com/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); 
      } 
     }); 
    } 
} 
+0

這就是它!謝謝! – ryvantage