2017-10-17 20 views
0

저는 miscropy 프로그램을위한 플러그인을 작성 중이며 repaint() 메소드에 문제가 있습니다.자바 jpanel과 repaint() 또는 : 스윙의 다시 그리기에 리스너를 추가 할 수 있습니까?

짧은 질문 : JPanel의 페인트가 완료 되 자마자 정보를 얻거나 코드를 동기화 할 수있는 방법이 있습니까?

세부 버전 :

JPanel과에 XY 차트에 데이터 세트를 플롯 및 jfree.chart를 사용하여 표시 할 수 내 프로그램; programm의 또 다른 부분에서는 이미지로 저장하고 저장하려는 많은 데이터 세트 (~ 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)을 좋아하지 않아 ... 그것 없이는 내가 repaint를 요구하고 있지만 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. 갱신 A가 JLabel (즉 이미 프레임에 추가 된)를 setIcon(...) 방법을 사용
  3. 위 단계는 PropertyChange를 생성한다 위에서 이미지를 사용 ImageIcon를 생성 패널
  4. BufferedImage 만들 이벤트가 아이콘 변경시. ProperChangeListener을 사용하여이 이벤트를 수신 할 수 있습니다. 이벤트를 받으면 1 - 4 단계를 반복하십시오.

체크 아웃 Screen Image. 보이지 않는 구성 요소의 이미지를 만드는 데 도움이됩니다.

참고 4-5 단계는 실제로 필요하지 않습니다. 방금 처리 한 플롯을 시각적으로 표시하도록 방금 추가했습니다.비주얼을 원하지 않는다면 JLabel에 현재 변환중인 플롯을 나타내는 텍스트 만 표시하면됩니다.

+0

1 단계 : 새 JPanel을 의미합니까, 아니면 기존의 JFrame (PlotSpectrum 클래스)을 사용할 수 있습니까? 내 코드에서 약간의 변경 사항이 있습니다. 이미지가있는 패널을 만들 수 있어야합니다 ... 시각화가 필요하지 않습니다 ImageIcon과 BufferedImage의 차이점은 무엇입니까? – schetefan24

+0

@ schetefan24 생각은 패널을 메모리에 생성하고 프레임에 추가하지 않는 것입니다. 문제는 패널이 언제 그려 지는지 모르기 때문입니다. 패널을 메모리에 만들고 패널 이미지를 직접 작성하면 스윙의 페인트 메커니즘이 아닌 프로세스를 제어 할 수 있습니다. – camickr

+0

가시성 및 이벤트 트리거를 약간 테스트했습니다. 가장 쉬운 방법은 저장을 시작하기 전에 전체 프레임을 보이지 않게 설정하고 이미지를 새로 고치려면 pack()을 호출하는 것입니다. D는 여전히 약간 더러워 보이지만 완벽하게 수행합니다 :) 그리고 시정에 대한 힌트를 주셔서 감사합니다. 그걸로 스윙 컨트롤에서 프레임을 제거하는 것 같습니다 – schetefan24