我是Java的新手,我一直在研究一个简单的GPS雷达程序,我正在使用Javafx作为FXML的接口。我注意到当我有无限循环等待中断事件时它崩溃了界面。因此我决定将我的程序分开运行两个线程。
问题是我从按钮(Refresh)事件开始的新线程没有看到全局变量的当前状态,因为它们不是静态的。但FXML不允许我声明静态变量。那么如何让我的后台线程看到第一个线程的那些变量而不使它们变为静态呢?
这是我的控制器类:
public class Controller extends Task<Void> {
@FXML
private ListView<String> listView;
private String itemSelectedFromList;
@FXML
private Circle NorthCircle;
@FXML
private Circle SouthCircle;
@FXML
private Circle EastCircle;
@FXML
private Circle WestCircle;
@FXML
private Circle NorthWestCircle;
@FXML
private Circle NorthEastCircle;
@FXML
private Circle SouthWestCircle;
@FXML
private Circle SouthEastCircle;
@FXML
private Label bearingLabel;
@FXML
private Label distanceLabel;
@FXML
private Button refresher;
private float angle;
private double distance;
Thread thread;
public void readFileClicked(ActionEvent event) throws IOException {
String[][] csvCoords = Util.getCoordsFromLocalFile();
ObservableList<String> items = Util.getObservableList(csvCoords);
listView.setItems(items);
}
public void refresh(ActionEvent event) throws Exception {
if (listView.getSelectionModel().getSelectedItem() == null) {
AlertBox.display("No coords are selected",
"Please select a coord from the list, before attempting to refresh");}
else{
setToDone();
Task<Void> task = new Controller();
thread = new Thread(task);
if(thread.isAlive()){
thread.interrupt();
}
thread.setDaemon(true);
thread.start();
System.out.println("Thread started");
}
}
@Override
protected Void call() throws Exception {
Coord destination = new Coord();
String selection = listView.getSelectionModel().getSelectedItem();
destination = Util.getCoordsFromList(selection);
updateInterface(destination);
return null;
}
/* Update the interface by calculating haversine, and bearing
*
*/
private void updateInterface(Coord destination)
throws InterruptedException {
double x2 = Math.toRadians(41.1);
double y2 = Math.toRadians(-122.1716800);
Coord source = new Coord();
source.setX(x2);
source.setY(y2);
while(!thread.isInterrupted()){
//source= ReadPort.parseData();
distance = Util.haversine(source.getX(), source.getY(), destination.getX(), destination.getY());
angle = Util.getAngle(source.getX(), source.getY(), destination.getX(), destination.getY());
updateCircles(angle);
updateTexts(angle, distance);
}
}
public void updateCircles(float angle) {
NorthCircle.setFill(Color.RED);
SouthCircle.setFill(Color.RED);
EastCircle.setFill(Color.RED);
WestCircle.setFill(Color.RED);
NorthEastCircle.setFill(Color.RED);
NorthWestCircle.setFill(Color.RED);
SouthEastCircle.setFill(Color.RED);
SouthWestCircle.setFill(Color.RED);
if (angle >= 22.5 && angle < 67.5) {
System.out.println("Head North-East");
NorthEastCircle.setFill(Color.GREEN);
} else if (angle >= 67.5 && angle < 112.5) {
System.out.println("Head East");
EastCircle.setFill(Color.GREEN);
} else if (angle >= 112.5 && angle < 157.5) {
System.out.println("Head South-East");
SouthEastCircle.setFill(Color.GREEN);
} else if (angle >= 157.5 && angle < 202.5) {
System.out.println("South");
SouthCircle.setFill(Color.GREEN);
} else if (angle >= 202.5 && angle < 247.5) {
System.out.println("Head South-West");
SouthWestCircle.setFill(Color.GREEN);
} else if (angle >= 247.5 && angle < 292.5) {
System.out.println("Head West");
WestCircle.setFill(Color.GREEN);
} else if (angle >= 292.5 && angle <= 337.5) {
System.out.println("Head North-West");
NorthWestCircle.setFill(Color.GREEN);
} else if ((angle >= 0 && angle < 22.5) || (angle > 337.5 && angle <= 360)) {
System.out.println("North");
NorthCircle.setFill(Color.GREEN);
}
}
public void updateTexts(float angle, double distance) throws InterruptedException {
angle = (float) Math.ceil(angle);
bearingLabel.setText("Bearing: " + String.valueOf(angle));
distance = Math.ceil(distance);
distanceLabel.setText("Distance: " + distance + " feet");
}
public void setToDone() {
listView.getSelectionModel().getSelectedItem().replace(",", "S");
listView.setEditable(true);
listView.setCellFactory(TextFieldListCell.forListView());
listView.setOnEditCommit(new EventHandler<ListView.EditEvent<String>>() {
@Override
public void handle(ListView.EditEvent<String> t) {
listView.getItems().set(t.getIndex(), t.getNewValue());
System.out.println("setOnEditCommit");
}
});
listView.setOnEditCancel(new EventHandler<ListView.EditEvent<String>>() {
@Override
public void handle(ListView.EditEvent<String> t) {
System.out.println("setOnEditCancel");
}
});
}}