2015-06-09 2 views
0

Мне нужно построить парсер GPS. Мне нужно разобрать строку NMEA в другом потоке, который будет синтаксический анализ одной строки NMEA и диаграммы обновления с частотой 1 Гц. Пока я создаю часть своего кода, но я анализирую данные в основном потоке во время цикла; мой учитель сказал, что это неправильно. Я программировал некоторые на Java, но не в многопоточных аспектах. Как я мог перемещать процесс синтаксического анализа и обновлять диаграмму в фоновый поток?Обновление JFreeChart из темы

public class MainFrame extends JFrame { 

    private JButton btnWybPlik; 
    private JLabel jlDroga; 
    private JLabel jlPredkosc; 
    private JLabel jlCzas; 
    private JPanel mainjpanel; 
    private JPanel jpMenu; 
    private JPanel jpTablica; 

    //private String sciezkaPliku; 
    private SekwencjaGGA sekGGA = null; 
    private SekwencjaGGA popSekGGA = null; 
    private SekwencjaGSA sekGSA; 
    private SekwencjaGLL sekGLL; 
    private SekwencjaRMC sekRMC; 

    private double droga; 
    private double predkosc; 

    private XYSeries series1; 
    private XYSeriesCollection dataset; 

    public MainFrame() { 
     droga = 0; 
     btnWybPlik.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       JFileChooser fileChooser = new JFileChooser(); 
       fileChooser.setCurrentDirectory(new File(System.getProperty("user.home"))); 
       int result = fileChooser.showOpenDialog(mainjpanel); 
       if (result == JFileChooser.APPROVE_OPTION) { 
        File selectedFile = fileChooser.getSelectedFile(); 
        //System.out.println("Selected file: " + selectedFile.getAbsolutePath()); 
        String sciezkaPliku = selectedFile.getAbsolutePath(); 
        wczytaniePliku(sciezkaPliku); 
       } 
      } 
     }); 

     jpTablica = new JPanel(); 
     mainjpanel.add(jpTablica); 

     this.series1 = new XYSeries("Trasa", false); 

     final XYSeriesCollection dataset = new XYSeriesCollection(this.series1); 
     final JFreeChart chart = createChart(dataset); 
     final ChartPanel chartPanel = new ChartPanel(chart); 
     jpTablica.add(chartPanel); 
    } 

    private void wczytaniePliku(String sciezkaDoPliku) { 
     try (BufferedReader br = new BufferedReader(new FileReader(sciezkaDoPliku))) { 
      String line; 
      //series1.add(53.448, 14.4907); 
      while ((line = br.readLine()) != null) { 
       parseLine(line); 
      } 
      //series1.add(53.4485, 14.4910); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void parseLine(String line) { 
     String bezSumKont = line.substring(0, line.length() - 3); 
     List<String> podzSekw = Arrays.asList(bezSumKont.split(",")); 

     if (podzSekw.get(0).equalsIgnoreCase("$GPGGA")) { 
      if (check(line)) { 
       if (sekGGA != null) 
        popSekGGA = sekGGA; 

       sekGGA = new SekwencjaGGA(podzSekw); 
       if (popSekGGA != null) { 
        droga += obliczOdleglosc(popSekGGA, sekGGA); 
        jlDroga.setText(String.valueOf(droga)); 
       } 

       series1.add(sekGGA.getWspolzedne().getLongitude(), sekGGA.getWspolzedne().getLatitude()); 
       System.out.println(sekGGA.getWspolzedne().getLatitude() + " " + sekGGA.getWspolzedne().getLongitude()); 
       //System.out.println(series1.getMaxY() + " " + series1.getMinY()); 
      } else { 
       //TODO: Zlicz błąd 
      } 
     } 
     if (podzSekw.get(0).equalsIgnoreCase("$GPGSA")) { 
      if (check(line)) { 
       sekGSA = new SekwencjaGSA(podzSekw); 
      } else { 
       //TODO: Zlicz błąd 
      } 
     } 
     if (podzSekw.get(0).equalsIgnoreCase("$GPGLL")) { 
      if (check(line)) { 
       sekGLL = new SekwencjaGLL(podzSekw); 
      } else { 
       //TODO: Zlicz błąd 
      } 
     } 
     if (podzSekw.get(0).equalsIgnoreCase("$GPRMC")) { 
      //TODO: Sekwencja RMC (Recommended minimum of data) 
      if (check(line)) { 
       sekRMC = new SekwencjaRMC(podzSekw); 
      } else { 
       //TODO: Zlicz błąd 
      } 
     } 
    } 

    private double obliczOdleglosc(SekwencjaGGA pkt1, SekwencjaGGA pkt2) { 
     double odleglosc = 0; 

     double earthRadius = 6371000; //meters 
     double dLat = Math.toRadians(pkt2.getWspolzedne().getLatitude() - pkt1.getWspolzedne().getLatitude()); 
     double dLng = Math.toRadians(pkt2.getWspolzedne().getLongitude() - pkt1.getWspolzedne().getLongitude()); 
     double a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
       Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude())) * Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude())) * 
         Math.sin(dLng/2) * Math.sin(dLng/2); 
     double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
     odleglosc = earthRadius * c; 

     return odleglosc; 
    } 

    /** 
    * Funkcja sprawdzająca sume kontrolną 
    * 
    * @param tekst cała linia NMEA 
    * @return true jeśli się suma kontrolna zgadza 
    */ 
    private boolean check(String tekst) { 
     String suma = tekst.substring(tekst.length() - 2, tekst.length()); 
     tekst = tekst.substring(1, tekst.length() - 3); 

     int checksum = 0; 
     for (int i = 0; i < tekst.length(); i++) { 
      checksum = checksum^tekst.charAt(i); 
     } 

     if (Integer.parseInt(suma, 16) == checksum) { 
      return true; 
     } 

     return false; 
    } 

    private JFreeChart createChart(final XYDataset dataset) { ... } 

    private void customizeChart(JFreeChart chart) { ... }  

    public static void main(String[] args) { 
     JFrame frame = new JFrame("MainFrame"); 
     frame.setContentPane(new MainFrame().mainjpanel); 
     frame.setPreferredSize(new Dimension(640, 480)); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

ответ

2

Чтобы избежать блокировки event dispatch thread, построить экземпляр SwingWorker. Соберите данные в своей реализации doInBackground(), publish() промежуточных результатов и обновите XYSeries в вашей реализации process(). Диаграмма прослушивания обновится в ответ. Соответствующий пример, который использует , показан ниже и рассмотрен here.

image