We built an information retrieval engine as part of our course project. We were asked to run our program with JavaFX.
The problem is that the project is very busy and includes: parse documents (460,000 docs and up to 3 million words), add terms to a dictionary and more functions that take time.
The time needed for the project to run without GUI is about 19 minutes; it includes merging post files and load the dictionary from disk to RAM. The issue is that when we add the GUI, the time is multiplied to reach almost 56 minutes.
We think that we did something wrong in the GUI built:
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();
}*/
}
}
FXML file
<?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>
Main class
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);
}
}
I would appreciate your help, thank you.