- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为类(class)项目的一部分,我们构建了一个信息检索引擎。我们被要求使用 JavaFX 运行我们的程序。
问题是该项目非常繁忙,包括:解析文档(460,000 个文档和多达 300 万个单词)、将术语添加到字典以及更多需要时间的功能。
项目在没有 GUI 的情况下运行所需的时间约为 19 分钟;它包括合并帖子文件并将字典从磁盘加载到 RAM。
问题是,当我们添加 GUI 时,时间会成倍增加,几乎达到 56 分钟。
我们认为我们在构建的 GUI 中做错了:
Controller
package sample;
import javafx.event.ActionEvent;
import javafx.scene.control.Alert;
import javafx.scene.control.TableView;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import main.Indexer;
import main.ReadFile;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class Controller {
public javafx.scene.control.CheckBox checkBox_Stemming;
public javafx.scene.control.Button btn_start;
public javafx.scene.control.Button btn_browse_Corpus;
public javafx.scene.control.Button btn_browse_postfile;
public javafx.scene.control.Button btn_reset;
public javafx.scene.control.TextField tf_postfilePath;
public javafx.scene.control.TextField tf_corpusPath;
public javafx.scene.control.Button btn_dictionary;
public TableView table_dic;
public javafx.scene.control.TableColumn tc_term;
public javafx.scene.control.TableColumn tc_tf;
private Stage mainStage;
private Indexer indexer;
private ReadFile rf;
public void initialize(Stage mainStage) {
this.mainStage = mainStage;
mainStage.setMinHeight(600);
mainStage.setMinWidth(800);
}
public String openFile(ActionEvent event) {
DirectoryChooser chooser = new DirectoryChooser();
File defaultDirectory = new File("C:\\");
chooser.setInitialDirectory(defaultDirectory);
File selectedDirectory = chooser.showDialog(new Stage());
return selectedDirectory.getPath();
}
public void setStopWord(ActionEvent event){
tf_postfilePath.textProperty().setValue(openFile(event));
}
public void setCorpusPath(ActionEvent event){
tf_corpusPath.textProperty().setValue(openFile(event));
}
public void startIndex(ActionEvent event) {
String corpusPath = tf_corpusPath.textProperty().getValue();
String postfilePath = tf_postfilePath.textProperty().getValue();
if(corpusPath.length() > 0 && postfilePath.length() > 0 ){
long startTime = System.currentTimeMillis();
indexer=new Indexer();
rf= new ReadFile();
try {
indexer.Start(rf,corpusPath,checkBox_Stemming.isSelected(),postfilePath);
} catch (IOException e) {
e.printStackTrace();
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
long minutes = TimeUnit.MILLISECONDS.toMinutes(elapsedTime);
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("Number of documents:"+ main.Indexer.n+"\n"
+"Number of uniq terms:"+ "\n"+"Running time:"+minutes+ "minutes\n");
alert.showAndWait();
} else if (postfilePath.length() > 0) {
indexer = new Indexer();
try {
indexer.createFinalDictionary(postfilePath);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Problem");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("The path are empty or both not. please insert only one path postingfile or corpus");
alert.showAndWait();
}
}
public void resetIndexer(ActionEvent event) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("The dictionary and the postingfile deleted");
alert.showAndWait();
indexer = null;
rf = null;
tf_postfilePath.textProperty().setValue("");
tf_corpusPath.textProperty().setValue("");
}
public void showDictionary(ActionEvent event) {
System.out.println("hello");
/**if(indexer != null) {
HashMap<String, String> dic = indexer.getDic();
List<String> sortedKeys = new ArrayList(dic.keySet());
Collections.sort(sortedKeys);
for (String k:sortedKeys) {
table_dic.getColumns().addAll(k);
} else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("The dictionary is empty");
alert.showAndWait();
}*/
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Text?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/11.0.1">
<Button fx:id="btn_reset" layoutX="33.0" layoutY="70.0" mnemonicParsing="false" text="Reset" onAction='#resetIndexer' />
<Button fx:id="btn_browse_Corpus" layoutX="129.0" layoutY="112.0" mnemonicParsing="false" onAction="#setCorpusPath" text="Browse" />
<Button fx:id="btn_browse_postfile" layoutX="129.0" layoutY="149.0" mnemonicParsing="false" onAction="#setStopWord" text="Browse" />
<TableView fx:id="table_dic" layoutX="451.0" layoutY="70.0" prefHeight="439.0" prefWidth="427.0">
<columns>
<TableColumn fx:id="tc_term" prefWidth="211.20001220703125" text="Term " />
<TableColumn fx:id="tc_tf" minWidth="2.4000244140625" prefWidth="215.20001220703125" text="tf" />
</columns>
</TableView>
<TextField fx:id="tf_postfilePath" layoutX="204.0" layoutY="148.0" prefHeight="26.0" prefWidth="218.0" />
<TextField fx:id="tf_corpusPath" layoutX="205.0" layoutY="111.0" prefHeight="26.0" prefWidth="217.0" />
<CheckBox fx:id="checkBox_Stemming" layoutX="125.0" layoutY="74.0" mnemonicParsing="false" text="Stemming" />
<Button fx:id="btn_dictionary" layoutX="39.0" layoutY="233.0" mnemonicParsing="false" text="Dictionary" onAction="#showDictionary" />
<Button fx:id="btn_start" layoutX="35.0" layoutY="187.0" mnemonicParsing="false" text="Start" onAction='#startIndex' />
<Text layoutX="46.0" layoutY="129.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Corpus" />
<Text layoutX="33.0" layoutY="163.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Posting files" wrappingWidth="75.0" />
</AnchorPane>
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("IR2020");
primaryStage.setScene(new Scene(root, 300, 275));
Controller controller=new Controller();
controller.initialize(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
最佳答案
我关注@Slaw 和@LuxusProblem 的回答;您应该创建一个服务,其唯一作用是执行指令 indexer.Start(rf,corpusPath,checkBox_Stemming.isSelected(),postfilePath);
.然后在你的 Controller 中,你必须启动这个服务然后监听这个服务的状态;如果它切换到 SUCCEEDED,那么您可以显示您的消息框。
我已经为你的代码实现了一个基本的服务(也许会有一些小错误,因为我不知道 Indexer
和 ReadFile
类是如何制作的):
package sample;
import java.util.concurrent.TimeUnit;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
public class IndexService extends Service<Boolean> {
private String corpusPath;
private String postFilePath;
private ReadFile readFile;
private boolean stemming;
public IndexService(String cPath, String pfPath, ReadFile rf, boolean stem) {
corpusPath = cPath;
postFilePath = pfPath;
readFile = rf;
stemming = stem;
}
@Override
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
try {
indexer.Start(readFile, corpusPath, stem, postfilePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
};
}
}
startIndex
方法将如下所示:
@FXML
public void startIndex(ActionEvent event) throws InterruptedException {
String corpusPath = tf_corpusPath.textProperty().getValue();
String postfilePath = tf_postfilePath.textProperty().getValue();
if (corpusPath.length() > 0 && postfilePath.length() > 0) {
long startTime = System.currentTimeMillis();
IndexService service = new IndexService(corpusPath, postfilePath, rf, checkBox_Stemming.isSelected());
service.start();
service.stateProperty().addListener((bean_p, old_p, new_p) -> {
switch (new_p) {
case SUCCEEDED:
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
long minutes = TimeUnit.MILLISECONDS.toMinutes(elapsedTime);
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("Number of documents:" + "main.Indexer.n" + "\n" + "Number of uniq terms:" + "\n" + "Running time:" + minutes + "minutes\n");
alert.showAndWait();
break;
default:
break;
}
});
} else if (postfilePath.length() > 0) {
indexer = new Indexer();
try {
indexer.createFinalDictionary(postfilePath);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Problem");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText("The path are empty or both not. please insert only one path postingfile or corpus");
alert.showAndWait();
}
}
IndexService
切换到 FAILED 以便您可以显示它。
IndexService
类,只需删除
try-catch
:
@Override
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
indexer.Start(readFile, corpusPath, stem, postfilePath);
return true;
}
};
}
State.FAILED
添加一个案例进入您的服务状态监听器:
case FAILED:
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Look, an Information Dialog");
alert.setContentText(service.getException().getMessage());
alert.showAndWait();
break;
关于user-interface - JavaFX 应用程序很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59372765/
export class UserListComponent implements OnInit{ users; constructor(private userService: UserS
我最近在我的系统中遇到了 Java 语言环境的问题,我试图用这个配置运行一个项目: -Duser.language=pt_BR -Duser.country=BR 谷歌搜索后,我找到了this sit
1 当我希望出现注册错误时,我的代码出现问题:管理器不可用; 'auth.User' 已替换为 'users.User' ,我尝试解决其他问题,与 Manager 不可用相同; 'auth.User'
Loopback 非常酷,但这是我迄今为止遇到的一个缺点,我真的不确定如何解决它。内置用户模型在我的 MongoDB 数据库中生成一个名为“User”的集合,当我尝试根据 Loopback.js 自己
我在 aws cognito 中有以下用户组。行政成员付费成员(member) 我想在所有用户注册我的应用程序时将所有用户默认分配到 Member 用户组,这样我就可以为该用户组分配不同的 IAM A
blogsIndex.blade.php @extends('layouts.default') @section('details')
我正在尝试在Rails 3开发环境中使用sqlite3而不是MySQL,但是遇到了问题。尝试执行rake db:migrate时,我得到: SQLite3::SQLException: no such
尝试使用 构建 API Phoenix v1.3 按照本教程: https://dreamconception.com/tech/phoenix-full-fledged-api-in-five-mi
我正在使用通过模板 cookie-cutter 创建的 Django。当我尝试在本地使用 docker 运行项目时,出现以下错误。 FATAL: password authentication fai
我正在尝试使用 node.js/adonis 创建新用户 我创建了这两个函数: const User = use("App/Models/User") async store ({ request,
我想安排一些事情,例如 GET 请求 http://example.com/user/foo@bar.com 内部调用脚本 /var/www/example.com/rest/user/GET.php
我是一名具有可用性工程背景的软件开发人员。当我在研究生院学习可用性工程时,其中一位教授有一句口头禅:“你不是用户”。我们的想法是,我们需要将 UI 设计基于实际的用户研究,而不是我们自己关于 UI 应
您好,我正在制作一个使用互联网发送消息的消息传递应用程序。我需要从用户 a 向用户 b 发出通知。 我使用这段代码: if (toUser!= nil){ parseMessage[@
在 ruby/ror 中你可以这样做: user = User.new(params[:user]) 它使用发布表单中的值填充新对象。 使用 django/python 可以完成类似的事情吗? 最
每当我编辑用户的角色时,用户都需要注销并重新登录以查看更改。提升用户时没有问题,因为他们在再次登录之前不会看到额外的权限。但是,当降级发生时,用户仍将保留其现有角色,这会带来安全风险。想象一下,撤销一
我的核心数据有线问题。使用 iOS 10 中的 Swift3,每次使用 获取或存储数据时,我都会获得托管对象上下文 func getContext () -> NSManagedObjectCont
我发现当我使用 users_path(user) 时它返回 /users.id 其中 id 是用户的 ID 但我希望它返回 /用户/ID。我的配置 routes.rb 如下所示。 # config/r
我的应用程序在我的测试设备上正常运行(当我通过 ADT 安装它时,当我通过导出的 APK 文件安装它时)但它在 Play Store 测试设备上失败并出现以下错误: Permission Denial
创建模型的第一个条目会抛出错误 我执行了以下命令进行迁移 manage.py makemigrations manage.py migrate 在我执行这些命令以在数据库中创建第一个“数据”之后,一切
我正在尝试实现一个 getter,但它在下面代码 fragment 的最后一行向我显示了这个错误。 代码是—— class AuthRepository extends BaseAuthReposit
我是一名优秀的程序员,十分优秀!