Skip to content
Closed
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
10 changes: 7 additions & 3 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
import com.google.common.eventbus.Subscribe;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fxmisc.easybind.EasyBind;


/**
Expand Down Expand Up @@ -180,8 +179,13 @@ public EntryEditor(BasePanel panel) {
add(container, BorderLayout.CENTER);

DefaultTaskExecutor.runInJavaFXThread(() -> {
EasyBind.subscribe(tabbed.getSelectionModel().selectedItemProperty(), tab -> {
EntryEditorTab activeTab = (EntryEditorTab) tab;
tabbed.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> {
if (oldTab != null) {
EntryEditorTab oldActiveTab = (EntryEditorTab) oldTab;
oldActiveTab.notifyAboutFocusLost();
}

EntryEditorTab activeTab = (EntryEditorTab) newTab;
if (activeTab != null) {
activeTab.notifyAboutFocus(entry);
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@ public void notifyAboutFocus(BibEntry entry) {
}
handleFocus();
}

/**
* Notifies the tab that it lost focus and should clear all non-reusable content.
*/
public void notifyAboutFocusLost() {

}
}
44 changes: 31 additions & 13 deletions src/main/java/org/jabref/gui/entryeditor/SourceTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class SourceTab extends EntryEditorTab {
private UndoManager undoManager;
private final ObjectProperty<ValidationMessage> sourceIsValid = new SimpleObjectProperty<>();
private final ObservableRuleBasedValidator sourceValidator = new ObservableRuleBasedValidator(sourceIsValid);
private BindingsHelper.BidirectionalMapBinding<String, String, String> entryBinding;

public SourceTab(BasePanel panel) {
this.mode = panel.getBibDatabaseContext().getMode();
Expand Down Expand Up @@ -95,19 +96,36 @@ protected void bindToEntry(BibEntry entry) {

// Store source for every change in the source code
// and update source code for every change of entry field values
BindingsHelper.bindContentBidirectional(entry.getFieldsObservable(), codeArea.textProperty(), this::storeSource, fields -> {
DefaultTaskExecutor.runInJavaFXThread(() -> {
codeArea.clear();
try {
codeArea.appendText(getSourceString(entry, mode));
} catch (IOException ex) {
codeArea.setEditable(false);
codeArea.appendText(ex.getMessage() + "\n\n" +
Localization.lang("Correct the entry, and reopen editor to display/edit source."));
LOGGER.debug("Incorrect entry", ex);
}
});
});
entryBinding = BindingsHelper.bindContentBidirectional(entry.getFieldsObservable(), codeArea.textProperty(), this::storeSource, fields ->
DefaultTaskExecutor.runInJavaFXThread(() -> {
codeArea.clear();
try {
codeArea.appendText(getSourceString(entry, mode));
} catch (IOException ex) {
codeArea.setEditable(false);
codeArea.appendText(ex.getMessage() + "\n\n" +
Localization.lang("Correct the entry, and reopen editor to display/edit source."));
LOGGER.debug("Incorrect entry", ex);
}
}));
}

@Override
public void notifyAboutFocus(BibEntry entry) {
// Because we always clear the tab on focus lost (see notifyAboutFocusLost), we also have to always build it again
currentEntry = entry;
bindToEntry(entry);
}

@Override
public void notifyAboutFocusLost() {
if (currentEntry != null) {
currentEntry.getFieldsObservable().removeListener(entryBinding);
}

// Due to a bug in the source code editor (https://github.com/FXMisc/RichTextFX/issues/637), a hidden code editor makes troubles
// Thus, we just clear the source tab as soon as it losses focus
this.setContent(null);
}

private void storeSource(String text) {
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/org/jabref/gui/util/BindingsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,16 @@ public static <A, B> void bindContentBidirectional(ListProperty<A> listProperty,
updateB);
}

public static <A, V, B> void bindContentBidirectional(ObservableMap<A, V> propertyA, ObservableValue<B> propertyB, Consumer<B> updateA, Consumer<Map<A, V>> updateB) {
public static <A, V, B> BidirectionalMapBinding<A, V, B> bindContentBidirectional(ObservableMap<A, V> propertyA, ObservableValue<B> propertyB, Consumer<B> updateA, Consumer<Map<A, V>> updateB) {
final BidirectionalMapBinding<A, V, B> binding = new BidirectionalMapBinding<>(propertyA, propertyB, updateA, updateB);

// use list as initial source
updateB.accept(propertyA);

propertyA.addListener(binding);
propertyB.addListener(binding);

return binding;
}

public static <A, V, B> void bindContentBidirectional(ObservableMap<A, V> propertyA, Property<B> propertyB, Consumer<B> updateA, Function<Map<A, V>, B> mapToB) {
Expand Down Expand Up @@ -231,15 +233,15 @@ public void onChanged(Change<? extends A> c) {
}
}

private static class BidirectionalMapBinding<A, V, B> implements MapChangeListener<A, V>, ChangeListener<B> {
public static class BidirectionalMapBinding<A, V, B> implements MapChangeListener<A, V>, ChangeListener<B> {

private final ObservableMap<A, V> mapProperty;
private final ObservableValue<B> property;
private final Consumer<B> updateA;
private final Consumer<Map<A, V>> updateB;
private boolean updating = false;

public BidirectionalMapBinding(ObservableMap<A, V> mapProperty, ObservableValue<B> property, Consumer<B> updateA, Consumer<Map<A, V>> updateB) {
private BidirectionalMapBinding(ObservableMap<A, V> mapProperty, ObservableValue<B> property, Consumer<B> updateA, Consumer<Map<A, V>> updateB) {
this.mapProperty = mapProperty;
this.property = property;
this.updateA = updateA;
Expand Down