Verified Owner
Top Inners Fields Constructors Methods
org.jabref.gui.groups

public Class GroupNodeViewModel

extends Object
Class Inheritance
Imports
java.util.ArrayList, .Collections, .HashSet, .List, .Optional, .Set, java.util.concurrent.Future, .TimeUnit, java.util.stream.Collectors, javafx.beans.InvalidationListener, .WeakInvalidationListener, javafx.beans.binding.Bindings, .BooleanBinding, .IntegerBinding, javafx.beans.property.ReadOnlyIntegerWrapper, .SimpleBooleanProperty, .SimpleObjectProperty, javafx.collections.FXCollections, .ListChangeListener, .ObservableList, javafx.scene.input.Dragboard, javafx.scene.paint.Color, org.jabref.gui.DragAndDropDataFormats, .StateManager, org.jabref.gui.icon.IconTheme, .JabRefIcon, org.jabref.gui.preferences.GuiPreferences, org.jabref.gui.util.CustomLocalDragboard, .DroppingMouseLocation, .UiTaskExecutor, org.jabref.logic.groups.GroupsFactory, org.jabref.logic.layout.format.LatexToUnicodeFormatter, org.jabref.logic.search.SearchContext, org.jabref.logic.util.BackgroundTask, .TaskExecutor, org.jabref.logic.util.strings.StringUtil, org.jabref.model.FieldChange, org.jabref.model.database.BibDatabaseContext, org.jabref.model.entry.BibEntry, org.jabref.model.groups.AbstractGroup, .AllEntriesGroup, .AutomaticDateGroup, .AutomaticEntryTypeGroup, .AutomaticGroup, .AutomaticKeywordGroup, .AutomaticPersonsGroup, .DateGroup, .EntryTypeGroup, .ExplicitGroup, .GroupEntryChanger, .GroupTreeNode, .KeywordGroup, .LastNameGroup, .RegexKeywordGroup, .SearchGroup, .TexGroup, org.jabref.model.search.event.IndexAddedOrUpdatedEvent, .IndexClosedEvent, .IndexRemovedEvent, .IndexStartedEvent, com.google.common.eventbus.Subscribe, com.tobiasdiez.easybind.EasyBind, com.tobiasdiez.easybind.EasyObservableList, org.jspecify.annotations.NonNull, .Nullable, org.slf4j.Logger, .LoggerFactory

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv class

Field Summary

Modifier and TypeField and Description
private final BooleanBinding
private final BooleanBinding
private static final int
private final ObservableList<GroupNodeViewModel>
private @Nullable Future<?>
private @Nullable org.jabref.logic.util.BackgroundTask<List<BibEntry>>
private final ListChangeListener<BibEntry>
private final BibDatabaseContext
private final SimpleObjectProperty<String>
private boolean
private final ObservableList<BibEntry>
private final SimpleBooleanProperty
private final GroupTreeNode
private final SimpleBooleanProperty
private final boolean
private final CustomLocalDragboard
private static final Logger
private final Set<String>
matchedEntries

Internal cache of matched entry IDs.

private final ReadOnlyIntegerWrapper
matchedEntriesCount

UI-facing count derived from matchedEntries.

private boolean
private final Object
matchedEntriesLock

Guards both the matched-entry cache and the derived hit-count property so readers observe a consistent pair.

private boolean
private boolean
private final InvalidationListener
private final GuiPreferences
private final List<Future<?>>
private final GroupNodeViewModel.SearchIndexListener
private final StateManager
private final TaskExecutor

Constructor Summary

AccessConstructor and Description
public
public
GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager stateManager, TaskExecutor taskExecutor, AbstractGroup group, CustomLocalDragboard localDragboard, GuiPreferences preferences)

Method Summary

Modifier and TypeMethod and Description
public boolean
acceptableDrop(Dragboard dragboard)

Decides if the content stored in the given Dragboard can be dropped on the given target row.

public List<FieldChange>
addEntriesToGroup(List<BibEntry> entries)

Returns: what the assignment changed, for the caller to record — this does not touch the journal itself, because whether the assignment is a step of its own or part of a larger one is the caller's to know

Todo

warn before assigning to a group whose membership is written to a field other than keywords, since that edits the entries in a way the user may not expect.

private void
public GroupTreeNode
public BooleanBinding
public BooleanBinding
public boolean
public boolean
public boolean
public boolean
private void
private void
private JabRefIcon
pack-priv void
public void
pack-priv void
public boolean
equals(Object o)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

public SimpleBooleanProperty
public Optional<GroupNodeViewModel>
private Optional<GroupNodeViewModel>
private Optional<GroupNodeViewModel>
pack-priv static GroupNodeViewModel
getAllEntriesGroup(BibDatabaseContext newDatabase, StateManager stateManager, TaskExecutor taskExecutor, CustomLocalDragboard localDragBoard, GuiPreferences preferences)

public Optional<GroupNodeViewModel>
getChildByPath(String pathToSource)

public ObservableList<GroupNodeViewModel>
public Color
public String
public String
public GroupTreeNode
public IntegerBinding
public JabRefIcon
public Optional<GroupTreeNode>
public String
private int
public boolean
public SimpleBooleanProperty
public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for this object.

public boolean
public boolean
public boolean
public boolean
pack-priv boolean
isMatchedBy(String searchString)

private boolean
isMatchEffective(GroupNodeViewModel vm, BibEntry entry)

Returns whether the given entry should be considered part of this group for the purpose of the groups sidebar (hit counter, highlighting, etc.).

public boolean
public void
moveTo(GroupNodeViewModel target)

Moves this group, without recording: a drag can move several groups at once, so the step is opened by whoever handles the gesture — see GroupTreeViewModel#recordTreeChange.

public void
moveTo(GroupTreeNode target, int targetIndex)

private void
onDatabaseChanged(ListChangeListener.Change<? extends BibEntry> change)

Gets invoked if an entry in the current database changes.

private Optional<JabRefIcon>
parseIcon(String iconCode)

private void
private void
private void
public void
pack-priv void
public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

private GroupNodeViewModel
private void
pack-priv void
Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAllwaitwaitwait

Field Detail

allSelectedEntriesMatchedback to summary
private final BooleanBinding allSelectedEntriesMatched
anySelectedEntriesMatchedback to summary
private final BooleanBinding anySelectedEntriesMatched
BULK_CHANGE_THRESHOLDback to summary
private static final int BULK_CHANGE_THRESHOLD
childrenback to summary
private final ObservableList<GroupNodeViewModel> children
currentUpdateFutureback to summary
private @Nullable Future<?> currentUpdateFuture
currentUpdateTaskback to summary
private @Nullable org.jabref.logic.util.BackgroundTask<List<BibEntry>> currentUpdateTask
databaseChangeListenerback to summary
private final ListChangeListener<BibEntry> databaseChangeListener
databaseContextback to summary
private final BibDatabaseContext databaseContext
displayNameback to summary
private final SimpleObjectProperty<String> displayName
disposedback to summary
private boolean disposed
entriesListback to summary
private final ObservableList<BibEntry> entriesList
Annotations
@SuppressWarnings:FieldCanBeLocal
expandedPropertyback to summary
private final SimpleBooleanProperty expandedProperty
groupNodeback to summary
private final GroupTreeNode groupNode
hasChildrenback to summary
private final SimpleBooleanProperty hasChildren
isRootback to summary
private final boolean isRoot
localDragBoardback to summary
private final CustomLocalDragboard localDragBoard
LOGGERback to summary
private static final Logger LOGGER
matchedEntriesback to summary
private final Set<String> matchedEntries

Internal cache of matched entry IDs.

Kept as a plain Set instead of an ObservableSet, because group refreshes and search-index updates can overlap while the UI stays responsive (for example inside modal dialogs). Exposing collection change events for this cache made bulk refreshes re-entrant and could trigger ConcurrentModificationException.

matchedEntriesCountback to summary
private final ReadOnlyIntegerWrapper matchedEntriesCount

UI-facing count derived from matchedEntries. The sidebar binds to this property instead of the cache itself.

matchedEntriesInitializedback to summary
private boolean matchedEntriesInitialized
matchedEntriesLockback to summary
private final Object matchedEntriesLock

Guards both the matched-entry cache and the derived hit-count property so readers observe a consistent pair.

matchedEntriesUpdateInProgressback to summary
private boolean matchedEntriesUpdateInProgress
matchedEntriesUpdatePendingback to summary
private boolean matchedEntriesUpdatePending
onInvalidatedGroupback to summary
private final InvalidationListener onInvalidatedGroup
Annotations
@SuppressWarnings:FieldCanBeLocal
preferencesback to summary
private final GuiPreferences preferences
searchIndexFuturesback to summary
private final List<Future<?>> searchIndexFutures
searchIndexListenerback to summary
private final GroupNodeViewModel.SearchIndexListener searchIndexListener
stateManagerback to summary
private final StateManager stateManager
taskExecutorback to summary
private final TaskExecutor taskExecutor

Constructor Detail

GroupNodeViewModelback to summary
public GroupNodeViewModel(@NonNull BibDatabaseContext databaseContext, @NonNull StateManager stateManager, @NonNull TaskExecutor taskExecutor, @NonNull GroupTreeNode groupNode, @NonNull CustomLocalDragboard localDragBoard, @NonNull GuiPreferences preferences)
GroupNodeViewModelback to summary
public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager stateManager, TaskExecutor taskExecutor, AbstractGroup group, CustomLocalDragboard localDragboard, GuiPreferences preferences)

Method Detail

acceptableDropback to summary
public boolean acceptableDrop(Dragboard dragboard)

Decides if the content stored in the given Dragboard can be dropped on the given target row. Currently, the following sources are allowed:

  • another group (will be added as subgroup on drop)
  • entries if the group implements GroupEntryChanger (will be assigned to group on drop)
addEntriesToGroupback to summary
public List<FieldChange> addEntriesToGroup(List<BibEntry> entries)
Returns:List<FieldChange>

what the assignment changed, for the caller to record — this does not touch the journal itself, because whether the assignment is a step of its own or part of a larger one is the caller's to know

Todo

warn before assigning to a group whose membership is written to a field other than keywords, since that edits the entries in a way the user may not expect.

addMatchedEntryback to summary
private void addMatchedEntry(String entryId)
addSubgroupback to summary
public GroupTreeNode addSubgroup(AbstractGroup subgroup)
allSelectedEntriesMatchedPropertyback to summary
public BooleanBinding allSelectedEntriesMatchedProperty()
anySelectedEntriesMatchedPropertyback to summary
public BooleanBinding anySelectedEntriesMatchedProperty()
canAddEntriesInback to summary
public boolean canAddEntriesIn()
canAddGroupsInback to summary
public boolean canAddGroupsIn()
canBeDraggedback to summary
public boolean canBeDragged()
canRemoveback to summary
public boolean canRemove()
clearMatchedEntriesback to summary
private void clearMatchedEntries()
completeMatchedEntriesUpdateback to summary
private void completeMatchedEntriesUpdate()
createDefaultIconback to summary
private JabRefIcon createDefaultIcon()
disposeback to summary
pack-priv void dispose()
draggedOnback to summary
public void draggedOn(GroupNodeViewModel target, DroppingMouseLocation mouseLocation)
ensureMatchedEntriesLoadedback to summary
pack-priv void ensureMatchedEntriesLoaded()
equalsback to summary
public boolean equals(Object o)

Overrides java.lang.Object.equals.

Doc from java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Annotations
@Override
expandedPropertyback to summary
public SimpleBooleanProperty expandedProperty()
findGroupNodeViewModelback to summary
public Optional<GroupNodeViewModel> findGroupNodeViewModel(GroupTreeNode targetNode)
findGroupNodeViewModelByEqualityback to summary
private Optional<GroupNodeViewModel> findGroupNodeViewModelByEquality(GroupTreeNode targetNode)
findGroupNodeViewModelByIdentityback to summary
private Optional<GroupNodeViewModel> findGroupNodeViewModelByIdentity(GroupTreeNode targetNode)
getAllEntriesGroupback to summary
pack-priv static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase, StateManager stateManager, TaskExecutor taskExecutor, CustomLocalDragboard localDragBoard, GuiPreferences preferences)
getChildByPathback to summary
public Optional<GroupNodeViewModel> getChildByPath(String pathToSource)
getChildrenback to summary
public ObservableList<GroupNodeViewModel> getChildren()
getColorback to summary
public Color getColor()
getDescriptionback to summary
public String getDescription()
getDisplayNameback to summary
public String getDisplayName()
getGroupNodeback to summary
public GroupTreeNode getGroupNode()
getHitsback to summary
public IntegerBinding getHits()
getIconback to summary
public JabRefIcon getIcon()
getParentback to summary
public Optional<GroupTreeNode> getParent()
getPathback to summary
public String getPath()
getPositionInParentback to summary
private int getPositionInParent()
hasAllSuggestedGroupsback to summary
public boolean hasAllSuggestedGroups()
hasChildrenPropertyback to summary
public SimpleBooleanProperty hasChildrenProperty()
hashCodeback to summary
public int hashCode()

Overrides java.lang.Object.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for this object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Annotations
@Override
hasSimilarSearchGroupback to summary
public boolean hasSimilarSearchGroup(SearchGroup searchGroup)
hasSubgroupsback to summary
public boolean hasSubgroups()
isAllEntriesGroupback to summary
public boolean isAllEntriesGroup()
isEditableback to summary
public boolean isEditable()
isMatchedByback to summary
pack-priv boolean isMatchedBy(String searchString)
isMatchEffectiveback to summary
private boolean isMatchEffective(GroupNodeViewModel vm, BibEntry entry)

Returns whether the given entry should be considered part of this group for the purpose of the groups sidebar (hit counter, highlighting, etc.).

We cannot simply use groupNode.matches(entry) here. That only checks the rule of this single group and ignores the configured hierarchy type and any child groups created in the view model (for example automatic subgroups)

This method applies the hierarchy type: INDEPENDENT: match this group only, INCLUDING: match this group or any child group, REFINING: match this group and all ancestor groups.

isRootback to summary
public boolean isRoot()
moveToback to summary
public void moveTo(GroupNodeViewModel target)

Moves this group, without recording: a drag can move several groups at once, so the step is opened by whoever handles the gesture — see GroupTreeViewModel#recordTreeChange.

moveToback to summary
public void moveTo(GroupTreeNode target, int targetIndex)
onDatabaseChangedback to summary
private void onDatabaseChanged(ListChangeListener.Change<? extends BibEntry> change)

Gets invoked if an entry in the current database changes.

Implementation Note

Search groups are updated in SearchIndexListener.

parseIconback to summary
private Optional<JabRefIcon> parseIcon(String iconCode)
refreshGroupback to summary
private void refreshGroup()
removeMatchedEntryback to summary
private void removeMatchedEntry(String entryId)
replaceMatchedEntriesback to summary
private void replaceMatchedEntries(List<BibEntry> entries)
setDisplayNameback to summary
public void setDisplayName(String newName)
toggleExpansionback to summary
pack-priv void toggleExpansion()
toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Annotations
@Override
toViewModelback to summary
private GroupNodeViewModel toViewModel(GroupTreeNode child)
updateAllEntriesCountback to summary
private void updateAllEntriesCount()
updateMatchedEntriesback to summary
pack-priv void updateMatchedEntries()
org.jabref.gui.groups back to summary

pack-priv Class GroupNodeViewModel.SearchIndexListener

extends Object
Class Inheritance

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public void
public void
public void
public void
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

SearchIndexListenerback to summary
pack-priv SearchIndexListener()

Method Detail

listenback to summary
public void listen(IndexStartedEvent event)
Annotations
@Subscribe
listenback to summary
public void listen(IndexAddedOrUpdatedEvent event)
Annotations
@Subscribe
listenback to summary
public void listen(IndexRemovedEvent event)
Annotations
@Subscribe
listenback to summary
public void listen(IndexClosedEvent event)
Annotations
@Subscribe