Структура проект такой
В App получаю контроллер MainXMLController и через метод setStage() устанавливаю primaryStage.
App.java
public void start(Stage primaryStage){
try{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/main.xml.fxml")); // FXMLLoader.load(getClass().getResource("/views/main.xml.fxml"));
Parent root = fxmlLoader.load();
MainXMLController mainXMLController = fxmlLoader.getController();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.UNDECORATED);
mainXMLController.setPrimaryStage(primaryStage);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
MainXMLController.java
public class MainXMLController extends BaseController implements Initializable{
private Stage primaryStage;
private static double xOffset = 0;
private static double yOffset = 0;
@FXML
private FlowPane titleBar;
@FXML
private FlowPane firstKeyboardRow, secondKeyboardRow, thirdKeyboardRow;
@FXML
private TextArea typeIt;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
dragUndecoratedWindow();
setKeyboardThemes();
setTypeItText();
installEventHandlerStage();
}
public void setTypeItText(){
typeIt.setText(new DefaultTextModel().getTypeText());
}
public void setPrimaryStage(Stage stage){
primaryStage = stage;
}
/* ActionListners */
private void println(Object object){
System.out.println(object);
}
private void dragUndecoratedWindow(){
titleBar.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
xOffset = primaryStage.getX() - mouseEvent.getScreenX();
yOffset = primaryStage.getY() - mouseEvent.getScreenY();
println("stageFROM event " + primaryStage.getY() );
}
});
titleBar.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
primaryStage.setX(mouseEvent.getScreenX() + xOffset);
primaryStage.setY(mouseEvent.getScreenY() + yOffset);
}
});
}
private void installEventHandlerStage(){
EventHandler<KeyEvent> keyEventEventHandler = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
System.out.println(keyEvent.getCode());
}
};
//println("stageFROM event " + primaryStage.getY() );
primaryStage.addEventFilter(KeyEvent.KEY_TYPED, keyEventEventHandler);
}
}
Главный метод перемещения работает а вот когда хочу установить EventHandler получаю NullPointer? Почему так работает? Или когда программа запускается стейдж не доступен?
Метод public void initialize
вызывается во время прогрузки fxml
(т.е. во время выполнения fxmlLoader.load()
), и в этот момент primaryStage
ещё не прокинут контроллеру.
Варианты решения:
installEventHandlerStage
в setPrimaryStage
;installEventHandlerStage
самостоятельно после
setPrimaryStage
;создать конструктор класса public
MainXMLController( Stage stage ){...}
, убрать упоминания этого
класса в fxml
и самостоятельно установить контроллер
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/main.xml.fxml"));
MainXMLController mainXMLController = new MainXMLController( primaryStage );
fxmlLoader.setController( mainXMLController );
Parent root = fxmlLoader.load();
тут ещё десяток вариантов, связанных с порядком вызовов.
@FXML private javafx.scene.control.Button closeButton;
//или любая другая нода на сцене
@FXML
private void initialize(){
Stage stage = (Stage) closeButton.getScene().getWindow();
}
И не очень понятно зачем вам метод инициализации с ресурс бандлом, если вы его не используете.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
После вывода текста в JTextPane, необходимо вернуть фокус в начало текста, а потом переместить фокус на кнопкуЧтобы долго не объяснять, вот две...
Пытался связать поле одной таблицы с id другойПока не до конца понимаю как это вообще сделать