Java 从线程更新JFreeChart

Java 从线程更新JFreeChart,java,multithreading,swing,jfreechart,Java,Multithreading,Swing,Jfreechart,我必须建立一个GPS解析器。我需要在另一个线程中解析NMEA字符串,该线程将解析单个NMEA字符串并以1Hz的频率更新图表。现在我构建了部分代码,但我在while循环中解析主线程中的数据;我的老师说那是错误的。我是在Java上编程的,但不是在多线程方面。如何将解析过程和刷新图表移动到后台线程 public class MainFrame extends JFrame { private JButton btnWybPlik; private JLabel jlDroga;

我必须建立一个GPS解析器。我需要在另一个线程中解析NMEA字符串,该线程将解析单个NMEA字符串并以1Hz的频率更新图表。现在我构建了部分代码,但我在while循环中解析主线程中的数据;我的老师说那是错误的。我是在Java上编程的,但不是在多线程方面。如何将解析过程和刷新图表移动到后台线程

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);
    }
公共类大型机扩展JFrame{
私人JButton btnWybPlik;
私人JLabel jlDroga;
私人JLabel jlPredkosc;
私人JLabel jlCzas;
私人JPanel mainjpanel;
私有JPanel jpMenu;
私人JPanel jpTablica;
//私人字符串sciezkaPliku;
私有SekwencjaGGA sekGGA=null;
私有SekwencjaGGA-popSekGGA=null;
私营企业SekwencjaGSA sekGSA;
私人SekwencjaGLL sekGLL;
私营企业SekwencjaRMC sekRMC;
私人双卓加;
私人双普雷德科斯克;
私有XY系列1;
私有XYSeriesCollection数据集;
公共主机(){
droga=0;
btnWybPlik.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
JFileChooser fileChooser=新的JFileChooser();
fileChooser.setCurrentDirectory(新文件(System.getProperty(“user.home”));
int result=fileChooser.showOpenDialog(mainjpanel);
if(result==JFileChooser.APPROVE\u选项){
File selectedFile=fileChooser.getSelectedFile();
//System.out.println(“所选文件:+selectedFile.getAbsolutePath());
字符串sciezkaPliku=selectedFile.getAbsolutePath();
wczytaniePliku(sciezkaPliku);
}
}
});
jpTablica=新的JPanel();
mainjpanel.add(jpTablica);
this.series1=新的XYSeries(“Trasa”,false);
最终XYSeriesCollection数据集=新的XYSeriesCollection(this.series1);
最终JFreeChart图表=createChart(数据集);
最终图表面板图表面板=新图表面板(图表);
jpTablica.add(图表面板);
}
私有void wczytaniePliku(字符串sciezkaDoPliku){
try(BufferedReader br=new BufferedReader(new FileReader(sciezkaDoPliku))){
弦线;
//系列1.添加(53.448,14.4907);
而((line=br.readLine())!=null){
行(行);
}
//系列1.增补(53.4485,14.4910);
}捕获(IOE异常){
e、 printStackTrace();
}
}
专用行(字符串行){
字符串bezzumkont=line.substring(0,line.length()-3);
List podzSekw=Arrays.asList(bezzumkont.split(“,”);
if(podzSekw.get(0.equalsIgnoreCase($GPGGA))){
如果(勾选(行)){
如果(sekGGA!=null)
popSekGGA=sekGGA;
sekGGA=新的SekwencjaGGA(podzSekw);
if(popSekGGA!=null){
droga+=斜交链(popSekGGA,sekGGA);
setText(String.valueOf(droga));
}
series1.add(sekGGA.getWspolzedne().getLongitude(),sekGGA.getWspolzedne().getLatitude());
System.out.println(sekGGA.getWspolzedne().getLatitude()+“”+sekGGA.getWspolzedne().getLatitude());
//System.out.println(series1.getMaxY()+“”+series1.getMinY());
}否则{
//待办事项:Zlicz błd
}
}
if(podzSekw.get(0.equalsIgnoreCase($GPGSA))){
如果(勾选(行)){
sekGSA=新SekwencjaGSA(podzSekw);
}否则{
//待办事项:Zlicz błd
}
}
if(podzSekw.get(0.equalsIgnoreCase($GPGLL))){
如果(勾选(行)){
sekGLL=新SekwencjaGLL(podzSekw);
}否则{
//待办事项:Zlicz błd
}
}
if(podzSekw.get(0.equalsIgnoreCase($GPRMC))){
//TODO:Sekwencja RMC(建议的最低数据)
如果(勾选(行)){
sekRMC=新的SekwencjaRMC(podzSekw);
}否则{
//待办事项:Zlicz błd
}
}
}
私人双债务人(SekwencjaGGA pkt1、SekwencjaGGA pkt2){
双odleglosc=0;
双接地半径=6371000;//米
double dLat=Math.toRadians(pkt2.getWspolzedne().getLatitude()-pkt1.getWspolzedne().getLatitude());
double dLng=Math.toRadians(pkt2.getWspolzedne().getLongitude()-pkt1.getWspolzedne().getLongitude());
双a=Math.sin(dLat/2)*Math.sin(dLat/2)+
Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude())*Math.cos(Math.toRadians(pkt1.getWspolzedne().getLatitude()))*
数学单(dLng/2)*数学单(dLng/2);
double c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
odleglosc=地球半径*c;
返回odleglosc;
}
/**
*斯普拉德扎伊·苏姆·康特罗酒店
*
*@param tekst cała linia NMEA
*@return true jeśli sięsuma kontrolna zgadza
*/
专用布尔检查(字符串tekst){
字符串suma=tekst.substring(tekst.length()-2,tekst.length());
tekst=tekst子字符串(1,tekst长度()-3);
整数校验和=0;
对于(int i=0;i