演示:
支持托盘后台运行、全局快捷键换出、单词本地查询、双击单词朗读等功能:
自己刚学JavaFx,有问题欢迎指出讨论!希望帮到了大家!
一、新建JavaFX项目:
Controller文件存放界面的Button、TextFiled等等控件的事件代码。可以看到在sample.fxml中指定了相应控件的 controller 为 sample.Controller
sample.fxml文件存放控件的各种属性、布局的定义,这种界面逻辑代码分离的思想非常漂亮。
Main文件存放JavaFx的基本框架和程序启动入口。
二、界面布局
JavaFx的界面布局存放在sample.fxml中,强烈推荐安装一个JavaFXSceneBuilder ,有了它就可以所见即所得的编写界面了。
https://pan.baidu.com/s/1c0Ah54k
我的布局代码为:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.control.ComboBox?>
<SplitPane fx:id="Panel" dividerPositions="0.5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<items>
<TextField fx:id="input" prefHeight="0.0" prefWidth="598.0" style="-fx-font-size: 30;" />
<ListView fx:id="listView" prefHeight="373.0" prefWidth="598.0" style="-fx-font-size: 30;" />
</items>
</SplitPane>
三、单词库读取
网上下载一份单词库,当然你也可以去用爬虫爬取。
格式大概如下:
a art.一(个);每一(个);(同类事物中)任一个
abandon vt.离弃,丢弃;遗弃,抛弃;放弃
abdomen n.腹,下腹(胸部到腿部的部分)
...
然后导入到程序里面:
public class Word {
public List<String> words = new ArrayList<>();
public Word() {
String file = "a.txt"; // 你的单词文件存放路径
BufferedReader br = null;//构造一个BufferedReader类来读取文件
try {
br = new BufferedReader(new FileReader(file));
String temp = null;
while ((temp = br.readLine()) != null)
if (!temp.equals(""))
words.add(temp);
} catch (IOException e) {
e.printStackTrace();
}
}
// 通用的查找函数
public static List<String> search(String keyword, Collection<String> tCollection, BiFunction<String, String, Boolean> matcher) {
return (tCollection == null || matcher == null) ?
Collections.emptyList() :
tCollection.stream()
.filter(t -> matcher.apply(t, keyword))
.collect(Collectors.toList());
}
}
四、GUI事件处理
JavaFx常用有两种事件处理方式,一种是在.fxml定义好Action,然后在Controller里面实现该事件处理。这一种方式好处是代码清晰,但是不够灵活。
另一种方式是在.fxml定义好控件的id,然后在Main类里面直接用下面的方式取得控件。TextField input = (TextField) root.lookup("#input");
然后就可以为所欲为了。
首先在JavaFXSceneBuilder 里面指定控件id。其实就是.fxml文件里面的TextField变成了 fx:id=“input”:
修改代码为:
public class Main extends Application {
private Word word = new Word();
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Demo");
primaryStage.setScene(new Scene(root));
primaryStage.setHeight(80);
primaryStage.setResizable(false);//窗口不可改变高度 宽度 这样就不用调节自适应了
primaryStage.setOpacity(0.8);//设置透明度 0为完全透明 1为完全不透明 默认是1
primaryStage.initStyle(StageStyle.UNDECORATED);//设定窗口无边框
primaryStage.show();
// 一定show();完再lookup
TextField input = (TextField) root.lookup("#input");
ListView<String> listview = (ListView<String>) root.lookup("#listView");
input.textProperty().addListener((observable, oldValue, newValue) -> {
String trimed = newValue.trim();
if (trimed.length() > 0) {
List<String> searchResult = Word.search(trimed, word.words, String::contains);
listview.getItems().clear();
listview.getItems().addAll(searchResult);
primaryStage.setHeight(400);
} else {
primaryStage.setHeight(80);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
基本框架已经搭建好了,托盘和快捷键、单词朗读功能还没有实现,就留到下一节吧!有问题欢迎留言评论!