2017-10-17 9 views
0

私はmiscropyプログラム用のプラグインを作成しており、repaint()メソッドに問題があります。java jpanelとrepaint()または:スイングの再ペイントにリスナーを追加できますか?

短い質問: JPanelの再描画が完了するとすぐに情報を取得する方法や、コードを同期させる方法はありますか?

詳細版:

のJPanelに、XYグラフのデータのセットをプロットし、jfree.chartを使用してそれを表示することができます私のプログラム。プログラムの別の部分では、私は画像としてプロットして保存したい多くのデータセット(〜100)を持っています。私も解決策を見つけましたが、私は本当にそれが好きではありません。この問題は、JPanelのペイントステータスに関する通知に減らすことができます。私はこのソリューションを持っているすべての画像を保存しなければならない部分で

PlotSpectrum spectrumWindow = getTheWindow(); //pseudo code... 
// some stuff 
ti = storage.getImage(channel, slice, frame, position); 
spectrumWindow.plotData(false, andor.captureSpectrum(ti.pix), wave, 
       centerWave, fineGrating, exposureTime, 
       slitWidth, substractBackground); 
spectrumWindow.repaint(); // probably not necessary 
sleep(100);    // this annoys me... 
spectrumWindow.savePlot(path, true, config, null); 

spectrumWindowは、別のウィンドウに表示され、それはすべてが正常に動作しているJPanelのです。 しかし、私は本当にその睡眠(100)が好きではない...それなしでは、私は再塗りを求めているが、それはsavePlotがやっていることの "スナップショット"を保存しようとするまで行われていない。 ..)。私は知っている、他のスレッドとこれらの気がする同期の問題... 私はそれを必要としない遅いと私は長い間、再塗装が完了したらすぐに情報を得るための方法はありますか?私はおそらくリスナーでうまくいくかもしれませんが、モニターやsthに匹敵する解決法が良いでしょうか、それとも今では再描画している方法でしょうか(私の知る限りでは存在しません) メインGUI(JPanel spectrumWindowを含む)と以前に貼り付けられたコードは異なるスレッドで実行されています。

おそらく私のコードの重要な部分は次のとおりです。大括弧が一致しないか、変数が宣言されていない場合は大変申し訳ありません。コードを削除しました。

おかげで、私はプロットし、画像として保存したい schetefan24

class PlotSpectrum extends ApplicationFrame // that extends JFrame 
{ 
public void plotData(boolean backgroundGiven, int[] spect, double[] wave_, 
        double centerWave, boolean fineGrating_, double exposureTime, 
        double slitWidth, boolean substractBackground) 
{ 
//process data and store internally 
replot(); 
} 

private void replot() 
{ 
XYSeries series = new XYSeries("Spectrum"); 
//add data to series 
XYSeriesCollection collection = new XYSeriesCollection(series); 
//setting up some labels and such stuff... 
JFreeChart chart = ChartFactory.createXYLineChart(
     title, 
     "Wavelength [nm]", 
     yLabel, 
     collection, 
     PlotOrientation.VERTICAL, 
     false, 
     false, 
     false 
    ); 
dataPanel.add(new ChartPanel(chart)); // this is contained in a Frame 
} 

public void savePlot(String path, boolean overWriteAll, HashMap<String,String> config, int[][] addData) 
{ 
File output = new File(path); 
//some more stuff, ask overwrite etc 
if(image) 
{ 
    BufferedImage im = createImage(); 
    String extension = path.substring(path.lastIndexOf(".")+1, path.length()); 
    ImageIO.write(im, extension, output); 
} else { 
//that is an textexport, works fine 
} 
} 

public BufferedImage createImage() 
{ 
    JPanel panel = (JPanel) flipChart.getSelectedComponent(); 
    int w = panel.getWidth(); 
    int h = panel.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g = bi.createGraphics(); 
    panel.paint(g); 
    return bi; 
} 
} 

答えて

1

  1. 非可視パネルにデータを追加します。
  2. 上記ステップはPropertyChangeを生成する必要がsetIcon(...)方法
  3. を用い
  4. 上記更新 JLabel(すなわち、既にフレームに追加されている)からの画像を用い ImageIconを作成パネル
  5. BufferedImageを作成アイコンが変更されたときのイベント。 ProperChangeListenerを使用して、このイベントを待機することができます。イベントを受け取ったら、手順1〜4を繰り返してください。

Screen Imageをチェックしてください。これは、目に見えないコンポーネントのイメージを作成するのに役立ちます。

手順4-5は必要ありません。私はそれらを追加したので、処理中のプロットのビジュアルが表示されます。ビジュアルを必要としない場合は、現在変換されているプロットを示すテキストをJLabelに表示するだけです。

+0

to step 1:新しいJPanelを意味するのですか、既に存在するJFrame(PlotSpectrumクラス)を使用できますか? 私のコードで若干の変更がありました画像を持つPanelだけを作成できるはずです...視覚化は必要ありません ImageIconとBufferedImageとの違いは何ですか? – schetefan24

+0

@ schetefan24アイデアは、パネルをメモリに作成し、それをフレームに追加しないことです。なぜなら、パネルがいつペイントされるのかわからないからです。パネルをメモリに作成し、パネルの独自のイメージを作成することで、Swingのペイントメカニズムではなく、プロセスを制御しています。 – camickr

+0

私は可視性とイベントトリガーを少しテストしました: 最も簡単な方法は、保存を開始する前にフレーム全体を表示しないようにすることです。画像を更新するためにpack()を呼び出すよりも、完璧に実行します:)と可視性のヒントのおかげで;それは私がそれによってスイングのコントロールからフレームを削除するようです – schetefan24

関連する問題