困扰了三天的界面数据初始化问题解决了,虽然带我的师父给我推了相关文章,但我还是毫不犹豫的跳入了坑中并且没有解决空指针问题。(明明是按照形式写的,依然空指针)。所以我换了另一种方式解决空指针的问题。可以使用getcontroller方法,照样能够的到当前页面的所有对象(目前有没有bug还说不准)。关于fxml的问题文章链接也放在下面以便不时之需:
https://blog.csdn.net/o83290102o5/article/details/78188211?spm=1001.2014.3001.5506
感谢这位大佬的分享,与这个一同的还有数据之间的传递,链接也放在下面:(因为我解决不了而且为了赶时间我使用的不是这种方式,稍后也会贴出来):
https://blog.csdn.net/HuoYiHengYuan/article/details/98038023?spm=1001.2014.3001.5506
我使用的在上文也有介绍,是通过
static FXMLLoader loaderMain = new FXMLLoader();MainUser mainUser = loaderMain.getController();
这种方式去获得控制器,索性是有用的,在加载页面的时候,会同步加载数据,不过有一点点小缺陷是不能重复使用,因为Parent只能生成一次相同的根,次数过了后会报错。
我开始没管这个,后面解决了这个问题(后面写),先按思路将,因为初始化好数据之后能够进界面了,我就开始写读取数据,我新建了个数据更少的User类,用来从服务器读取原始数据并加载到页面中
这个是下午设置个性签名的时候做的截图(感谢E哥保佑)。
大概代码是这个样子的:
public void SetMainPage(Object o)throws Exception{
UserData userData = (UserData) o;
System.out.println(userData.getAvatar());
File imageFile = new File(userData.getAvatar());
MainUser mainUser = loaderMain.getController();
mainUser.VisibleUserName.setText(userData.getUserName());
mainUser.VisibleSignature.setText(userData.getSignature());
mainUser.VisibleAvatar.setImage(new Image(imageFile.toURI().toString()));
Scene MainScene = new Scene(MainPage,400,710);
MainStage.setScene(MainScene);
MainStage.setResizable(false);
MainStage.show();
stageLogin.close();
}
直接暴力解决。里面还有其他加载就稍后再说。
然后对头像设置了一个切换的方法,点击头像会进入到一个个人资料界面,当然数据设置方法是一致的。
public void showInfo(Object o)throws Exception{
UserData userData = (UserData) o;
MainUser mainUser = loaderInfo.getController();
File filePath = new File(userData.getAvatar());
mainUser.VisibleAvatar.setImage(new Image(filePath.toURI().toString()));
mainUser.InformName.setText(userData.getUserName());
mainUser.InforSignature.setText(userData.getSignature());
mainUser.VisibleID.setText(userData.getUserID());
mainUser.VisibleSex.setText(userData.getSex());
mainUser.VisibleAge.setText(userData.getAge());
Scene InfoScene = new Scene(InfoPage,560,430);
stageInfo.setScene(InfoScene);
stageInfo.setResizable(false);
}
然后就能对头像进行设置,但是又出现了新的问题,就是读取完头像后,数据库其实存不下(BLOB)二进制数据文件,会超长,于是换了一种写法,选取头像的时候读取头像的绝对路径,将绝对路径存入数据库,然后加载的时候从数据库读取,再进行设置,这里又出现了两个bug。一个是在个人资料页面设置了头像之后,主界面不会加载头像,二是在退出系统后,读取数据库时注册的新用户没有设置头像,于是File的路径为NULL,于是他死活不会让你进主界面。
加上最上面那个bug,一共出现了三个bug。
最上面那个只能加载一次的Parent,我在Control中设置了一个计数器,然后将生成页面的方法单独写出来了,根据cnt计数判断该直接生成(因为初始化一次数据后,只要程序在运行,就可以不要初始第二次)还是先初始化数据。
int cntInfo = 0;
@FXML
void SetPersonalInfo(Event event) throws Exception{
if(cntInfo == 0){
if(user.getAvatar() == null){
start.NULLAvatarshowInfo(user);
}else{
start.showInfo(user);
}
start.SHOWINFO();
cntInfo++;
}else{
start.SHOWINFO();
}
}
办法确实蠢,但是很有用。
然后就是关于路径为空的问题,我设置了判断,就是上面代码那个NULL,但是这样的话代码复用率就高了,必须得复制一个一样的代码,唯一不同的是这个代码不设置头像,这样就可以对新用户进行操作。
public void NULLAvatarshowInfo(Object o)throws Exception{
UserData userData = (UserData) o;
MainUser mainUser = loaderInfo.getController();
mainUser.InformName.setText(userData.getUserName());
mainUser.InforSignature.setText(userData.getSignature());
mainUser.VisibleID.setText(userData.getUserID());
mainUser.VisibleSex.setText(userData.getSex());
mainUser.VisibleAge.setText(userData.getAge());
Scene InfoScene = new Scene(InfoPage,560,430);
stageInfo.setScene(InfoScene);
stageInfo.setResizable(false);
}
public void NULLAvatarMainPage(Object o)throws Exception{
UserData userData = (UserData) o;
MainUser mainUser = loaderMain.getController();
mainUser.VisibleUserName.setText(userData.getUserName());
mainUser.VisibleSignature.setText(userData.getSignature());
Scene MainScene = new Scene(MainPage,400,710);
MainStage.setScene(MainScene);
MainStage.setResizable(false);
MainStage.show();
stageLogin.close();
}
这么看代码复用率确实很高。
然后就是设置个人资料的话主页头像得同步更新。
我写了个Flush方法用来刷新头像。
public void FlushAvatar(UserData user){
MainUser mainUser = loaderMain.getController();
File pathName = new File(user.getAvatar());
mainUser.VisibleAvatar.setImage(new Image(pathName.toURI().toString()));
MainStage.show();
}
@FXML
void ChooseAvatar() throws Exception{//打开本地文件夹选择头像并上传到服务器
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Image");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")
);
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile != null) {
String filepath = selectedFile.getAbsolutePath();
Image image = new Image(selectedFile.toURI().toString());
VisibleAvatar.setImage(image);
user.setAvatar(filepath);
new ClientServer().SavaAvatar(user);
start.FlushAvatar(user);
}
}
这是关于头像选择,其他的数据估计也跟头像异曲同工,所以就不写了,值得注意的是年龄可以通过计算,JavaFX中应该是存在选择器的,希望自己写项目的速度能更加快一点。(对再补充一点其实一开始只是冲着一个用户去写的,意外之喜是实例化Controller类的时候会根据ID的不同设置不同的数据,看来最开始的想法没有错)