Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve startup time #8035

Merged
merged 1 commit into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ public void showLibraryTab(LibraryTab libraryTab) {
}

public void init() {
sidePaneManager = new SidePaneManager(prefs, this, dialogService, stateManager);
sidePaneManager = new SidePaneManager(prefs, this, taskExecutor, dialogService, stateManager);
sidePane = sidePaneManager.getPane();

tabbedPane = new TabPane();
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/jabref/gui/SidePaneManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.jabref.gui.groups.GroupSidePane;
import org.jabref.gui.importer.fetcher.WebSearchPane;
import org.jabref.gui.openoffice.OpenOfficeSidePanel;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.openoffice.OpenOfficePreferences;
import org.jabref.preferences.PreferencesService;

Expand All @@ -23,13 +24,13 @@ public class SidePaneManager {
private final List<SidePaneComponent> visibleComponents = new LinkedList<>();
private final PreferencesService preferencesService;

public SidePaneManager(PreferencesService preferencesService, JabRefFrame frame, DialogService dialogService, StateManager stateManager) {
public SidePaneManager(PreferencesService preferencesService, JabRefFrame frame, TaskExecutor taskExecutor, DialogService dialogService, StateManager stateManager) {
this.preferencesService = preferencesService;
this.sidePane = new SidePane();

OpenOfficePreferences openOfficePreferences = preferencesService.getOpenOfficePreferences();
Stream.of(
new GroupSidePane(this, preferencesService, dialogService),
new GroupSidePane(this, taskExecutor, stateManager, preferencesService, dialogService),
new WebSearchPane(this, preferencesService, dialogService, stateManager),
new OpenOfficeSidePanel(this, preferencesService, frame))
.forEach(pane -> components.put(pane.getType(), pane));
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/org/jabref/gui/groups/GroupSidePane.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,30 @@
import org.jabref.gui.SidePaneComponent;
import org.jabref.gui.SidePaneManager;
import org.jabref.gui.SidePaneType;
import org.jabref.gui.StateManager;
import org.jabref.gui.actions.Action;
import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.l10n.Localization;
import org.jabref.preferences.PreferencesService;

import com.airhacks.afterburner.views.ViewLoader;

/**
* The groups side pane.
*/
public class GroupSidePane extends SidePaneComponent {

private final PreferencesService preferences;
private final DialogService dialogService;
private final TaskExecutor taskExecutor;
private final StateManager stateManager;
private final Button intersectionUnionToggle = IconTheme.JabRefIcons.GROUP_INTERSECTION.asButton();

public GroupSidePane(SidePaneManager manager, PreferencesService preferences, DialogService dialogService) {
public GroupSidePane(SidePaneManager manager, TaskExecutor taskExecutor, StateManager stateManager, PreferencesService preferences, DialogService dialogService) {
super(manager, IconTheme.JabRefIcons.TOGGLE_GROUPS, Localization.lang("Groups"));
this.preferences = preferences;
this.taskExecutor = taskExecutor;
this.stateManager = stateManager;
this.dialogService = dialogService;
}

Expand Down Expand Up @@ -83,9 +87,7 @@ private void setGraphicsAndTooltipForButton(GroupViewMode mode) {

@Override
protected Node createContentPane() {
return ViewLoader.view(GroupTreeView.class)
.load()
.getView();
return new GroupTreeView(taskExecutor, stateManager, preferences, dialogService);
}

@Override
Expand Down
43 changes: 0 additions & 43 deletions src/main/java/org/jabref/gui/groups/GroupTree.fxml

This file was deleted.

93 changes: 75 additions & 18 deletions src/main/java/org/jabref/gui/groups/GroupTreeView.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.inject.Inject;

import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Control;
Expand All @@ -23,6 +21,7 @@
import javafx.scene.control.SelectionMode;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
Expand All @@ -32,6 +31,9 @@
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;

Expand All @@ -57,29 +59,85 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GroupTreeView {
public class GroupTreeView extends BorderPane {

private static final Logger LOGGER = LoggerFactory.getLogger(GroupTreeView.class);

@FXML private TreeTableView<GroupNodeViewModel> groupTree;
@FXML private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> mainColumn;
@FXML private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> numberColumn;
@FXML private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> expansionNodeColumn;
@FXML private CustomTextField searchField;
@FXML private Button addNewGroup;
private TreeTableView<GroupNodeViewModel> groupTree;
private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> mainColumn;
private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> numberColumn;
private TreeTableColumn<GroupNodeViewModel, GroupNodeViewModel> expansionNodeColumn;
private CustomTextField searchField;
private Button addNewGroup;

@Inject private StateManager stateManager;
@Inject private DialogService dialogService;
@Inject private TaskExecutor taskExecutor;
@Inject private PreferencesService preferencesService;
private final StateManager stateManager;
private final DialogService dialogService;
private final TaskExecutor taskExecutor;
private final PreferencesService preferencesService;

private GroupTreeViewModel viewModel;
private CustomLocalDragboard localDragboard;

private DragExpansionHandler dragExpansionHandler;

@FXML
public void initialize() {
/**
* The groups panel
*
* Note: This panel is deliberately not created in FXML, since parsing of this took about 500 msecs. In an attempt
* to speed up the startup time of JabRef, this has been rewritten to plain java.
*/
public GroupTreeView(TaskExecutor taskExecutor, StateManager stateManager, PreferencesService preferencesService, DialogService dialogService) {
this.taskExecutor = taskExecutor;
this.stateManager = stateManager;
this.preferencesService = preferencesService;
this.dialogService = dialogService;

createNodes();
this.getStylesheets().add(Objects.requireNonNull(GroupTreeView.class.getResource("GroupTree.css")).toExternalForm());
initialize();
}

private void createNodes() {
searchField = new CustomTextField();

searchField.setPromptText(Localization.lang("Filter groups"));
searchField.setId("searchField");
HBox.setHgrow(searchField, Priority.ALWAYS);
HBox groupFilterBar = new HBox(searchField);
groupFilterBar.setId("groupFilterBar");
this.setTop(groupFilterBar);

mainColumn = new TreeTableColumn<>();
mainColumn.setId("mainColumn");
numberColumn = new TreeTableColumn<>();
numberColumn.getStyleClass().add("numberColumn");
numberColumn.setMinWidth(50d);
numberColumn.setMaxWidth(70d);
numberColumn.setPrefWidth(60d);
expansionNodeColumn = new TreeTableColumn<>();
expansionNodeColumn.getStyleClass().add("expansionNodeColumn");
expansionNodeColumn.setMaxWidth(25d);
expansionNodeColumn.setMinWidth(25d);

groupTree = new TreeTableView<>();
groupTree.setId("groupTree");
groupTree.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
groupTree.getColumns().addAll(List.of(mainColumn, numberColumn, expansionNodeColumn));
this.setCenter(groupTree);

addNewGroup = new Button(Localization.lang("Add group"));
addNewGroup.setId("addNewGroup");
addNewGroup.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(addNewGroup, Priority.ALWAYS);
addNewGroup.setTooltip(new Tooltip(Localization.lang("New group")));
addNewGroup.setOnAction(event -> addNewGroup());

HBox groupBar = new HBox(addNewGroup);
groupBar.setId("groupBar");
this.setBottom(groupBar);
}

private void initialize() {
this.localDragboard = stateManager.getLocalDragboard();
viewModel = new GroupTreeViewModel(stateManager, dialogService, preferencesService, taskExecutor, localDragboard);

Expand Down Expand Up @@ -396,13 +454,12 @@ private ContextMenu createContextMenuForGroup(GroupNodeViewModel group) {
return menu;
}

@FXML
private void addNewGroup() {
viewModel.addNewGroupToRoot();
}

/**
* Workaround taken from https://bitbucket.org/controlsfx/controlsfx/issues/330/making-textfieldssetupclearbuttonfield
* Workaround taken from https://github.com/controlsfx/controlsfx/issues/330
*/
private void setupClearButtonField(CustomTextField customTextField) {
try {
Expand Down