Skip to content

Commit 16a68f3

Browse files
authored
Convert DuplicateResolverDialog to javafx (#4601)
* Convert DuplicateResolverDialog to javafx * add result * change buttons to button types simplify dialog reset duplicate bibtex key search dialog for the moment * fix help and move buttons to init return null on default
1 parent aa3657c commit 16a68f3

File tree

5 files changed

+124
-157
lines changed

5 files changed

+124
-157
lines changed

Diff for: src/main/java/org/jabref/gui/DuplicateResolverDialog.java

+74-100
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
package org.jabref.gui;
22

3-
import java.awt.BorderLayout;
4-
import java.awt.event.WindowAdapter;
5-
import java.awt.event.WindowEvent;
3+
import javafx.scene.control.Button;
4+
import javafx.scene.control.ButtonBar;
5+
import javafx.scene.control.ButtonBar.ButtonData;
6+
import javafx.scene.control.ButtonType;
7+
import javafx.scene.layout.BorderPane;
68

7-
import javax.swing.Box;
8-
import javax.swing.JButton;
9-
import javax.swing.JPanel;
10-
11-
import javafx.scene.Scene;
12-
13-
import org.jabref.gui.customjfx.CustomJFXPanel;
9+
import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverResult;
1410
import org.jabref.gui.help.HelpAction;
15-
import org.jabref.gui.importer.ImportInspectionDialog;
1611
import org.jabref.gui.mergeentries.MergeEntries;
17-
import org.jabref.gui.util.WindowLocation;
12+
import org.jabref.gui.util.BaseDialog;
1813
import org.jabref.logic.help.HelpFile;
1914
import org.jabref.logic.l10n.Localization;
2015
import org.jabref.model.entry.BibEntry;
21-
import org.jabref.preferences.JabRefPreferences;
2216

23-
public class DuplicateResolverDialog extends JabRefDialog {
17+
public class DuplicateResolverDialog extends BaseDialog<DuplicateResolverResult> {
2418

2519
public enum DuplicateResolverType {
2620
DUPLICATE_SEARCH,
@@ -30,7 +24,6 @@ public enum DuplicateResolverType {
3024
}
3125

3226
public enum DuplicateResolverResult {
33-
NOT_CHOSEN,
3427
KEEP_BOTH,
3528
KEEP_LEFT,
3629
KEEP_RIGHT,
@@ -39,108 +32,89 @@ public enum DuplicateResolverResult {
3932
BREAK
4033
}
4134

42-
JButton helpButton = new HelpAction(Localization.lang("Help"), HelpFile.FIND_DUPLICATES).getHelpButton();
43-
private final JButton cancel = new JButton(Localization.lang("Cancel"));
44-
private final JButton merge = new JButton(Localization.lang("Keep merged entry only"));
4535
private final JabRefFrame frame;
46-
private final JPanel options = new JPanel();
47-
private DuplicateResolverResult status = DuplicateResolverResult.NOT_CHOSEN;
4836
private MergeEntries me;
4937

5038
public DuplicateResolverDialog(JabRefFrame frame, BibEntry one, BibEntry two, DuplicateResolverType type) {
51-
super(Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class);
5239
this.frame = frame;
53-
init(one, two, type);
54-
}
55-
56-
public DuplicateResolverDialog(ImportInspectionDialog dialog, BibEntry one, BibEntry two,
57-
DuplicateResolverType type) {
58-
super(dialog, Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class);
59-
this.frame = dialog.getFrame();
40+
this.setTitle(Localization.lang("Possible duplicate entries"));
6041
init(one, two, type);
6142
}
6243

6344
private void init(BibEntry one, BibEntry two, DuplicateResolverType type) {
64-
JButton both;
65-
JButton second;
66-
JButton first;
67-
JButton removeExact = null;
68-
switch (type) {
69-
case DUPLICATE_SEARCH:
70-
first = new JButton(Localization.lang("Keep left"));
71-
second = new JButton(Localization.lang("Keep right"));
72-
both = new JButton(Localization.lang("Keep both"));
73-
me = new MergeEntries(one, two, frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
74-
break;
75-
case INSPECTION:
76-
first = new JButton(Localization.lang("Remove old entry"));
77-
second = new JButton(Localization.lang("Remove entry from import"));
78-
both = new JButton(Localization.lang("Keep both"));
79-
me = new MergeEntries(one, two, Localization.lang("Old entry"),
80-
Localization.lang("From import"), frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
81-
break;
82-
case DUPLICATE_SEARCH_WITH_EXACT:
83-
first = new JButton(Localization.lang("Keep left"));
84-
second = new JButton(Localization.lang("Keep right"));
85-
both = new JButton(Localization.lang("Keep both"));
86-
removeExact = new JButton(Localization.lang("Automatically remove exact duplicates"));
87-
me = new MergeEntries(one, two, frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
88-
break;
89-
default:
90-
first = new JButton(Localization.lang("Import and remove old entry"));
91-
second = new JButton(Localization.lang("Do not import entry"));
92-
both = new JButton(Localization.lang("Import and keep old entry"));
93-
me = new MergeEntries(one, two, Localization.lang("Old entry"),
94-
Localization.lang("From import"), frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
95-
break;
96-
}
9745

98-
if (removeExact != null) {
99-
options.add(removeExact);
46+
HelpAction helpCommand = new HelpAction(HelpFile.FIND_DUPLICATES);
47+
ButtonType help = new ButtonType(Localization.lang("Help"), ButtonData.HELP);
48+
49+
ButtonType cancel = ButtonType.CANCEL;
50+
ButtonType merge = new ButtonType(Localization.lang("Keep merged entry only"), ButtonData.APPLY);
51+
52+
ButtonBar options = new ButtonBar();
53+
ButtonType both;
54+
ButtonType second;
55+
ButtonType first;
56+
ButtonType removeExact = new ButtonType(Localization.lang("Automatically remove exact duplicates"), ButtonData.APPLY);
57+
boolean removeExactVisible = false;
58+
59+
switch (type) {
60+
case DUPLICATE_SEARCH:
61+
first = new ButtonType(Localization.lang("Keep left"), ButtonData.APPLY);
62+
second = new ButtonType(Localization.lang("Keep right"), ButtonData.APPLY);
63+
both = new ButtonType(Localization.lang("Keep both"), ButtonData.APPLY);
64+
me = new MergeEntries(one, two, frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
65+
break;
66+
case INSPECTION:
67+
first = new ButtonType(Localization.lang("Remove old entry"), ButtonData.APPLY);
68+
second = new ButtonType(Localization.lang("Remove entry from import"), ButtonData.APPLY);
69+
both = new ButtonType(Localization.lang("Keep both"), ButtonData.APPLY);
70+
me = new MergeEntries(one, two, Localization.lang("Old entry"),
71+
Localization.lang("From import"), frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
72+
break;
73+
case DUPLICATE_SEARCH_WITH_EXACT:
74+
first = new ButtonType(Localization.lang("Keep left"), ButtonData.APPLY);
75+
second = new ButtonType(Localization.lang("Keep right"), ButtonData.APPLY);
76+
both = new ButtonType(Localization.lang("Keep both"), ButtonData.APPLY);
77+
78+
removeExactVisible = true;
79+
80+
me = new MergeEntries(one, two, frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
81+
break;
82+
default:
83+
first = new ButtonType(Localization.lang("Import and remove old entry"), ButtonData.APPLY);
84+
second = new ButtonType(Localization.lang("Do not import entry"), ButtonData.APPLY);
85+
both = new ButtonType(Localization.lang("Import and keep old entry"), ButtonData.APPLY);
86+
me = new MergeEntries(one, two, Localization.lang("Old entry"),
87+
Localization.lang("From import"), frame.getCurrentBasePanel().getBibDatabaseContext().getMode());
88+
break;
10089
}
101-
options.add(first);
102-
options.add(second);
103-
options.add(both);
104-
options.add(merge);
105-
options.add(Box.createHorizontalStrut(5));
106-
options.add(cancel);
107-
options.add(helpButton);
108-
109-
first.addActionListener(e -> buttonPressed(DuplicateResolverResult.KEEP_LEFT));
110-
second.addActionListener(e -> buttonPressed(DuplicateResolverResult.KEEP_RIGHT));
111-
both.addActionListener(e -> buttonPressed(DuplicateResolverResult.KEEP_BOTH));
112-
merge.addActionListener(e -> buttonPressed(DuplicateResolverResult.KEEP_MERGE));
113-
if (removeExact != null) {
114-
removeExact.addActionListener(e -> buttonPressed(DuplicateResolverResult.AUTOREMOVE_EXACT));
90+
if (removeExactVisible) {
91+
this.getDialogPane().getButtonTypes().add(removeExact);
11592
}
11693

117-
cancel.addActionListener(e -> buttonPressed(DuplicateResolverResult.BREAK));
118-
addWindowListener(new WindowAdapter() {
119-
@Override
120-
public void windowClosing(WindowEvent e) {
121-
buttonPressed(DuplicateResolverResult.BREAK);
122-
}
123-
});
94+
this.getDialogPane().getButtonTypes().addAll(first, second, both, merge, cancel, help);
12495

125-
getContentPane().add(CustomJFXPanel.wrap(new Scene(me)));
126-
getContentPane().add(options, BorderLayout.SOUTH);
127-
pack();
96+
BorderPane borderPane = new BorderPane(me);
97+
borderPane.setBottom(options);
12898

129-
WindowLocation pw = new WindowLocation(this, JabRefPreferences.DUPLICATES_POS_X,
130-
JabRefPreferences.DUPLICATES_POS_Y, JabRefPreferences.DUPLICATES_SIZE_X,
131-
JabRefPreferences.DUPLICATES_SIZE_Y);
132-
pw.displayWindowAtStoredLocation();
99+
this.setResultConverter(button -> {
133100

134-
both.requestFocus();
135-
}
136-
137-
private void buttonPressed(DuplicateResolverResult result) {
138-
status = result;
139-
dispose();
140-
}
101+
if (button.equals(first)) {
102+
return DuplicateResolverResult.KEEP_LEFT;
103+
} else if (button.equals(second)) {
104+
return DuplicateResolverResult.KEEP_RIGHT;
105+
} else if (button.equals(both)) {
106+
return DuplicateResolverResult.KEEP_BOTH;
107+
} else if (button.equals(merge)) {
108+
return DuplicateResolverResult.KEEP_MERGE;
109+
} else if (button.equals(removeExact)) {
110+
return DuplicateResolverResult.AUTOREMOVE_EXACT;
111+
}
112+
return null;
113+
});
141114

142-
public DuplicateResolverResult getSelected() {
143-
return status;
115+
getDialogPane().setContent(borderPane);
116+
Button helpButton = (Button) this.getDialogPane().lookupButton(help);
117+
helpButton.setOnAction(evt -> helpCommand.getCommand().execute());
144118
}
145119

146120
public BibEntry getMergedEntry() {

Diff for: src/main/java/org/jabref/gui/DuplicateSearch.java

+28-32
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import java.util.concurrent.atomic.AtomicBoolean;
1313
import java.util.concurrent.atomic.AtomicInteger;
1414

15-
import javax.swing.SwingUtilities;
16-
1715
import org.jabref.Globals;
1816
import org.jabref.JabRefExecutorService;
1917
import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverResult;
@@ -37,15 +35,17 @@ public class DuplicateSearch extends SimpleCommand {
3735
private final AtomicBoolean libraryAnalyzed = new AtomicBoolean();
3836
private final AtomicBoolean autoRemoveExactDuplicates = new AtomicBoolean();
3937
private final AtomicInteger duplicateCount = new AtomicInteger();
38+
private final DialogService dialogService;
4039

41-
public DuplicateSearch(JabRefFrame frame) {
40+
public DuplicateSearch(JabRefFrame frame, DialogService dialogService) {
4241
this.frame = frame;
42+
this.dialogService = dialogService;
4343
}
4444

4545
@Override
4646
public void execute() {
4747
BasePanel panel = frame.getCurrentBasePanel();
48-
panel.output(Localization.lang("Searching for duplicates..."));
48+
dialogService.notify(Localization.lang("Searching for duplicates..."));
4949

5050
List<BibEntry> entries = panel.getDatabase().getEntries();
5151
duplicates.clear();
@@ -57,8 +57,7 @@ public void execute() {
5757
return;
5858
}
5959

60-
JabRefExecutorService.INSTANCE
61-
.executeInterruptableTask(() -> searchPossibleDuplicates(entries, panel.getBibDatabaseContext().getMode()), "DuplicateSearcher");
60+
JabRefExecutorService.INSTANCE.executeInterruptableTask(() -> searchPossibleDuplicates(entries, panel.getBibDatabaseContext().getMode()), "DuplicateSearcher");
6261
BackgroundTask.wrap(this::verifyDuplicates)
6362
.onSuccess(this::handleDuplicates)
6463
.executeWith(Globals.TASK_EXECUTOR);
@@ -124,13 +123,11 @@ private DuplicateSearchResult verifyDuplicates() {
124123

125124
private void askResolveStrategy(DuplicateSearchResult result, BibEntry first, BibEntry second, DuplicateResolverType resolverType) {
126125
DuplicateResolverDialog dialog = new DuplicateResolverDialog(frame, first, second, resolverType);
127-
dialog.setVisible(true);
128-
dialog.dispose();
129126

130-
DuplicateResolverResult resolverResult = dialog.getSelected();
127+
DuplicateResolverResult resolverResult = dialog.showAndWait().orElse(DuplicateResolverResult.BREAK);
131128

132129
if ((resolverResult == DuplicateResolverResult.KEEP_LEFT)
133-
|| (resolverResult == DuplicateResolverResult.AUTOREMOVE_EXACT)) {
130+
|| (resolverResult == DuplicateResolverResult.AUTOREMOVE_EXACT)) {
134131
result.remove(second);
135132
if (resolverResult == DuplicateResolverResult.AUTOREMOVE_EXACT) {
136133
autoRemoveExactDuplicates.set(true); // Remember choice
@@ -150,31 +147,30 @@ private void handleDuplicates(DuplicateSearchResult result) {
150147
return;
151148
}
152149

153-
SwingUtilities.invokeLater(() -> {
154-
BasePanel panel = frame.getCurrentBasePanel();
155-
final NamedCompound compoundEdit = new NamedCompound(Localization.lang("duplicate removal"));
156-
// Now, do the actual removal:
157-
if (!result.getToRemove().isEmpty()) {
158-
for (BibEntry entry : result.getToRemove()) {
159-
panel.getDatabase().removeEntry(entry);
160-
compoundEdit.addEdit(new UndoableRemoveEntry(panel.getDatabase(), entry, panel));
161-
}
162-
panel.markBaseChanged();
150+
BasePanel panel = frame.getCurrentBasePanel();
151+
final NamedCompound compoundEdit = new NamedCompound(Localization.lang("duplicate removal"));
152+
// Now, do the actual removal:
153+
if (!result.getToRemove().isEmpty()) {
154+
for (BibEntry entry : result.getToRemove()) {
155+
panel.getDatabase().removeEntry(entry);
156+
compoundEdit.addEdit(new UndoableRemoveEntry(panel.getDatabase(), entry, panel));
163157
}
164-
// and adding merged entries:
165-
if (!result.getToAdd().isEmpty()) {
166-
for (BibEntry entry : result.getToAdd()) {
167-
panel.getDatabase().insertEntry(entry);
168-
compoundEdit.addEdit(new UndoableInsertEntry(panel.getDatabase(), entry));
169-
}
170-
panel.markBaseChanged();
158+
panel.markBaseChanged();
159+
}
160+
// and adding merged entries:
161+
if (!result.getToAdd().isEmpty()) {
162+
for (BibEntry entry : result.getToAdd()) {
163+
panel.getDatabase().insertEntry(entry);
164+
compoundEdit.addEdit(new UndoableInsertEntry(panel.getDatabase(), entry));
171165
}
166+
panel.markBaseChanged();
167+
}
168+
169+
dialogService.notify(Localization.lang("Duplicates found") + ": " + duplicateCount.get() + ' '
170+
+ Localization.lang("pairs processed") + ": " + result.getDuplicateCount());
171+
compoundEdit.end();
172+
panel.getUndoManager().addEdit(compoundEdit);
172173

173-
panel.output(Localization.lang("Duplicates found") + ": " + duplicateCount.get() + ' '
174-
+ Localization.lang("pairs processed") + ": " + result.getDuplicateCount());
175-
compoundEdit.end();
176-
panel.getUndoManager().addEdit(compoundEdit);
177-
});
178174
}
179175

180176
/**

Diff for: src/main/java/org/jabref/gui/JabRefFrame.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ private MenuBar createMenu() {
858858
}
859859

860860
quality.getItems().addAll(
861-
factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(this)),
861+
factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(this, dialogService)),
862862
factory.createMenuItem(StandardActions.MERGE_ENTRIES, new MergeEntriesAction(this)),
863863

864864
new SeparatorMenuItem(),

Diff for: src/main/java/org/jabref/gui/bibtexkeypattern/ResolveDuplicateLabelDialog.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@ class ResolveDuplicateLabelDialog {
4444
private boolean okPressed;
4545
private boolean cancelPressed;
4646

47-
4847
public ResolveDuplicateLabelDialog(BasePanel panel, String key, List<BibEntry> entries) {
4948
diag = new JDialog((JFrame) null, Localization.lang("Duplicate BibTeX key"), true);
5049

5150
FormBuilder b = FormBuilder.create().layout(new FormLayout(
52-
"left:pref, 4dlu, fill:pref", "p"));
51+
"left:pref, 4dlu, fill:pref", "p"));
5352
b.add(new JLabel(Localization.lang("Duplicate BibTeX key") + ": " + key)).xyw(1, 1, 3);
5453
b.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
5554

@@ -59,7 +58,7 @@ public ResolveDuplicateLabelDialog(BasePanel panel, String key, List<BibEntry> e
5958
JCheckBox cb = new JCheckBox(Localization.lang("Generate BibTeX key"), !first);
6059
b.appendRows("1dlu, p");
6160
b.add(cb).xy(1, row);
62-
PreviewPanel previewPanel = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService(), ExternalFileTypes.getInstance());
61+
PreviewPanel previewPanel = new PreviewPanel(null, panel.getBibDatabaseContext(), Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService(), ExternalFileTypes.getInstance());
6362
previewPanel.setEntry(entry);
6463
JFXPanel container = CustomJFXPanel.wrap(new Scene(previewPanel));
6564
container.setPreferredSize(new Dimension(800, 90));
@@ -86,8 +85,8 @@ public ResolveDuplicateLabelDialog(BasePanel panel, String key, List<BibEntry> e
8685
diag.pack();
8786

8887
ok.addActionListener(e -> {
89-
okPressed = true;
90-
diag.dispose();
88+
okPressed = true;
89+
diag.dispose();
9190
});
9291

9392
ignore.addActionListener(e -> diag.dispose());

0 commit comments

Comments
 (0)