决定在冬天把毕设水完,开春出去玩。
今日进度:新建文件夹并找一个能跑的框架
项目参考:JavaFX-Chat
1. 新建maven项目,导入javafx依赖,出现:错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
之前一直是加了个引导类解决的,但会出现警告:Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...'
原因是javafx需要用java9引入的模块系统启动,详见解决JavaFX报错缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
那就加个模块,在包内添加module-info.java:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
module com.pdfTool {
requires javafx.controls;
requires javafx.fxml;
opens com.pdfTool to javafx.fxml;
exports com.pdfTool;
}
正常启动。
2. 研究fxml
赶时髦下了最新版的SceneBuilder顺便把java换成了java17,虽然全装在d盘但中间看了一眼c盘感觉它快爆了,明明一学期都在玩什么花活都没有整,又下了个WizTree,手动清出13G,tx会议你为什么要搁这打200M的log,好用爱用,记一下。
先看一下项目目录:
设想是模仿聊天那个项目,样式和视图放在resources下,逻辑放在java下。由于并不想把单个fxml写很长,所以要找一个自定义组件的方法。你在干什么,我在拿java写前端三件套.jpg
↑ 要写的界面
主界面用一个BorderPane,各个部分单独写一个fxml。以将导航栏塞进主视图做个实验:
导航栏的fxml:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.layout.HBox?> <fx:root type="HBox" prefHeight="30" xmlns:fx="http://javafx.com/fxml"> <Button fx:id="importButton" text="导入" onAction="#importPaper"></Button> </fx:root>
外层是root,为HBox类型。里面塞几个button触发各个功能。在onAction上绑定点击事件。
但由于IDEA找不到importPaper这个方法,它会爆红。实际运行没有问题。
给它写对应的方法类:
package com.pdfTool; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.layout.HBox; import java.io.IOException; public class MenuViewController extends HBox { public MenuViewController(){ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("views/MenuView.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } @FXML protected void importPaper(){ System.out.println("clicked."); } }
先继承一下HBox,然后写一个构造函数,并且把构造函数标成public,这样我们在另一个fxml里引用它时会自动调用构造函数来新建对象。如果不标public会触发IllegalAccessException。
构造函数里解析fxml并加载。
对事件importPaper使用@FXML注解。
调用一下:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.BorderPane?> <?import com.pdfTool.MenuViewController?> <BorderPane minHeight="500" minWidth="800" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"> <top> <MenuViewController/> </top> </BorderPane>
另一种方法是指定fx:controller,如果加上的话在当前用法中会触发Error: Controller value already specified,因为在调用MenuViewController已经创建了一个对象,这里再创建就冲突了。明天试试继承Initializable。
研究了一下发现有两种方式,一是通过创建controller加载fxml,一是加载fxml然后创建对应controller。后者显然不用在controller里加载fxml,但也不能当成组件直接写在fxml里,需要在java里加载,感觉有点怪。前者是现在用的方法,决定保持不变。
研究了一会儿怎么用javafx显示pdf。有转换成图片加载和找个js用webview包装一下两个选项。后者有包装好的轮子,但加载起来有点问题,而且感觉往桌面小应用里塞一个浏览器也很淦。还是转换成图片显示吧。