2016-12-12 3 views
2

In meinem Hauptprojekt habe ich eine Klasse, die ein Histogramm in einem Frame mit JFreeChart plottet. Von diesem Frame möchte ich in der Lage sein, das Histogramm mit der Anzahl der vom Benutzer gewünschten Bins neu zu plotten.Erneutes Berechnen des Histogramms in demselben Frame und erneutes Plotten mithilfe von JFrechart

Um das zu tun, habe ich ein Menü mit einem Textfeld und einer Schaltfläche hinzugefügt, wo der Benutzer die Anzahl der Fächer auswählen kann. Wenn er den Knopf drückt, wird der ganze Rahmen mit der neuen Anzahl von Behältern neu gepoolt.

Mein Problem ist, dass es einfach nicht geplottet wird, der alte Rahmen wird entsorgt, aber anstatt etwas zu plotten, erzeugt es nur einen leeren Rahmen. Ich bekomme keine Fehler oder Ausnahmen, daher habe ich keine Ahnung, wo das Problem liegen könnte. Ich vermute, dass es etwas mit der JChart-Klasse oder dem JChart-Datensatz zu tun hat, aber ich kann keine Informationen darüber finden, was genau nicht funktioniert.

Ich habe versucht, einen MCVE-Code aus meinem Code zu erstellen. Von drei TIFF-Bildern genannt:

"IMG_7911.CR2.R.TIFF", "IMG_7911.CR2.G.TIFF", "IMG_7911.CR2.B.TIFF" 

(nicht für die Frage aus, wie sie aussehen, sie alle könnten das gleiche Bild sein) erstelle ich ein Histogramm mit einer Standard-Binabmessung 2^16 = 16384, 16 Bits. Dann möchte ich, dass der Benutzer die Größe eines Menüs ändern kann. Zu tun, dass ich die Methode „changeBinsSize“ verwenden und „Neuanzeige“:

package mcve; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Paint; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 
import java.awt.image.Raster; 
import java.awt.image.RenderedImage; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
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; 

public class HistogramRAW { 

private int BINS; 
private Raster raster;//Load image 
private String filename; 
private RenderedImage image; 

private JFreeChart chart; //Create histogram 
private ChartPanel panel; 
private HistogramDataset dataset; 
private XYBarRenderer renderer; 
private JMenuBar menuBar; //Menubar 
private JMenu options; 

private JTextField numBINS; 
private JFrame f; //Frame 

public HistogramRAW(String filename) { 
    this.filename = filename; 
    this.BINS = 16384; 
} 

private void getImage(String filename) { 
    try { 
     URL url = new URL(filename); 
     final BufferedImage bi = ImageIO.read(url); 
     raster=bi.getRaster(); 
     image=(RenderedImage)bi; 

    } catch (IOException e) { 
     e.printStackTrace(System.err); 
     return; 
    } 
} 

private ChartPanel createChartPanel() { 
    // dataset 
    dataset = new HistogramDataset(); 
    getImage(filename); //Put it here to get width and height from it 
    final int w = image.getWidth(); 
    final int h = image.getHeight(); 

    double[] buffer = new double[w * h]; 

    //R 
    buffer = raster.getSamples(0, 0, w, h, 0, buffer); 
    dataset.addSeries("red", buffer, BINS); 

    //G 
    getImage(filename); 
    buffer = raster.getSamples(0, 0, w, h, 0, buffer); 
    dataset.addSeries("green", buffer, BINS); 

    //B 
    getImage(filename); 
    buffer = raster.getSamples(0, 0, w, h, 0, buffer); 
    dataset.addSeries("blue", buffer, BINS); 

    //chart 
    chart = ChartFactory.createHistogram("Histogram", "", 
      "", dataset, PlotOrientation.VERTICAL, false, true, false); 
    //Set colors 
    XYPlot plot = (XYPlot) chart.getPlot(); 
    renderer = (XYBarRenderer) plot.getRenderer(); 
    renderer.setBarPainter(new StandardXYBarPainter()); 
    Paint[] paintArray = { // translucent red, green blue 
     new Color(0x800000ff, true),//blue 
     new Color(0x8000ff00, true),//green1 
     new Color(0x80ff0000, true)//red 
    }; 
    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)); 

    //Create panel with chart 
    panel = new ChartPanel(chart); 
    panel.setMouseWheelEnabled(true); 

    return panel; 
} 

private JMenuBar setMenuBar() { 
    menuBar = new JMenuBar(); //Create Menubar 

    options = new JMenu("Options"); // menu. 
    options.setMnemonic(KeyEvent.VK_O); 
    menuBar.add(options); 

    JPanel binsPanel = new JPanel(); //Change BINS size button 
    numBINS = new JTextField("" + BINS); 
    binsPanel.add(numBINS); 
    JButton binsButton = new JButton("changeBins"); 
    binsButton.addActionListener(new MenuActionListener()); 
    binsPanel.add(binsButton); 
    options.add(binsPanel); 

    return menuBar; 
} 

public void display() throws CloneNotSupportedException { 
    f = new JFrame("Histogram"); 
    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    f.add(createChartPanel(), BorderLayout.CENTER); 
    f.setJMenuBar(setMenuBar()); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
} 

public void reDisplay() throws CloneNotSupportedException { 
    f.add(createChartPanel(), BorderLayout.CENTER); 
    f.setJMenuBar(setMenuBar()); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 

} 

public void changeBinsSize() { 
    try { 
     BINS = Integer.parseInt(numBINS.getText()); 
     f.removeAll(); 
     f.dispose(); 
     System.out.println("" + BINS); 
     reDisplay(); 
    } catch (CloneNotSupportedException e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) { 
    try { 
     HistogramRAW hist = new HistogramRAW("https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/245px-Wikipedia-logo-v2.svg.png"); 
     hist.display(); 
    } catch (CloneNotSupportedException e) { 
     e.printStackTrace(); 

    } 
} 

private class MenuActionListener implements ActionListener { 

    public void actionPerformed(ActionEvent e) { 
     if (e.getActionCommand().equals("changeBins")) { 
      changeBinsSize(); 
     } 
    } 
} 
} 

aktualisieren: Ich habe den Code modifizierte, um ein zufälliges Foto anstelle die tiff herunterladen und alle Kanäle das gleiche Foto.

Kann jemand sehen, was mache ich falsch ?, Ich habe seit Stunden versucht zu sehen, was los ist, aber ich kann nichts finden.

+2

Entfernen Sie nicht die Ansicht. Aktualisieren Sie das Dataset. In Ihrem [mcve], Zugriff auf gepostete Bilder über 'URL', wie hier [hier] (http://stackoverflow.com/a/10862262/230513); Verwende synthetische Bilder wie hier gezeigt [http://stackoverflow.com/a/15982915/230513]; oder verwenden Sie "UIManager" -Symbole, wie hier [hier] (http://stackoverflow.com/a/12228640/230513). – trashgod

+0

@trashgod Ich habe gerade den MCVE aktualisiert, ich denke, jetzt sollte es richtig funktionieren, indem Sie auf die URL zugreifen, wie Ihre erste Antwort vermuten lässt. --- Ich habe auch versucht, den Datensatz zu aktualisieren, aber ich sehe keine Möglichkeit, Serien zu löschen, und für mein Projekt ist es wichtig, dass die RGB-Serie den gleichen Index haben, da ich einige Tasten habe, die auf sie wirken. http://www.jfree.org/jfreechart/api/javadoc/org/jfree/data/statistics/HistogramDataset.html – nck

+1

Ah, ich verstehe deinen Standpunkt; mehr unten. – trashgod

Antwort

3

Ihre aktuelle Implementierung von changeBinsSize() versucht, ersetzen die View-Komponente. Aktualisieren Sie stattdessen das Modell und die Wiedergabeansicht wird aktualisiert.

Ich habe versucht, den Datensatz zu aktualisieren, aber ich sehe keine Möglichkeit zum Löschen von Serien.

Die Methode von HistogramDataset stellt den internen Zustand des Datensatzes in Abhängigkeit von der Anzahl der Bins. Als Ergebnis müssen Sie die dataset aus den ursprünglichen Bildbeispielen neu erstellen und die neue Bin-Anzahl als Parameter an übergeben. Verwenden Sie die setDataset()-Methode von XYPlot, um das Dataset zu ersetzen, das den hörenden Plot benachrichtigt, sich selbst zu aktualisieren. Ein vollständiges Beispiel wird gezeigt here.

+0

Vielen Dank, das war's. Ich muss mich daran gewöhnen, diese XYPlot-Klasse zu betrachten. Es ist ziemlich merkwürdig, damit arbeiten zu müssen, anstatt direkt über die Datenobjekte. – nck

Verwandte Themen