になっていないFXMLボタンをハードコードされたように動作させるために、以下のことがなぜ必要なのかを説明してください。FXMLボタンがnullpointerにつながり、ハードコードされたボタンが
ボタンを押して、オンザフライでアプリケーションのCSSを変更しようとしています。 コントローラのボタンをハードコードすると、すべてが正常に機能していますが、FXMLを使用すると、同じ関数呼び出しによってnullpointerが発生します。
完全なコードを表示するように更新しました(とにかく小さなテストプログラム)。私はいくつかの名前を変更して読みやすくしました。機能が変更されませんが、一方で弱い回避策として役立つ機能が追加されましたいいえ: コントローラ:私のFXMLの
public class SoC extends Application
{
public Scene myScene;
Button btn = new Button();
@FXML
Button btnFXHack;
@FXML
Button btnFXFail;
boolean flipIt = false;
// basic function i want to use
public void changeCSS()
{
if (!flipIt)
{
myScene.getStylesheets().remove(0);
myScene.getStylesheets().add(getClass().getResource("styleTwo.css").toExternalForm());
}
else
{
myScene.getStylesheets().remove(0);
myScene.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());
}
flipIt = !flipIt;
}
// workaround that is fine unless there are more then one scene
public void changeCSSHack(Scene s)
{
if (!flipIt)
{
s.getStylesheets().remove(0);
s.getStylesheets().add(getClass().getResource("styleTwo.css").toExternalForm());
}
else
{
s.getStylesheets().remove(0);
s.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());
}
flipIt = !flipIt;
}
/**
* Button one changes CSS on his own scene only, which feels kinda hacked and lame.
*
* @param event
*/
@FXML
private void handleCSSHack(ActionEvent event)
{
// this button can access his own scene AND use it,....
changeCSSHack(btnFXHack.getScene());
}
/**
* Button two tries to change CSS with saved values in the mainController...
* ...and fails.
*
* @param event
*/
@FXML
private void handleCSSFail(ActionEvent event)
{
// ...yet this button tells me the SAME scene is null. Yes, the one he is on himself.
changeCSS();
}
@Override
public void start(Stage primaryStage)
{
try
{
BorderPane pane = (BorderPane) FXMLLoader.load(getClass().getResource("SoC.fxml"));
myScene = new Scene(pane);
myScene.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());
btn = new Button("hardcoded");
btn.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
changeCSS();
}
});
pane.setCenter(btn);
primaryStage.setScene(myScene);
primaryStage.show();
System.out.println("Started");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
}
パート(ボードはFXMLを好きとは思われないので、フルに貼り付けることはできません)
<Button fx:id="btnFXHack" mnemonicParsing="false" onAction="#handleCSSHack" text="FX Button Hack" BorderPane.alignment="CENTER" />
<Button fx:id="btnFXFail" mnemonicParsing="false" onAction="#handleCSSFail" text="FX Button Fail" BorderPane.alignment="CENTER" />
サイドノート:「children()。add(btnFX)」を使用してFXMLボタンをペインに追加するだけで、今は2倍になりますが、これも機能します。 Idは本当に私のコードから自分のGUIのものを保つことを好むので、IDは本当にこの問題を解決する方法を聞くのが大好きです。
ありがとうございました。
編集私の構成を示す:
programmfolder
-src
--mainpackage
---controller.java
---.fxml-file
-themes folder
--default.css
--SciFi.css
そうです、 "/" .cssファイルに到達するために必要とされています。そしてもう一度:ハードコードボタンによって呼び出されると、changeCSS()は実際に動作しています。だから私はこの問題がこの目的のためにあるのではないかと疑う。
また、println(「stuff」)のためにFXMLボタンを押すこともできます。今私は彼がmySceneを見ないので、nullpointerを取得するという気持ちを得る。単純なsystem.out.println(myScene.toString())でも、FXMLボタンのnullポインタが返されます。問題は、どこから呼び出されているのかによって同じオブジェクトが突然nullになるのはなぜですか?
関連性があるかどうかわかりませんが、changeCssメソッドの前に "@FXML"と入力する必要があります。さらに、btnFXはコード内で初期化する必要はありません。単に "@FXMl Button btnFX;"を使用してください。 –
悲しいことに、FXML表記は何も変更しません。私は前にそれを試みた。 – Rattenmann
ボタンはfxmlの唯一のコンポーネントですか?他の要素はどうですか?彼らは働きますか?コントローラがfxmlに正しく設定されていない可能性があります。 –