2013-07-08 2 views
0

나는 모두 더블 타입의 100,000 샘플의 배열을 가지고 있습니다. 나는이 배열을 표시하거나 플롯하여 한 번에 표시하는 대신 움직이는 차트/플롯 (동적)을 얻고 싶습니다. 누구든지 나를 도울 수 있습니까? 플롯에서 ee []와 y []는 어떤 처리 후에 얻어진다.JFreeChart를 사용하는 다이나믹 차트

private byte[] FileR(String filename) { 
    byte[] data = null; 
    AudioInputStream ais; 
    try { 
     File fileIn = new File(filename); 
     if (fileIn.exists()) { 
      ais = AudioSystem.getAudioInputStream(fileIn); 
      data = new byte[ais.available()]; 
      ais.read(data); 
     } 
    } catch (UnsupportedAudioFileException | IOException e) { 
     System.out.println(e.getMessage()); 
     throw new RuntimeException("Could not read " + filename); 
    } 
    return data; 
} 

private byte[] Capture(double t) throws LineUnavailableException { 
    AudioFormat format = new AudioFormat(48000, 16, 2, true, false); 
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); 
    line = (TargetDataLine) AudioSystem.getLine(info); 
    line.open(format); 
    line.open(); 
    int size = (int) (line.getBufferSize() * t); 
    byte[] b = new byte[size]; 
    line.start(); 
    line.read(b, 0, size); 
    return b; 
} 

private void plot(double[] ee, double[] y) { 
    XYSeries see = new XYSeries("Filtered"); 
    for (int i = 0; i < ee.length; i++) { 
     see.add(i, ee[i]); 
    } 
    XYSeriesCollection cee = new XYSeriesCollection(); 
    cee.addSeries(see); 
    XYItemRenderer ree = new StandardXYItemRenderer(); 
    NumberAxis rangeAxisee = new NumberAxis("Filtered"); 
    XYPlot subplot1 = new XYPlot(cee, null, rangeAxisee, ree); 
    subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); 
    XYSeries sy = new XYSeries("Noisy"); 
    for (int i = 0; i < y.length; i++) { 
     sy.add(i, y[i]); 
    } 
    XYSeriesCollection cy = new XYSeriesCollection(); 
    cy.addSeries(sy); 
    XYItemRenderer ry = new StandardXYItemRenderer(); 
    NumberAxis rangeAxisy = new NumberAxis("Noisy"); 
    XYPlot subplot2 = new XYPlot(cy, null, rangeAxisy, ry); 
    subplot2.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); 
    CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain")); 
    plot.setGap(10.0); 
    plot.add(subplot1); 
    plot.add(subplot2); 
    plot.setOrientation(PlotOrientation.VERTICAL); 
    JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true); 
    panel = new ChartPanel(chart, true, true, true, false, true); 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(750, 500); 
    frame.add(panel, BorderLayout.CENTER); 
    frame.setVisible(true); 
} 
+0

무엇을 의미합니까? 런타임에 변경된다는 의미입니까? 애니메이션? –

+0

아마도 여기에 표시된 방법 중 하나를 찾고있을 것입니다 (http://stackoverflow.com/q/5048852/230513). – trashgod

+0

올리버 왓킨스, 아마도 내 질문이 있습니다. 나 좀 도와 줄 수있어? –

답변

0

당신은이 모든 데이터에서오고있다 스레드이 필요합니다. 예를 들어 백엔드에서. 그런 다음 차트에 대한 새로운 데이터 집합이있을 때마다 이벤트 발송 스레드을 통해 차트를 업데이트해야합니다. 차트 데이터가 일정한 간격으로 오게되면 매우 쉽게 푸시됩니다. 즉, 푸시 (즉, 데이터가 더 무작위 임) 인 경우 조금 더 까다 롭습니다.

플롯 방법에서 모든 GUI 생성을 제거

JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true); 
panel = new ChartPanel(chart, true, true, true, false, true); 
JFrame frame = new JFrame(); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
frame.setSize(750, 500); 
frame.add(panel, BorderLayout.CENTER); 
frame.setVisible(true); 

이 한 번만 호출 할 필요가있다. 새로운 데이터가 올 때마다 플롯 메소드가 호출됩니다.

public void startCharting() { 

    final MySoundCard card = new MySoundCard(); 
    final MyJFreeChart chart = new MyJFreeChart(); 

    Runnable r = new Runnable() { 

     @Override 
     public void run() { 
      while(true) { 

       int[] i = card.FileR(); 


       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 

         chart.plot(); 
        } 

       }); 


       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 
     } 
    }; 

    Thread t = new Thread(r); 
    t.start(); 
} 

는 스레드가 데이터 소스 매 초마다 호출 한 후 차트를 업데이트 : 여기

간단한 방법입니다. 이벤트 디스패치 스레드에서 업데이트가 호출됩니다.

+0

오디오 파일에서 수신했거나 사운드 카드에서 캡처 한 데이터 (샘플 배열)입니다. 이제는 한 번에 표시하는 대신 동적 인 방식으로 (시계열이 아닌 동적 인 방식으로) 표시하고 싶습니다. 가능한 경우 예시하십시오. –

+0

먼저 데이터가 애플리케이션에 어떻게 유입되는지 방법을 부르는거야? 아니면 응용 프로그램에서 데이터가 어떻게 든 캡처되고 있습니까? –

+0

@AbdulBaseerBuriro 아이디어를 줄 수있는 코드를 추가했습니다. –

관련 문제