我在更改JavaFX场景时遇到问题。当我尝试切换场景时,出现空指针异常,但是我使用调试器对其进行调试,它告诉我舞台指针为空。我注意到它没有找到stage的start方法的构造函数声明,因此我为整个类创建了一个变量。我不确定为什么该阶段指针为null,因为我确实在类中声明了变量。
这是主控制器切换场景的方法:
onstart.changeScene("password.fxml");
这是OnStart类,用于切换场景:
public class OnStart extends Application{
Parent root;
private Stage stage;
//private AnchorPane mainLayout;
//private HashMap<String, Pane> screenMap = new HashMap<>();
private Scene main;
FXMLLoader loader = new FXMLLoader();
@Override
public void start(Stage stage) throws Exception{
this.stage = stage;
root = loader.load(getClass().getResource("mainmenu.fxml"));
main = new Scene(root);
this.stage.setTitle("Photo Encryptor 9000");
this.stage.setScene(main);
this.stage.show();
}
public Parent getRoot() {
return root;
}
public Scene getScene() { return main; }
public void changeScene(String fxml) throws IOException {
root = loader.load(
getClass().getResource(fxml));
stage.getScene().setRoot(root);
}
}
这也是错误(第44行是stage.getScene.setRoot(root)
方法):
Caused by: java.lang.NullPointerException
at com.example.helloworld.OnStart.changeScene(OnStart.java:44)
at com.example.helloworld.MainController.encryptpress(MainController.java:99)
MainController:
public class MainController implements Initializable{
public String path, name;
private String passwordPlainText;
private boolean hasname;
private File f;
FileWriter out;
OnStart onstart = new OnStart();
BufferedImage image;
int widthofimage, heightofimage, numberofpixils;
AES aes = new AES();
@FXML
private TextField passwordtextbox;
FileReader read;
@FXML
private AnchorPane rootpane;
@Override
public void initialize(URL url, ResourceBundle rb){
}
@FXML
private void encryptpress(ActionEvent event) throws Exception {
//byte[] converter; //sample of encrypting and decrypting
//String output = "hello";
//converter = output.getBytes();
//System.out.println(output);
//converter = aes.encrypt(output, "noooo");
//System.out.println(converter);
//output = aes.decrypt(converter, "noooo");
//System.out.println(output);
//File chooser
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JPEG Files", "*.jpg"));
f = fileChooser.showOpenDialog(null); //f is the image
//Checks if a jpg file was chosen
if(f == null) {//if a file wasn't chosen...
AlertBox.display("Error", "No file was chosen");
return;
}
read = new FileReader();
out = new FileWriter("passwords.txt", true);
path = f.getAbsolutePath();//gets absolute path of file
name = f.getName();//gets name of file
System.out.println("Does file exist in passwords file: " + read.checkforfile(name)); //test - should output true if a file with name exists
if( read.checkforfile(name) ){ //goes back to parent node
if( read.hasHash(name) ){
AlertBox.display("Error", "This filename already has a password.");
//if true, then go back to main menu and display: "This filename already has a password."
Parent parent = onstart.getRoot(); //Not sure if this gets the pointer to the root or just a copy of the root
Scene parentscene = onstart.getScene();
Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();
window.setScene(parentscene);
window.show();
return;
}
hasname = true; //maybe close this automatically
//skips the addname process if hasname is true
}else { //adds the name of the image to the file if the image does not already exist
hasname = false; // waits to write the name just incase the user exits out of the program early without choosing a password
}
if(hasname == false){
out.write(name);
}
//System.out.println(name);
out.write(name);
image = ImageIO.read(f);
if(onstart.getRoot() != null) {System.out.println("Root is clear");}
if(onstart.getStage() != null) {System.out.println("Stage is clear");}
if(onstart.getScene() != null) {System.out.println("Scene is clear");}
onstart.changeScene("password.fxml");//////////////Error
//This copies the file and places it in the same directory
String newfile = "Encrypted" + f.getName();
File EncryptedImage = new File(newfile);
BufferedImage originalImage = ImageIO.read(f);
BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
widthofimage = originalImage.getWidth();
heightofimage = originalImage.getHeight();
numberofpixils = widthofimage * heightofimage;
int add = 0;
byte[] bytes = new byte[numberofpixils];
for (int x = 0; x < originalImage.getWidth(); x++) {
for (int y = 0; y < originalImage.getHeight(); y++) {
bytes[add] = (byte) originalImage.getRGB(x, y);
add++;
}
}
String s = new String(bytes);
String passwordtest = "password";
//s = aes.encrypt(s, passwordtest); //passwordplaintext is real passowrd holder
bytes = s.getBytes();
add = 0;
for (int x = 0; x < originalImage.getWidth(); x++) {
for (int y = 0; y < originalImage.getHeight(); y++) {
newImage.setRGB(x, y, bytes[add]);
add++;
}
}
ImageIO.write(newImage, "JPG", EncryptedImage);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ImageIO.write(newImage, "JPG", f2);//this creates a new image that is now encrypted
//System.out.println(image);
}
/*@FXML
private void dgxsd(ActionEvent event){
String test = "Hello";
String passwordtest = "password";
System.out.println(test);
test = aes.encrypt(test, passwordtest); //passwordplaintext is real passowrd holder
System.out.println(test);
test = aes.decrypt(test, passwordtest);
System.out.println(test);
}*/
@FXML
private void decryptpress(ActionEvent event) throws IOException {
//if passwords.txt is not empty: AnchorPane pane = FXMLLoader.load(getClass().getResource("password2.fxml"));
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JPEG Files", "*.jpg"));
File f = fileChooser.showOpenDialog(null);
if(f == null) {//if a file wasn't chosen...
AlertBox.display("Error", "No file was chosen");
return;
}
read = new FileReader();
out = new FileWriter("passwords.txt", true);
path = f.getAbsolutePath();//gets absolute path of file
name = f.getName();//gets name of file
System.out.println("Does file exist: " + read.checkforfile(name)); //test - should output true if a file with name exists
}
@FXML
private void Createpassword(ActionEvent event) throws IOException {
passwordPlainText = passwordtextbox.getText();
System.out.println(passwordPlainText);
BufferedImage image = ImageIO.read(f);
// doAESEncryption(passwordPlainText);
}
答案 0 :(得分:2)
@kendavidson是正确的,您得到null
的原因是MainController类中的这一行是您拥有的这一行
OnStart onstart = new OnStart();
使用null指针的原因是,您在创建该类的新实例时将其设置为null
要解决此问题,请在MainController类中创建一个看起来像这样的方法
public void setOnStartReference(OnStart onStartReference){
onstart = onStartReference;
}
并删除MainController类顶部的= new OnStart();
,使其现在看起来像这样
OnStart onstart;
现在,在OnStart类中,您需要先设置引用,然后才能调用OnStart类中的任何内容
MainController controller = loader.getController();
controller.setOnStartReference(this);
但是请确保将其放在loader.load...