将FX嵌入摆动时的问题

时间:2017-08-13 10:25:09

标签: java multithreading swing google-maps

我正在编写一个应用程序,它允许我在地图上打印一些坐标,并从几组坐标和其他东西中进行选择。 我初始化GUI的代码是:

public class MainApp_v2 extends JPanel implements ActionListener{
    final static String corDir = System.getProperty("user.dir") + "/coordinates/";
    public GoogleMapView mapView;
    public static GoogleMap map;
    private Scene scene;
    public static HashMap<String, HashMap<String, Marker>> markerMap = new HashMap <String, HashMap<String, Marker>>();
    protected JButton Fetchbtn, Parsebtn, IGSbtn, EUREFbtn, USbtn, TRIGbtn, UNAVCObtn;
    protected JTextArea TXTarea;
    private final JFXPanel jfxPanel;

    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI(); 
            }
        });
    }

    /**
     * createAndShowGUI
     * 
     * creating a GUI and presenting it on screen
     */
    public static void createAndShowGUI() {
        JFrame frame = new JFrame("Control panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MainApp_v2 newContentPane = new MainApp_v2();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
        frame.setLocation(150, 200);
        frame.setSize(900, 900);
    }

    public MainApp_v2() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        setBackground(Color.LIGHT_GRAY);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
        buttonPanel.setBorder(BorderFactory.createRaisedBevelBorder());
        Dimension nbuttonPanelDIM = new Dimension(900,50);
        buttonPanel.setPreferredSize(nbuttonPanelDIM);
        buttonPanel.setMaximumSize(nbuttonPanelDIM);

        // fetch button
        Fetchbtn = new JButton("Fetch");
        Fetchbtn.addActionListener(this);
        Fetchbtn.setEnabled(true);
        Fetchbtn.setBackground(Color.BLACK);
        Fetchbtn.setForeground(Color.GREEN);
        buttonPanel.add(Fetchbtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // parse button
        Parsebtn = new JButton("Parse");
        Parsebtn.addActionListener(this);
        Parsebtn.setEnabled(true);
        Parsebtn.setBackground(Color.BLACK);
        Parsebtn.setForeground(Color.GREEN);
        buttonPanel.add(Parsebtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // IGS button
        IGSbtn = new JButton("IGS");
        IGSbtn.addActionListener(this);
        IGSbtn.setEnabled(false);
        IGSbtn.setBackground(Color.BLACK);
        IGSbtn.setForeground(Color.GREEN);
        buttonPanel.add(IGSbtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // EUREF button
        EUREFbtn = new JButton("EUREF");
        EUREFbtn.addActionListener(this);
        EUREFbtn.setEnabled(false);
        EUREFbtn.setBackground(Color.BLACK);
        EUREFbtn.setForeground(Color.GREEN);
        buttonPanel.add(EUREFbtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // USCORS button
        USbtn = new JButton("USCORS");
        USbtn.addActionListener(this);
        USbtn.setEnabled(false);
        USbtn.setBackground(Color.BLACK);
        USbtn.setForeground(Color.GREEN);
        buttonPanel.add(USbtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // UNAVCO button
        UNAVCObtn = new JButton("UNAVCO");
        UNAVCObtn.addActionListener(this);
        UNAVCObtn.setEnabled(false);
        UNAVCObtn.setBackground(Color.BLACK);
        UNAVCObtn.setForeground(Color.GREEN);
        buttonPanel.add(UNAVCObtn);
        buttonPanel.add(Box.createHorizontalStrut(5));

        // TrigNet button
        TRIGbtn = new JButton("TrigNet");
        TRIGbtn.addActionListener(this);
        TRIGbtn.setEnabled(false);
        TRIGbtn.setBackground(Color.BLACK);
        TRIGbtn.setForeground(Color.GREEN);
        buttonPanel.add(TRIGbtn);
        add(buttonPanel);

        // Map
        jfxPanel = new JFXPanel();
        jfxPanel.setPreferredSize(new Dimension(850, 850));
        Platform.runLater(() -> { 
            mapView = new GoogleMapView();
            mapView.addMapInializedListener(() -> { 

                LatLong center = new LatLong(36, -100);

                MapOptions options = new MapOptions()
                        .center(center) 
                        .zoom(4) 
                        .overviewMapControl(false) 
                        .panControl(false) 
                        .rotateControl(false) 
                        .scaleControl(false) 
                        .streetViewControl(false) 
                        .zoomControl(false) 
                        .mapType(MapTypeIdEnum.SATELLITE); 

                map = mapView.createMap(options);

            }); 

            mapView.setPrefSize(850, 850);
            scene = new Scene(mapView);

            jfxPanel.setScene(scene);
        });
        add(jfxPanel);

        // message area
        TXTarea = new JTextArea(6, 29);
        TXTarea.setEditable(false);
        TXTarea.setEnabled(true);
        DefaultCaret caret = (DefaultCaret) TXTarea.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
        JScrollPane scrollableArea = new JScrollPane(TXTarea);
        add(scrollableArea);   
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if ("Fetch".equals(e.getActionCommand())) {
            TXTarea.append("Fetching coordinates data... \n");
            fetcher();
            TXTarea.append("Done. \n");
        }
        if ("Parse".equals(e.getActionCommand())) {
            TXTarea.append("Loading coordinates. \n");
            mapper();
            Fetchbtn.setEnabled(false);
            IGSbtn.setEnabled(true);
            EUREFbtn.setEnabled(true);
            UNAVCObtn.setEnabled(true);
            USbtn.setEnabled(true);
            TRIGbtn.setEnabled(true);
            TXTarea.append("Done. \n");
        }
        if ("IGS".equals(e.getActionCommand())) {
            TXTarea.append("Plotting IGS stations. \n");
            map.clearMarkers();
            plotIGS();
        }
        if ("EUREF".equals(e.getActionCommand())) {
            TXTarea.append("Plotting EUREF stations. \n");

        }
        if ("USCORS".equals(e.getActionCommand())) {
            TXTarea.append("Plotting IGS stations. \n");

        }
        if ("UNAVCO".equals(e.getActionCommand())) {
            TXTarea.append("Plotting EUREF stations. \n");

        }
        if ("TrigNet".equals(e.getActionCommand())) {
            TXTarea.append("Plotting EUREF stations. \n");

        }
    }

// some more methods .....
}

在启动时一切正常,我的GUI看起来像这样: enter image description here

尝试使用按钮时出现问题。 按下&#34; Parse&#34; button调用一个方法,该方法使用其他一些方法来读取文件,获取一些位置并从中创建Markers并将它们存储在HashMap中,例如:

private void EUREF_IGS(File f){
        HashMap<String, Marker> igs_euref = new HashMap<String, Marker>();
        try {
            BufferedReader bf = new BufferedReader(new FileReader(f));
            String line = "";
            for (int i = 0; i < 6; i++){ // skip header
                line = bf.readLine();
            }

            boolean chk = true;
            while (chk){
                line = bf.readLine();
                String[] tk = line.replaceAll("  ", " ").replaceAll("  ", " ").replaceAll("  ", " ").split(" ");
                if (tk.length > 5){
                    String name = tk[0];
                    double[] xyz = {Double.parseDouble(tk[1]), Double.parseDouble(tk[2]), Double.parseDouble(tk[3])};
                    double[] llh_rad = ecef2lla(xyz, "wgs84");
                    double[] llh_deg = {Math.toDegrees(llh_rad[0]), Math.toDegrees(llh_rad[1]), llh_rad[2]};
                    MarkerOptions markerOptions = new MarkerOptions();
                    markerOptions.position( new LatLong(llh_deg[0], llh_deg[1]))
                    .visible(Boolean.TRUE)
                    .title(tk[0]);
                    Marker marker = new Marker(markerOptions);
                    igs_euref.put(name, marker);

                } else {
                    chk = false;
                }
            }

            if (f.getName().contains("IGS")){
                markerMap.put("IGS", igs_euref);
            } else if(f.getName().contains("EUREF")){
                markerMap.put("EUREF", igs_euref);
            }
        } 
        catch (FileNotFoundException ex) {ex.printStackTrace();} 
        catch (IOException ex) {ex.printStackTrace();}  
    }

当我尝试调用此方法时,当我到达MarkerOptions markerOptions = new MarkerOptions();时,我收到了下一个错误: Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0。 我认为它不会让我访问MarkerOptions类。

为什么会这样?我该如何解决?它有什么办法吗? 任何帮助,将不胜感激?谢谢。

1 个答案:

答案 0 :(得分:1)

Integrating JavaFX into Swing Applications: Changing JavaFX Data in Response to a Change in Swing Data所述,您的JButton处理程序必须使用RunnablePlatform.runLater()方式调用所需的JavaFX代码。

@Override
public void actionPerformed(ActionEvent e) {
    if ("Fetch".equals(e.getActionCommand())) {
        Platform.runLater(new Runnable() { 
            @Override
            public void run() {
                TXTarea.append("Fetching coordinates data... \n");
                … 
            }
        });
    }
    …
}