Repository: jabref/jabref
Issue: Menu View on empty file => Uncaught exception

JabRef 5.1--2020-05-04--b5599c9
Linux 4.9.0-12-amd64 amd64 
Java 14.0.1

- [X] I have tested the latest development version from http://builds.jabref.org/master/ and the problem persists

When clicking on the menu item "View" with an empty library on focus, a message "Uncaught exception" is displayed.

Steps to reproduce the behavior:
1. Create a new BibTeX library
2. Click on menu View

A window pops-up, displaying the message "Uncaught exception occurred in Thread[JavaFX Application Thread,5,main]
Afterwards, To be able to display the menu View on another file, JabRef needs to be re-opened.

Note: All the other menus are working as expected.

<details>
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Unknown Source)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Unknown Source)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Unknown Source)
	at java.base/java.util.Objects.checkIndex(Unknown Source)
	at java.base/java.util.ArrayList.get(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.collections.ObservableListWrapper.get(Unknown Source)
	at org.jabref/org.jabref.gui.actions.ActionHelper.isFilePresentForSelectedEntry(Unknown Source)
	at org.jabref/org.jabref.gui.documentviewer.ShowDocumentViewerAction.<init>(Unknown Source)
	at org.jabref/org.jabref.gui.JabRefFrame.lambda$createMenu$13(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at org.jabref.merged.module/javafx.event.Event.fireEvent(Unknown Source)
	at org.jabref.merged.module/javafx.scene.control.Menu.setShowing(Unknown Source)
	at org.jabref.merged.module/javafx.scene.control.Menu.show(Unknown Source)
	at org.jabref.merged.module/javafx.scene.control.skin.MenuBarSkin.showMenu(Unknown Source)
	at org.jabref.merged.module/javafx.scene.control.skin.MenuBarSkin.showMenu(Unknown Source)
	at org.jabref.merged.module/javafx.scene.control.skin.MenuBarSkin.lambda$rebuildUI$27(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at org.jabref.merged.module/javafx.event.Event.fireEvent(Unknown Source)
	at org.jabref.merged.module/javafx.scene.Scene$MouseHandler.process(Unknown Source)
	at org.jabref.merged.module/javafx.scene.Scene.processMouseEvent(Unknown Source)
	at org.jabref.merged.module/javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
	at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
	at org.jabref.merged.module/com.sun.glass.ui.View.notifyMouse(Unknown Source)
	at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
	at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)

</details>


Changed files:
src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java, src/main/java/org/jabref/gui/actions/ActionHelper.java

diff --git a/src/main/java/org/jabref/gui/actions/ActionHelper.java b/src/main/java/org/jabref/gui/actions/ActionHelper.java
index 494c64f2fc..b6b0415f59 100644
--- a/src/main/java/org/jabref/gui/actions/ActionHelper.java
+++ b/src/main/java/org/jabref/gui/actions/ActionHelper.java
@@ -13,14 +13,15 @@ import org.jabref.gui.StateManager;
 import org.jabref.model.entry.BibEntry;
 import org.jabref.model.entry.LinkedFile;
 import org.jabref.model.entry.field.Field;
-import org.jabref.model.entry.field.StandardField;
 import org.jabref.model.util.FileHelper;
 import org.jabref.preferences.PreferencesService;
 
 import org.fxmisc.easybind.EasyBind;
 import org.fxmisc.easybind.monadic.MonadicBinding;
+import org.fxmisc.easybind.monadic.MonadicObservableValue;
 
 public class ActionHelper {
+
     public static BooleanExpression needsDatabase(StateManager stateManager) {
         return stateManager.activeDatabaseProperty().isPresent();
     }
@@ -30,9 +31,8 @@ public class ActionHelper {
     }
 
     public static BooleanExpression needsEntriesSelected(int numberOfEntries, StateManager stateManager) {
-        return Bindings.createBooleanBinding(
-                () -> stateManager.getSelectedEntries().size() == numberOfEntries,
-                stateManager.getSelectedEntries());
+        return Bindings.createBooleanBinding(() -> stateManager.getSelectedEntries().size() == numberOfEntries,
+                                             stateManager.getSelectedEntries());
     }
 
     public static BooleanExpression isFieldSetForSelectedEntry(Field field, StateManager stateManager) {
@@ -50,18 +50,23 @@ public class ActionHelper {
     }
 
     public static BooleanExpression isFilePresentForSelectedEntry(StateManager stateManager, PreferencesService preferencesService) {
-        return Bindings.createBooleanBinding(() -> {
-                    List<LinkedFile> files = stateManager.getSelectedEntries().get(0).getFiles();
-                    if ((files.size() > 0) && stateManager.getActiveDatabase().isPresent()) {
-                        Optional<Path> filename = FileHelper.find(
-                                stateManager.getActiveDatabase().get(),
-                                files.get(0).getLink(),
-                                preferencesService.getFilePreferences());
-                        return filename.isPresent();
-                    } else {
-                        return false;
-                    }
-                }, stateManager.getSelectedEntries(),
-                stateManager.getSelectedEntries().get(0).getFieldBinding(StandardField.FILE));
+
+        ObservableList<BibEntry> selectedEntries = stateManager.getSelectedEntries();
+        MonadicObservableValue<Boolean> fileIsPresent = EasyBind.monadic(Bindings.valueAt(selectedEntries, 0)).map(entry -> {
+            List<LinkedFile> files = entry.getFiles();
+
+            if ((entry.getFiles().size() > 0) && stateManager.getActiveDatabase().isPresent()) {
+                Optional<Path> filename = FileHelper.find(
+                                                          stateManager.getActiveDatabase().get(),
+                                                          files.get(0).getLink(),
+                                                          preferencesService.getFilePreferences());
+                return filename.isPresent();
+            } else {
+                return false;
+            }
+
+        }).orElse(false);
+
+        return BooleanExpression.booleanExpression(fileIsPresent);
     }
 }
diff --git a/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java b/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java
index 444bf3840e..a9a94d52b1 100644
--- a/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java
+++ b/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java
@@ -5,10 +5,12 @@ import org.jabref.gui.actions.ActionHelper;
 import org.jabref.gui.actions.SimpleCommand;
 import org.jabref.preferences.PreferencesService;
 
+import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected;
+
 public class ShowDocumentViewerAction extends SimpleCommand {
 
     public ShowDocumentViewerAction(StateManager stateManager, PreferencesService preferences) {
-        this.executable.bind(ActionHelper.isFilePresentForSelectedEntry(stateManager, preferences));
+        this.executable.bind(needsEntriesSelected(stateManager).and(ActionHelper.isFilePresentForSelectedEntry(stateManager, preferences)));
     }
 
     @Override