Changing JFreeChart dynamic colors dynamically?

I am trying to show a histogram of an image and show only some colors. I already did this with JFreeChart and createXYLineChart and got all the data by iterating all the pixels.

To speed this up, I am trying to do this using "createHistogram". I followed this code .

To update the chart with new values, I used these two methods:

XYPlot plot = (XYPlot) chart.getPlot(); plot.setDataset(setHistogram(red, green, blue)); 

Configure the Histogram of the method that HistogramDataset returns, depending on which checkbox is activated (Boolean red, green, and blue).

This works correctly as intended.

The second thing I have to do when I do this is updating the colors of each series, because otherwise they get the default value. I did this more or less with the same procedure as with the values:

 private void setHistogramColors(boolean red, boolean green, boolean blue) { XYPlot plot = (XYPlot) chart.getPlot(); XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer(); renderer.setBarPainter(new StandardXYBarPainter()); Paint[] paintArray = null; if (red) { if (green) { if (blue) { paintArray = new Paint[3]; paintArray[0] = new Color(0x80ff0000, true);// translucent red, green & blue paintArray[1] = new Color(0x8000ff00, true); paintArray[2] = new Color(0x800000ff, true); } else { paintArray = new Paint[2]; paintArray[0] = new Color(0x80ff0000, true); paintArray[1] = new Color(0x8000ff00, true); } } else { paintArray = new Paint[1]; paintArray[0] = new Color(0x80ff0000, true); } } else if (green) { if (blue) { paintArray = new Paint[2]; paintArray[0] = new Color(0x8000ff00, true); paintArray[1] = new Color(0x800000ff, true); } else { paintArray = new Paint[1]; paintArray[0] = new Color(0x8000ff00, true); } } else if (blue){ paintArray = new Paint[1]; paintArray[0] = new Color(0x800000ff, true); } else { return; } plot.setDrawingSupplier(new DefaultDrawingSupplier( paintArray, DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE)); } 

But for what I see, this only works when I draw the code for the first time, and the following stories from different episodes will take on the sames colors. Here is an example: RGB is the color that they should be: [ 2] When I update red, you get to the green histogram and green to blue:

Is there any way to fix this?

+2
source share
1 answer

Based on your snippet and comment , it looks like you are trying to change the display by adding and removing a series from a dataset in your handlers. Instead of changing the model, change the visibility of the series in the view. In this case, you can specify each Action flag, as shown here and below. Note in particular that VisibleAction uses a series index that matches the corresponding color in a custom DrawingSupplier .

red

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.Paint; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.awt.image.Raster; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.DefaultDrawingSupplier; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.StandardXYBarPainter; import org.jfree.chart.renderer.xy.XYBarRenderer; import org.jfree.data.statistics.HistogramDataset; /** * @see https://stackoverflow.com/q/40537278/230513 * @see https://stackoverflow.com/q/11870416/230513 * @see https://stackoverflow.com/a/28519356/230513 */ public class Histogram { private static final int BINS = 256; private final BufferedImage image = getImage(); private HistogramDataset dataset; private XYBarRenderer renderer; private BufferedImage getImage() { try { return ImageIO.read(new URL( "http://i.imgur.com/kxXhIH1.jpg")); } catch (IOException e) { e.printStackTrace(System.err); } return null; } private ChartPanel createChartPanel() { // dataset dataset = new HistogramDataset(); Raster raster = image.getRaster(); final int w = image.getWidth(); final int h = image.getHeight(); double[] r = new double[w * h]; r = raster.getSamples(0, 0, w, h, 0, r); dataset.addSeries("Red", r, BINS); r = raster.getSamples(0, 0, w, h, 1, r); dataset.addSeries("Green", r, BINS); r = raster.getSamples(0, 0, w, h, 2, r); dataset.addSeries("Blue", r, BINS); // chart JFreeChart chart = ChartFactory.createHistogram("Histogram", "Value", "Count", dataset, PlotOrientation.VERTICAL, true, true, false); XYPlot plot = (XYPlot) chart.getPlot(); renderer = (XYBarRenderer) plot.getRenderer(); renderer.setBarPainter(new StandardXYBarPainter()); // translucent red, green & blue Paint[] paintArray = { new Color(0x80ff0000, true), new Color(0x8000ff00, true), new Color(0x800000ff, true) }; plot.setDrawingSupplier(new DefaultDrawingSupplier( paintArray, DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE)); ChartPanel panel = new ChartPanel(chart); panel.setMouseWheelEnabled(true); return panel; } private JPanel createControlPanel() { JPanel panel = new JPanel(); panel.add(new JCheckBox(new VisibleAction(0))); panel.add(new JCheckBox(new VisibleAction(1))); panel.add(new JCheckBox(new VisibleAction(2))); return panel; } private class VisibleAction extends AbstractAction { private final int i; public VisibleAction(int i) { this.i = i; this.putValue(NAME, (String) dataset.getSeriesKey(i)); this.putValue(SELECTED_KEY, true); renderer.setSeriesVisible(i, true); } @Override public void actionPerformed(ActionEvent e) { renderer.setSeriesVisible(i, !renderer.getSeriesVisible(i)); } } private void display() { JFrame f = new JFrame("Histogram"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(createChartPanel()); f.add(createControlPanel(), BorderLayout.SOUTH); f.add(new JLabel(new ImageIcon(image)), BorderLayout.WEST); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(() -> { new Histogram().display(); }); } } 
+2
source

Source: https://habr.com/ru/post/982498/


All Articles