2016-12-12 24 views
2

私の主なプロジェクトでは、JFreeChartを使用してフレーム内にヒストグラムをプロットするクラスがあります。そのフレームから、ヒストグラムをユーザーが望むビンの数で置き換えたいと思っています。同じフレームでヒストグラムを再計算し、JFreechartを使用して再プロットする

私はこれを行うために、テキストフィールドとボタンが付いたメニューを追加しました。ここでは、ユーザーはビンの数を選択できます。彼がボタンを押すと、フレーム全体が新しい数のビンで再吐されます。

私の問題は、ちょうどプロットされません、古いフレームが処分されますが、何かをプロットするのではなく、空のフレームを作成することです。エラーや例外は発生しませんので、どこに問題があるのか​​わかりません。私はそれがJChartクラスやデータセットと関係があると思われますが、正確に何が動作していないのかの情報は見つかりません。

私のコードからMCVEコードを作成しようとしました。呼ばれる3枚のTIFF画像:

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

は(彼らがどのように見えるかの質問には関係ありませんが、それらはすべて同じイメージすることができる)私は16、デフォルトのビンサイズ2^16 = 16384でヒストグラムを作成しますビット。次に、ユーザーがメニューからサイズを変更できるようにします。更新

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

:行うには、私は、メソッド「changeBinsSize」と「再表示」を使用することを私はランダムな写真の代わりにTIFFをダウンロードするには、コードを変更し、すべてのチャネルが同じ写真です。

私は間違って何を見ているのですか?私は何時間も間違っているのを見てきましたが、何も見つかりませんでした。

+2

ビューを削除しないでください。データセットを更新します。あなたの[mcve]では、[URL]を使って投稿した画像にアクセスします(ここ[http://stackoverflow.com/a/10862262/230513])。図のように合成画像を使用する[here](http://stackoverflow.com/a/15982915/230513); [ここ](http://stackoverflow.com/a/12228640/230513)に示すように、 'UIManager'アイコンを使用してください。 – trashgod

+0

@trashgod私はMCVEを更新しました。最初の答えが示すように、URLにアクセスして正しく動作するはずです。 ---データセットを更新しようとしましたが、シリーズを削除する方法はありません。プロジェクトでは、RGBシリーズに同じインデックスが付いていることが重要です。 http://www.jfree.org/jfreechart/api/javadoc/org/jfree/data/statistics/HistogramDataset.html – nck

+1

ああ、私はあなたのポイントを見ます。もっと下に。 – trashgod

答えて

3

changeBinsSize()の現在の実装では、になります。ビューコンポーネントを置き換えます。代わりに、モデルを更新するとリスニング・ビューは自動的に更新されます。

私はデータセットを更新しようとしましたが、シリーズを削除する方法はありません。

HistogramDatasetの方法は、ビンの数の関数としてデータセットの内部状態を調整します。その結果、新しいビン数をパラメータとしてに渡して元のイメージサンプルからdatasetを再作成する必要があります。 setDataset()メソッドXYPlotを使用してデータセットを置き換えます。これにより、リスニングプロットが更新されるように通知されます。完全な例はhereです。

+0

ありがとうございました。私はそのXYPlotクラスを見るのに慣れてきました。データオブジェクトの直接の代わりにそれを扱わなければならないのはかなり奇妙です。 – nck

関連する問題