我正在编写一个应用程序,它将允许我在地图上打印一些坐标,也可以从几组坐标和其他内容中进行选择。
我用于初始化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如下所示:
java - 将FX嵌入 Swing 时出现的问题-LMLPHP

当我尝试使用按钮时出现问题。
按下“解析”按钮将调用一个方法,该方法使用其他一些方法来读取文件,获取位置并在其中创建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类。

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

最佳答案

Integrating JavaFX into Swing Applications: Changing JavaFX Data in Response to a Change in Swing Data中所述,您的JButton处理程序必须使用Runnable作为Platform.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");
                …
            }
        });
    }
    …
}

关于java - 将FX嵌入 Swing 时出现的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45659353/

10-09 19:26