我正在编写一个应用程序,它将允许我在地图上打印一些坐标,也可以从几组坐标和其他内容中进行选择。
我用于初始化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如下所示:
当我尝试使用按钮时出现问题。
按下“解析”按钮将调用一个方法,该方法使用其他一些方法来读取文件,获取位置并在其中创建
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/