From 6e279228bad2fbe54f20a8fcebf2a8b7cb9415ef Mon Sep 17 00:00:00 2001 From: Super-Tang <36810099+Super-Tang@users.noreply.github.com> Date: Mon, 20 Aug 2018 04:06:50 +0800 Subject: [PATCH] Fix for issue 3861 : Preferences Dialog to javafx (#4253) * Convert swing dialog to JavaFx * convert the swing dialog to javafx * Change the code style to meet the standard * Update CHANGELOG.md * Update SaveOrderConfigDisplay.java * Merge the latest commits * Merge the latest commits * merge the latest commits * Polish the code style * resolve the conficts * polish the code style * reslove the conflicts * resolve the conflict * Change the CHANGELOG.md * polish the code style * polish the code style * Modify the code to make test-suite pass * polish the code style * Beautify the option panes * Polish the code style * Merge the latest commits * merge the latest commits * Merge the latest commits * Polish the code style * Polish the code style * Polish the code style * Polish the code style * Beautify the dialog * Simplify the long method in PreferencesDialog.java * Polish the code style * Polish the code style * Merge the latest commits * Change Integer.parseInt to Double.parseDouble * Change the font size of several labels * fix a bug regarding the storeing of settings * fix the code style * Fix NullPointerException in settings for External Applications * Polish code style * Add a row * Fix NullPointerException in settings for External Application * push again to make test pass * Push again to make test pass * push again to make test pass * Push again to make test pass * Push again to make test pass * Update JabRefGUI.java * Update JabRefGUI.java * correct the wrong label name in settings for external Application * remove the duplicates and cleanup the code * remove unused imports * remove the duplicates in SaveOrderConfigDisplay.java * remove the unused imports in SaveOrderConfigDisplay.java * Change the return type to Interface Type * Change to lambda expression * cleanup the code * Merge latest commits * remove the Swing contron in BibtexKeyPatternPanel * Code style :( --- CHANGELOG.md | 1 + build.gradle | 26 +- src/main/java/org/jabref/JabRefGUI.java | 20 +- src/main/java/org/jabref/gui/BasePanel.java | 82 +- .../java/org/jabref/gui/ReplaceString.fxml | 2 +- .../jabref/gui/SaveOrderConfigDisplay.java | 103 +-- .../BibtexKeyPatternDialog.java | 7 +- .../BibtexKeyPatternPanel.java | 207 ++--- .../DatabasePropertiesDialog.java | 8 +- .../gui/exporter/SaveDatabaseAction.java | 14 +- .../gui/fieldeditors/EditorTextArea.java | 4 +- .../jabref/gui/fieldeditors/UrlEditor.java | 7 +- .../LinkedFilesEditDialogViewModel.java | 6 +- .../org/jabref/gui/preftabs/AdvancedTab.java | 153 ++-- .../gui/preftabs/AppearancePrefsTab.java | 29 +- .../gui/preftabs/BibtexKeyPatternPrefTab.java | 121 ++- .../gui/preftabs/EntryEditorPrefsTab.java | 227 +++--- .../gui/preftabs/ExportSortingPrefsTab.java | 95 ++- .../org/jabref/gui/preftabs/ExternalTab.java | 295 ++++---- .../java/org/jabref/gui/preftabs/FileTab.java | 279 ++++--- .../org/jabref/gui/preftabs/FontSize.java | 11 + .../org/jabref/gui/preftabs/GeneralTab.java | 272 ++++--- .../jabref/gui/preftabs/GroupsPrefsTab.java | 137 ++-- .../gui/preftabs/ImportSettingsTab.java | 196 +++-- .../jabref/gui/preftabs/NameFormatterTab.java | 330 +++----- .../org/jabref/gui/preftabs/NetworkTab.java | 149 ++-- .../gui/preftabs/PreferencesDialog.java | 314 ++++---- .../jabref/gui/preftabs/PreviewPrefsTab.java | 196 +++-- .../jabref/gui/preftabs/TableColumnsTab.java | 711 +++++++----------- .../jabref/gui/preftabs/TablePrefsTab.java | 297 ++++---- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 274 +++---- .../gui/push/PushToApplicationSettings.java | 59 +- .../push/PushToApplicationSettingsDialog.java | 4 +- .../jabref/gui/push/PushToApplications.java | 1 - .../jabref/gui/push/PushToEmacsSettings.java | 12 +- .../jabref/gui/push/PushToVimSettings.java | 4 +- .../java/org/jabref/gui/util/ThemeLoader.java | 2 +- .../bibtexfields/CleanupURLFormatter.java | 3 +- src/main/resources/l10n/JabRef_zh.properties | 2 - src/test/resources/log4j2-test.xml | 2 +- 40 files changed, 2087 insertions(+), 2575 deletions(-) create mode 100644 src/main/java/org/jabref/gui/preftabs/FontSize.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d5bd75123e..2c74df57dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -132,3 +132,4 @@ The changelog of JabRef 2.11 and all previous versions is available as [text fil [4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta [2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 [JavaFX]: https://en.wikipedia.org/wiki/JavaFX + diff --git a/build.gradle b/build.gradle index a2bb79c7f76..a493ae0bca1 100644 --- a/build.gradle +++ b/build.gradle @@ -205,12 +205,12 @@ dependencyUpdates.resolutionStrategy = { } rules.withModule("org.controlsfx:controlsfx") { ComponentSelection selection -> if (selection.candidate.version ==~ /9.*/) { // Reject version 9 or higher - selection.reject("Cannot be updated to 9.*.* until Jabref works with Java 9") + selection.reject("Cannot be updated to 9.*.* until Jabref works with Java 9") } } rules.withModule("com.github.tomtung:latex2unicode_2.12") { ComponentSelection selection -> if (selection.candidate.version ==~ /0.2.2/) { // Reject version higher than 2.0.2 - selection.reject("Cannot be updated to 0.2.4 until JabRef is prepared for it") + selection.reject("Cannot be updated to 0.2.4 until JabRef is prepared for it") } } rules.withModule("de.jensd:fontawesomefx-materialdesignfont") { ComponentSelection selection -> @@ -505,16 +505,16 @@ jmh { // Source: https://stackoverflow.com/a/44168582/873282 task downloadDependencies { - description "Pre-downloads *most* dependencies" - doLast { - configurations.getAsMap().each { name, config -> - println "Retrieving dependencies for $name" - try { - config.files - } catch (e) { - // some cannot be resolved, just log them - project.logger.info e.message - } + description "Pre-downloads *most* dependencies" + doLast { + configurations.getAsMap().each { name, config -> + println "Retrieving dependencies for $name" + try { + config.files + } catch (e) { + // some cannot be resolved, just log them + project.logger.info e.message + } + } } - } } diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index dc03333b7bf..84ea60e87cb 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -54,10 +54,10 @@ public JabRefGUI(Stage mainStage, List argsDatabases, boolean isBl // passed file (we take the first one) should be focused focusedFile = argsDatabases.stream() - .findFirst() - .flatMap(ParserResult::getFile) - .map(File::getAbsolutePath) - .orElse(Globals.prefs.get(JabRefPreferences.LAST_FOCUSED)); + .findFirst() + .flatMap(ParserResult::getFile) + .map(File::getAbsolutePath) + .orElse(Globals.prefs.get(JabRefPreferences.LAST_FOCUSED)); openWindow(mainStage); JabRefGUI.checkForNewVersion(false); @@ -109,15 +109,15 @@ private void openWindow(Stage mainStage) { try { new SharedDatabaseUIManager(mainFrame).openSharedDatabaseFromParserResult(pr); } catch (SQLException | DatabaseNotSupportedException | InvalidDBMSConnectionPropertiesException | - NotASharedDatabaseException e) { + NotASharedDatabaseException e) { pr.getDatabaseContext().clearDatabaseFile(); // do not open the original file pr.getDatabase().clearSharedDatabaseID(); LOGGER.error("Connection error", e); dialogService.showErrorDialogAndWait( - Localization.lang("Connection error"), - Localization.lang("A local copy will be opened."), - e); + Localization.lang("Connection error"), + Localization.lang("A local copy will be opened."), + e); } toOpenTab.add(pr); } else if (pr.toOpenTab()) { @@ -166,7 +166,7 @@ private void openWindow(Stage mainStage) { for (ParserResult pr : failed) { String message = Localization.lang("Error opening file '%0'.", pr.getFile().get().getName()) + "\n" - + pr.getErrorMessage(); + + pr.getErrorMessage(); dialogService.showErrorDialogAndWait(Localization.lang("Error opening file"), message); @@ -223,7 +223,7 @@ private void openLastEditedDatabases() { } ParserResult parsedDatabase = OpenDatabase.loadDatabase(fileName, - Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); if (parsedDatabase.isEmpty()) { LOGGER.error(Localization.lang("Error opening file") + " '" + dbFile.getPath() + "'"); diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 3ed33579d80..306939d3ace 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -396,33 +396,33 @@ private void setupActions() { actions.put(Actions.REPLACE_ALL, ()-> (new ReplaceStringAction(this)).execute()); actions.put(new SpecialFieldValueViewModel(SpecialField.RELEVANCE.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.RELEVANCE, undoManager).getSpecialFieldAction(SpecialField.RELEVANCE.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.RELEVANCE, undoManager).getSpecialFieldAction(SpecialField.RELEVANCE.getValues().get(0), frame)); actions.put(new SpecialFieldValueViewModel(SpecialField.QUALITY.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.QUALITY, undoManager).getSpecialFieldAction(SpecialField.QUALITY.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.QUALITY, undoManager).getSpecialFieldAction(SpecialField.QUALITY.getValues().get(0), frame)); actions.put(new SpecialFieldValueViewModel(SpecialField.PRINTED.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.PRINTED, undoManager).getSpecialFieldAction(SpecialField.PRINTED.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.PRINTED, undoManager).getSpecialFieldAction(SpecialField.PRINTED.getValues().get(0), frame)); for (SpecialFieldValue prio : SpecialField.PRIORITY.getValues()) { actions.put(new SpecialFieldValueViewModel(prio).getCommand(), - new SpecialFieldViewModel(SpecialField.PRIORITY, undoManager).getSpecialFieldAction(prio, this.frame)); + new SpecialFieldViewModel(SpecialField.PRIORITY, undoManager).getSpecialFieldAction(prio, this.frame)); } for (SpecialFieldValue rank : SpecialField.RANKING.getValues()) { actions.put(new SpecialFieldValueViewModel(rank).getCommand(), - new SpecialFieldViewModel(SpecialField.RANKING, undoManager).getSpecialFieldAction(rank, this.frame)); + new SpecialFieldViewModel(SpecialField.RANKING, undoManager).getSpecialFieldAction(rank, this.frame)); } for (SpecialFieldValue status : SpecialField.READ_STATUS.getValues()) { actions.put(new SpecialFieldValueViewModel(status).getCommand(), - new SpecialFieldViewModel(SpecialField.READ_STATUS, undoManager).getSpecialFieldAction(status, this.frame)); + new SpecialFieldViewModel(SpecialField.READ_STATUS, undoManager).getSpecialFieldAction(status, this.frame)); } actions.put(Actions.TOGGLE_PREVIEW, () -> { PreviewPreferences previewPreferences = Globals.prefs.getPreviewPreferences(); boolean enabled = !previewPreferences.isPreviewPanelEnabled(); PreviewPreferences newPreviewPreferences = previewPreferences.getBuilder() - .withPreviewPanelEnabled(enabled) - .build(); + .withPreviewPanelEnabled(enabled) + .build(); Globals.prefs.storePreviewPreferences(newPreviewPreferences); DefaultTaskExecutor.runInJavaFXThread(() -> setPreviewActiveBasePanels(enabled)); }); @@ -516,9 +516,9 @@ private void copyTitle() { if (!selectedBibEntries.isEmpty()) { // Collect all non-null titles. List titles = selectedBibEntries.stream() - .filter(bibEntry -> bibEntry.getTitle().isPresent()) - .map(bibEntry -> bibEntry.getTitle().get()) - .collect(Collectors.toList()); + .filter(bibEntry -> bibEntry.getTitle().isPresent()) + .map(bibEntry -> bibEntry.getTitle().get()) + .collect(Collectors.toList()); if (titles.isEmpty()) { output(Localization.lang("None of the selected entries have titles.")); @@ -550,8 +550,8 @@ private void copyCiteKey() { String sb = String.join(",", keys); String citeCommand = Optional.ofNullable(Globals.prefs.get(JabRefPreferences.CITE_COMMAND)) - .filter(cite -> cite.contains("\\")) // must contain \ - .orElse("\\cite"); + .filter(cite -> cite.contains("\\")) // must contain \ + .orElse("\\cite"); Globals.clipboardManager.setContent(citeCommand + "{" + sb + '}'); if (keys.size() == bes.size()) { @@ -595,7 +595,7 @@ private void copyKeyAndTitle() { Layout layout; try { layout = new LayoutHelper(sr, Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader)) - .getLayoutFromText(); + .getLayoutFromText(); } catch (IOException e) { LOGGER.info("Could not get layout", e); return; @@ -685,7 +685,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding, final String SAVE_DATABASE = Localization.lang("Save library"); try { SavePreferences prefs = Globals.prefs.loadForSaveFromPreferences() - .withEncoding(encoding) + .withEncoding(encoding) .withSaveType(saveType); BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter<>( FileSaveSession::new); @@ -718,7 +718,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding, boolean commit = true; if (!session.getWriter().couldEncodeAll()) { FormBuilder builder = FormBuilder.create() - .layout(new FormLayout("left:pref, 4dlu, fill:pref", "pref, 4dlu, pref")); + .layout(new FormLayout("left:pref, 4dlu, fill:pref", "pref, 4dlu, pref")); JTextArea ta = new JTextArea(session.getWriter().getProblemCharacters()); ta.setEditable(false); builder.add(Localization.lang("The chosen encoding '%0' could not encode the following characters:", session.getEncoding().displayName())).xy(1, 1); @@ -867,12 +867,12 @@ private void createMainTable() { // Update entry editor and preview according to selected entries mainTable.addSelectionListener(event -> mainTable.getSelectedEntries() - .stream() - .findFirst() - .ifPresent(entry -> { - preview.setEntry(entry); - entryEditor.setEntry(entry); - })); + .stream() + .findFirst() + .ifPresent(entry -> { + preview.setEntry(entry); + entryEditor.setEntry(entry); + })); // TODO: Register these actions globally /* @@ -962,8 +962,8 @@ public void setupMainPanel() { // Saves the divider position as soon as it changes // We need to keep a reference to the subscription, otherwise the binding gets garbage collected dividerPositionSubscription = EasyBind.monadic(Bindings.valueAt(splitPane.getDividers(), 0)) - .flatMap(SplitPane.Divider::positionProperty) - .subscribe((observable, oldValue, newValue) -> saveDividerLocation(newValue)); + .flatMap(SplitPane.Divider::positionProperty) + .subscribe((observable, oldValue, newValue) -> saveDividerLocation(newValue)); } /** @@ -1093,9 +1093,9 @@ public void previousPreviewStyle() { private void cyclePreview(int newPosition) { PreviewPreferences previewPreferences = Globals.prefs.getPreviewPreferences() - .getBuilder() - .withPreviewCyclePosition(newPosition) - .build(); + .getBuilder() + .withPreviewCyclePosition(newPosition) + .build(); Globals.prefs.storePreviewPreferences(previewPreferences); preview.updateLayout(previewPreferences); @@ -1259,11 +1259,11 @@ public boolean showDeleteConfirmationDialog(int numberOfEntries) { } return dialogService.showConfirmationDialogWithOptOutAndWait(title, - message, - okButton, - cancelButton, - Localization.lang("Disable this confirmation dialog"), - optOut -> Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, !optOut)); + message, + okButton, + cancelButton, + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, !optOut)); } else { return true; } @@ -1303,9 +1303,9 @@ private void saveDividerLocation(Number position) { if (mode == BasePanelMode.SHOWING_PREVIEW) { PreviewPreferences previewPreferences = Globals.prefs.getPreviewPreferences() - .getBuilder() - .withPreviewPanelDividerPosition(position) - .build(); + .getBuilder() + .withPreviewPanelDividerPosition(position) + .build(); Globals.prefs.storePreviewPreferences(previewPreferences); } else if (mode == BasePanelMode.SHOWING_EDITOR) { preferences.setEntryEditorDividerPosition(position.doubleValue()); @@ -1600,18 +1600,18 @@ public void action() { List files = bes.get(0).getFiles(); Optional linkedFile = files.stream() - .filter(file -> (FieldName.URL.equalsIgnoreCase(file.getFileType()) - || FieldName.PS.equalsIgnoreCase(file.getFileType()) - || FieldName.PDF.equalsIgnoreCase(file.getFileType()))) - .findFirst(); + .filter(file -> (FieldName.URL.equalsIgnoreCase(file.getFileType()) + || FieldName.PS.equalsIgnoreCase(file.getFileType()) + || FieldName.PDF.equalsIgnoreCase(file.getFileType()))) + .findFirst(); if (linkedFile.isPresent()) { try { JabRefDesktop.openExternalFileAnyFormat(bibDatabaseContext, - linkedFile.get().getLink(), - ExternalFileTypes.getInstance().fromLinkedFile(linkedFile.get(), true)); + linkedFile.get().getLink(), + ExternalFileTypes.getInstance().fromLinkedFile(linkedFile.get(), true)); output(Localization.lang("External viewer called") + '.'); } catch (IOException e) { diff --git a/src/main/java/org/jabref/gui/ReplaceString.fxml b/src/main/java/org/jabref/gui/ReplaceString.fxml index 3bf75a8f8a2..7d1c6a3488b 100644 --- a/src/main/java/org/jabref/gui/ReplaceString.fxml +++ b/src/main/java/org/jabref/gui/ReplaceString.fxml @@ -36,7 +36,7 @@ + text="%Limit to Selected Entries"/> diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index a2d8d023174..c55dd92fd35 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -1,32 +1,32 @@ package org.jabref.gui; -import java.awt.Component; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JPanel; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; - public class SaveOrderConfigDisplay { - private JPanel panel; - private JComboBox savePriSort; - private JComboBox saveSecSort; - private JComboBox saveTerSort; - private JCheckBox savePriDesc; - private JCheckBox saveSecDesc; - private JCheckBox saveTerDesc; + private GridPane panel; + private ComboBox savePriSort; + private ComboBox saveSecSort; + private ComboBox saveTerSort; + private CheckBox savePriDesc; + private CheckBox saveSecDesc; + private CheckBox saveTerDesc; public SaveOrderConfigDisplay() { @@ -37,57 +37,60 @@ private void init() { List fieldNames = InternalBibtexFields.getAllPublicFieldNames(); fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); - String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - savePriSort = new JComboBox<>(allPlusKey); + savePriSort = new ComboBox<>(FXCollections.observableArrayList(fieldNames)); savePriSort.setEditable(true); - saveSecSort = new JComboBox<>(allPlusKey); + saveSecSort = new ComboBox<>(FXCollections.observableArrayList(fieldNames)); saveSecSort.setEditable(true); - saveTerSort = new JComboBox<>(allPlusKey); + saveTerSort = new ComboBox<>(FXCollections.observableArrayList(fieldNames)); saveTerSort.setEditable(true); - savePriDesc = new JCheckBox(Localization.lang("Descending")); - saveSecDesc = new JCheckBox(Localization.lang("Descending")); - saveTerDesc = new JCheckBox(Localization.lang("Descending")); - - FormLayout layout = new FormLayout("right:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", - "pref, 2dlu, pref, 2dlu, pref"); - FormBuilder builder = FormBuilder.create().layout(layout); - builder.add(Localization.lang("Primary sort criterion")).xy(1, 1); - builder.add(savePriSort).xy(3, 1); - builder.add(savePriDesc).xy(5, 1); - - builder.add(Localization.lang("Secondary sort criterion")).xy(1, 3); - builder.add(saveSecSort).xy(3, 3); - builder.add(saveSecDesc).xy(5, 3); - - builder.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); - builder.add(saveTerSort).xy(3, 5); - builder.add(saveTerDesc).xy(5, 5); - - panel = builder.build(); + savePriDesc = new CheckBox(Localization.lang("Descending")); + saveSecDesc = new CheckBox(Localization.lang("Descending")); + saveTerDesc = new CheckBox(Localization.lang("Descending")); + + Font font = new Font(10); + GridPane builder = new GridPane(); + Label primarySortCriterion = new Label(Localization.lang("Primary sort criterion")); + primarySortCriterion.setFont(font); + builder.add(primarySortCriterion, 1, 1); + builder.add(savePriSort, 2, 1); + builder.add(savePriDesc, 3, 1); + + Label secondarySortCriterion = new Label(Localization.lang("Secondary sort criterion")); + secondarySortCriterion.setFont(font); + builder.add(secondarySortCriterion, 1, 2); + builder.add(saveSecSort, 2, 2); + builder.add(saveSecDesc, 3, 2); + + Label tertiarySortCriterion = new Label(Localization.lang("Tertiary sort criterion")); + tertiarySortCriterion.setFont(font); + builder.add(tertiarySortCriterion, 1, 3); + builder.add(saveTerSort, 2, 3); + builder.add(saveTerDesc, 3, 3); + panel = builder; } - public Component getPanel() { + public Node getJFXPanel() { return panel; } public void setEnabled(boolean enabled) { - savePriSort.setEnabled(enabled); - savePriDesc.setEnabled(enabled); - saveSecSort.setEnabled(enabled); - saveSecDesc.setEnabled(enabled); - saveTerSort.setEnabled(enabled); - saveTerDesc.setEnabled(enabled); + savePriSort.setDisable(!enabled); + savePriDesc.setDisable(!enabled); + saveSecSort.setDisable(!enabled); + saveSecDesc.setDisable(!enabled); + saveTerSort.setDisable(!enabled); + saveTerDesc.setDisable(!enabled); } public void setSaveOrderConfig(SaveOrderConfig saveOrderConfig) { Objects.requireNonNull(saveOrderConfig); - savePriSort.setSelectedItem(saveOrderConfig.sortCriteria[0].field); + savePriSort.setValue(saveOrderConfig.sortCriteria[0].field); savePriDesc.setSelected(saveOrderConfig.sortCriteria[0].descending); - saveSecSort.setSelectedItem(saveOrderConfig.sortCriteria[1].field); + saveSecSort.setValue(saveOrderConfig.sortCriteria[1].field); saveSecDesc.setSelected(saveOrderConfig.sortCriteria[1].descending); - saveTerSort.setSelectedItem(saveOrderConfig.sortCriteria[2].field); + saveTerSort.setValue(saveOrderConfig.sortCriteria[2].field); saveTerDesc.setSelected(saveOrderConfig.sortCriteria[2].descending); } @@ -104,7 +107,7 @@ public SaveOrderConfig getSaveOrderConfig() { return saveOrderConfig; } - private String getSelectedItemAsLowerCaseTrim(JComboBox sortBox) { - return sortBox.getSelectedItem().toString().toLowerCase(Locale.ROOT).trim(); + private String getSelectedItemAsLowerCaseTrim(ComboBox sortBox) { + return sortBox.getValue().toLowerCase(Locale.ROOT).trim(); } } diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java index 9b04361a327..7fc92b94f67 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java @@ -13,9 +13,13 @@ import javax.swing.JPanel; import javax.swing.WindowConstants; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefDialog; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.keyboard.KeyBinder; import org.jabref.logic.l10n.Localization; import org.jabref.model.bibtexkeypattern.AbstractBibtexKeyPattern; @@ -41,7 +45,8 @@ public BibtexKeyPatternDialog(BasePanel panel) { private void init() { getContentPane().setLayout(new BorderLayout()); - getContentPane().add(bibtexKeyPatternPanel, BorderLayout.CENTER); + JFXPanel bibPanel = CustomJFXPanel.wrap(new Scene(bibtexKeyPatternPanel)); + getContentPane().add(bibPanel, BorderLayout.CENTER); JButton ok = new JButton(Localization.lang("OK")); JButton cancel = new JButton(); // label of "cancel" is set later as the label is overwritten by assigning an action to the button diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 5d92dce5e62..35ce60b3592 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -1,26 +1,21 @@ package org.jabref.gui.bibtexkeypattern; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; -import java.awt.Insets; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.preftabs.FontSize; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.EntryTypes; @@ -31,21 +26,21 @@ import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; -public class BibtexKeyPatternPanel extends JPanel { +public class BibtexKeyPatternPanel extends Pane { // used by both BibtexKeyPatternPanel and TabLabelPAttern protected final GridBagLayout gbl = new GridBagLayout(); protected final GridBagConstraints con = new GridBagConstraints(); // default pattern - protected final JTextField defaultPat = new JTextField(); - + protected final TextField defaultPat = new TextField(); private final HelpAction help; // one field for each type - private final Map textFields = new HashMap<>(); + private final Map textFields = new HashMap<>(); + private final TextField[] textFieldArray = new TextField[19]; private final BasePanel panel; - + private final GridPane gridPane = new GridPane(); public BibtexKeyPatternPanel(BasePanel panel) { this.panel = panel; @@ -54,53 +49,24 @@ public BibtexKeyPatternPanel(BasePanel panel) { } private void buildGUI() { - JPanel pan = new JPanel(); - JScrollPane sp = new JScrollPane(pan); - sp.setPreferredSize(new Dimension(100, 100)); - sp.setBorder(BorderFactory.createEmptyBorder()); - pan.setLayout(gbl); - setLayout(gbl); // The header - can be removed - JLabel lblEntryType = new JLabel(Localization.lang("Entry type")); - Font f = new Font("plain", Font.BOLD, 12); - lblEntryType.setFont(f); - con.gridx = 0; - con.gridy = 0; - con.gridwidth = 1; - con.gridheight = 1; - con.fill = GridBagConstraints.VERTICAL; - con.anchor = GridBagConstraints.WEST; - con.insets = new Insets(5, 5, 10, 0); - gbl.setConstraints(lblEntryType, con); - pan.add(lblEntryType); + Label label = new Label(Localization.lang("Entry type")); + label.setFont(FontSize.smallFont); + gridPane.add(label, 1, 1); - JLabel lblKeyPattern = new JLabel(Localization.lang("Key pattern")); - lblKeyPattern.setFont(f); - con.gridx = 1; - con.gridy = 0; - con.gridheight = 1; - con.fill = GridBagConstraints.HORIZONTAL; - con.anchor = GridBagConstraints.WEST; - con.insets = new Insets(5, 5, 10, 5); - gbl.setConstraints(lblKeyPattern, con); - pan.add(lblKeyPattern); + Label keyPattern = new Label(Localization.lang("Key pattern")); + keyPattern.setFont(FontSize.smallFont); + gridPane.add(keyPattern, 3, 1); - con.gridy = 1; - con.gridx = 0; - JLabel lab = new JLabel(Localization.lang("Default pattern")); - gbl.setConstraints(lab, con); - pan.add(lab); - con.gridx = 1; - gbl.setConstraints(defaultPat, con); - pan.add(defaultPat); - con.insets = new Insets(5, 5, 10, 5); - JButton btnDefault = new JButton(Localization.lang("Default")); - btnDefault.addActionListener( - e -> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); - con.gridx = 2; - int y = 2; - gbl.setConstraints(btnDefault, con); - pan.add(btnDefault); + Label defaultPattern = new Label(Localization.lang("Default pattern")); + defaultPattern.setFont(FontSize.smallFont); + gridPane.add(defaultPattern, 1, 2); + gridPane.add(defaultPat, 3, 2); + + Button button = new Button("Default"); + button.setFont(FontSize.smallFont); + button.setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); + gridPane.add(button, 4, 2); BibDatabaseMode mode; // check mode of currently used DB @@ -111,98 +77,50 @@ private void buildGUI() { mode = Globals.prefs.getDefaultBibDatabaseMode(); } + addExtraText(mode); + int y = 0; for (EntryType type : EntryTypes.getAllValues(mode)) { - textFields.put(type.getName().toLowerCase(Locale.ROOT), addEntryType(pan, type, y)); + textFields.put(type.getName().toLowerCase(Locale.ROOT), textFieldArray[y]); y++; } - con.fill = GridBagConstraints.BOTH; - con.gridx = 0; - con.gridy = 1; - con.gridwidth = 3; - con.weightx = 1; - con.weighty = 1; - gbl.setConstraints(sp, con); - add(sp); - - // A help button - con.gridwidth = 1; - con.gridx = 1; - con.gridy = 2; - con.fill = GridBagConstraints.HORIZONTAL; - // - con.weightx = 0; - con.weighty = 0; - con.anchor = GridBagConstraints.SOUTHEAST; - con.insets = new Insets(0, 5, 0, 5); - JButton hlb = new JButton(IconTheme.JabRefIcons.HELP.getSmallIcon()); - hlb.setToolTipText(Localization.lang("Help on key patterns")); - gbl.setConstraints(hlb, con); - add(hlb); - hlb.addActionListener(help); + Button help1 = new Button("?"); + help1.setOnAction(e->new HelpAction(Localization.lang("Help on key patterns"), HelpFile.BIBTEX_KEY_PATTERN).getHelpButton().doClick()); + gridPane.add(help1, 1, 24); - // And finally a button to reset everything - JButton btnDefaultAll = new JButton(Localization.lang("Reset all")); - con.gridx = 2; - con.gridy = 2; - - con.weightx = 1; - con.weighty = 0; - con.anchor = GridBagConstraints.SOUTHEAST; - con.insets = new Insets(20, 5, 0, 5); - gbl.setConstraints(btnDefaultAll, con); - btnDefaultAll.addActionListener(e -> { + Button btnDefaultAll1 = new Button(Localization.lang("Reset all")); + btnDefaultAll1.setFont(FontSize.smallFont); + btnDefaultAll1.setOnAction(e-> { // reset all fields - for (JTextField field : textFields.values()) { + for (TextField field : textFieldArray) { field.setText(""); } - - // also reset the default pattern defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); }); - add(btnDefaultAll); + gridPane.add(btnDefaultAll1, 3, 24); } - private JTextField addEntryType(Container c, EntryType type, int y) { - - JLabel lab = new JLabel(type.getName()); - con.gridx = 0; - con.gridy = y; - con.fill = GridBagConstraints.BOTH; - con.weightx = 0; - con.weighty = 0; - con.anchor = GridBagConstraints.WEST; - con.insets = new Insets(0, 5, 0, 5); - gbl.setConstraints(lab, con); - c.add(lab); - - JTextField tf = new JTextField(); - tf.setColumns(15); - con.gridx = 1; - con.fill = GridBagConstraints.HORIZONTAL; - con.weightx = 1; - con.weighty = 0; - con.anchor = GridBagConstraints.CENTER; - con.insets = new Insets(0, 5, 0, 5); - gbl.setConstraints(tf, con); - c.add(tf); - - JButton but = new JButton(Localization.lang("Default")); - con.gridx = 2; - con.fill = GridBagConstraints.BOTH; - con.weightx = 0; - con.weighty = 0; - con.anchor = GridBagConstraints.CENTER; - con.insets = new Insets(0, 5, 0, 5); - gbl.setConstraints(but, con); - but.setActionCommand(type.getName().toLowerCase(Locale.ROOT)); - but.addActionListener(e -> { - JTextField tField = textFields.get(e.getActionCommand()); - tField.setText(""); - }); - c.add(but); - - return tf; + private void addExtraText(BibDatabaseMode mode) { + Label []label = new Label[19]; + Button []button = new Button[19]; + int i = 0; + for (i = 0; i <= 18; i++) { + textFieldArray[i] = new TextField(); + button[i] = new Button("Default"); + button[i].setFont(new javafx.scene.text.Font(10)); + button[i].setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); + } + i = 0; + for (EntryType type : EntryTypes.getAllValues(mode)) { + label[i] = new Label(type.getName()); + i ++; + } + for (i = 0; i <= 18; i++) { + label[i].setFont(FontSize.smallFont); + gridPane.add(label[i], 1, i + 3); + gridPane.add(textFieldArray[i], 3, i + 3); + gridPane.add(button[i], 4, i + 3); + } } /** @@ -210,7 +128,7 @@ private JTextField addEntryType(Container c, EntryType type, int y) { */ private void fillPatternUsingPanelData(AbstractBibtexKeyPattern keypatterns) { // each entry type - for (Map.Entry entry : textFields.entrySet()) { + for (Map.Entry entry : textFields.entrySet()) { String text = entry.getValue().getText(); if (!text.trim().isEmpty()) { keypatterns.addBibtexKeyPattern(entry.getKey(), text); @@ -244,7 +162,7 @@ public DatabaseBibtexKeyPattern getKeyPatternAsDatabaseBibtexKeyPattern() { * @param keyPattern the BibtexKeyPattern to use as initial value */ public void setValues(AbstractBibtexKeyPattern keyPattern) { - for (Map.Entry entry : textFields.entrySet()) { + for (Map.Entry entry : textFields.entrySet()) { setValue(entry.getValue(), entry.getKey(), keyPattern); } @@ -255,7 +173,7 @@ public void setValues(AbstractBibtexKeyPattern keyPattern) { } } - private static void setValue(JTextField tf, String fieldName, AbstractBibtexKeyPattern keyPattern) { + private static void setValue(TextField tf, String fieldName, AbstractBibtexKeyPattern keyPattern) { if (keyPattern.isDefaultValue(fieldName)) { tf.setText(""); } else { @@ -263,4 +181,7 @@ private static void setValue(JTextField tf, String fieldName, AbstractBibtexKeyP } } + public GridPane getPanel() { + return gridPane; + } } diff --git a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java index 24cdaae3aee..3199b30b423 100644 --- a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java +++ b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java @@ -19,6 +19,10 @@ import javax.swing.JRadioButton; import javax.swing.JTextField; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Parent; +import javafx.scene.Scene; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; @@ -26,6 +30,7 @@ import org.jabref.gui.JabRefDialog; import org.jabref.gui.SaveOrderConfigDisplay; import org.jabref.gui.cleanup.FieldFormatterCleanupsPanel; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.util.DefaultTaskExecutor; @@ -127,7 +132,8 @@ private void init() { builder.add(saveInSpecifiedOrder).xyw(1, 17, 5); saveOrderPanel = new SaveOrderConfigDisplay(); - builder.add(saveOrderPanel.getPanel()).xyw(1, 21, 5); + JFXPanel panel = CustomJFXPanel.wrap(new Scene((Parent) saveOrderPanel.getJFXPanel())); + builder.add(panel).xyw(1, 21, 5); builder.addSeparator(Localization.lang("Library protection")).xyw(1, 23, 5); builder.add(protect).xyw(1, 25, 5); diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index e0f27a1116d..a5a99090927 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -121,9 +121,9 @@ private void doSave() { // Save the database success = saveDatabase(panel.getBibDatabaseContext().getDatabaseFile().get(), false, panel.getBibDatabaseContext() - .getMetaData() - .getEncoding() - .orElse(Globals.prefs.getDefaultEncoding())); + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding())); panel.updateTimeStamp(); } else { @@ -393,10 +393,10 @@ private boolean checkExternalModification() { ButtonType reviewChanges = new ButtonType(Localization.lang("Review changes")); Optional buttonPressed = DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showCustomButtonDialogAndWait(AlertType.CONFIRMATION, Localization.lang("File updated externally"), - Localization.lang("File has been updated externally. " + "What do you want to do?"), - reviewChanges, - save, - ButtonType.CANCEL)); + Localization.lang("File has been updated externally. " + "What do you want to do?"), + reviewChanges, + save, + ButtonType.CANCEL)); if (buttonPressed.isPresent()) { if (buttonPressed.get() == ButtonType.CANCEL) { diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java index 1a5f7da082b..a718e408252 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java @@ -82,7 +82,7 @@ public void setPasteActionHandler(PasteActionHandler handler) { Objects.requireNonNull(handler); this.pasteActionHandler = handler; } - + /** * Override javafx TextArea method applying TextArea.paste() and pasteActionHandler after */ @@ -91,7 +91,7 @@ public void paste() { super.paste(); pasteActionHandler.handle(); } - + /** * Interface presents user-described paste behaviour applying to paste method */ diff --git a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java index 36546d1baa5..f004099dd00 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java @@ -28,8 +28,8 @@ public UrlEditor(String fieldName, DialogService dialogService, AutoCompleteSugg this.viewModel = new UrlEditorViewModel(fieldName, suggestionProvider, dialogService, fieldCheckers); ViewLoader.view(this) - .root(this) - .load(); + .root(this) + .load(); textArea.textProperty().bindBidirectional(viewModel.textProperty()); Supplier> contextMenuSupplier = EditorMenus.getCleanupURLMenu(textArea); @@ -37,7 +37,8 @@ public UrlEditor(String fieldName, DialogService dialogService, AutoCompleteSugg // init paste handler for URLEditor to format pasted url link in textArea textArea.setPasteActionHandler(()-> - textArea.setText(new CleanupURLFormatter().format(textArea.getText()))); + textArea.setText(new CleanupURLFormatter().format(textArea.getText()))); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); } diff --git a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java index 1226082b3d8..94c534381c1 100644 --- a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java +++ b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java @@ -76,9 +76,9 @@ public void openBrowseDialog() { String fileName = Paths.get(fileText).getFileName().toString(); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .withInitialDirectory(workingDir) - .withInitialFileName(fileName) - .build(); + .withInitialDirectory(workingDir) + .withInitialFileName(fileName) + .build(); dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(path -> { // Store the directory for next time: diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index ba94be7d18c..b63ed0850b4 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -1,13 +1,17 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Optional; -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.shape.Line; import org.jabref.Globals; import org.jabref.gui.DialogService; @@ -21,18 +25,16 @@ import org.jabref.logic.remote.RemoteUtil; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -class AdvancedTab extends JPanel implements PrefsTab { +class AdvancedTab extends Pane implements PrefsTab { private final JabRefPreferences preferences; - private final JCheckBox useRemoteServer; - private final JCheckBox useIEEEAbrv; - private final JTextField remoteServerPort; + private final CheckBox useRemoteServer; + private final CheckBox useIEEEAbrv; + private final TextField remoteServerPort; + private final CheckBox useCaseKeeperOnSearch; + private final CheckBox useUnitFormatterOnSearch; + private final GridPane builder = new GridPane(); - private final JCheckBox useCaseKeeperOnSearch; - private final JCheckBox useUnitFormatterOnSearch; private final RemotePreferences remotePreferences; private final DialogService dialogService; @@ -41,56 +43,76 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { preferences = prefs; remotePreferences = prefs.getRemotePreferences(); - useRemoteServer = new JCheckBox(Localization.lang("Listen for remote operation on port") + ':'); - useIEEEAbrv = new JCheckBox(Localization.lang("Use IEEE LaTeX abbreviations")); - remoteServerPort = new JTextField(); - useCaseKeeperOnSearch = new JCheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); - useUnitFormatterOnSearch = new JCheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu", //, 4dlu, fill:pref",// 4dlu, left:pref, 4dlu", - ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Remote operation")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(new JLabel("" - + Localization.lang("This feature lets new files be opened or imported into an " - + "already running instance of JabRef
instead of opening a new instance. For instance, this " - + "is useful when you open a file in JabRef
from your web browser." - + "
Note that this will prevent you from running more than one instance of JabRef at a time.") - + "")); - builder.nextLine(); - builder.append(new JPanel()); - - JPanel p = new JPanel(); - p.add(useRemoteServer); - p.add(remoteServerPort); - p.add(new HelpAction(HelpFile.REMOTE).getHelpButton()); - builder.append(p); - - // IEEE - builder.nextLine(); - builder.appendSeparator(Localization.lang("Search %0", "IEEEXplore")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(useIEEEAbrv); - - builder.nextLine(); - builder.appendSeparator(Localization.lang("Import conversions")); - builder.nextLine(); - builder.append(pan); - builder.append(useCaseKeeperOnSearch); - builder.nextLine(); - builder.append(pan); - builder.append(useUnitFormatterOnSearch); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + useRemoteServer = new CheckBox(Localization.lang("Listen for remote operation on port") + ':'); + useRemoteServer.setFont(FontSize.smallFont); + useIEEEAbrv = new CheckBox(Localization.lang("Use IEEE LaTeX abbreviations")); + useIEEEAbrv.setFont(FontSize.smallFont); + remoteServerPort = new TextField(); + useCaseKeeperOnSearch = new CheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); + useCaseKeeperOnSearch.setFont(FontSize.smallFont); + useUnitFormatterOnSearch = new CheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); + useUnitFormatterOnSearch.setFont(FontSize.smallFont); + + Label remoteOperation = new Label(Localization.lang("Remote operation") + " -----------------------------"); + remoteOperation.setFont(FontSize.bigFont); + builder.add(remoteOperation, 2, 1); + builder.add(new Separator(), 2, 1); + builder.add(new Pane(), 1, 2); + Label label1 = new Label(Localization.lang("This feature lets new files be opened or imported into an " + + + "already running instance of JabRef
instead of opening a new instance. For instance, this " + + + "is useful when you open a file in JabRef
from your web browser." + + + "
Note that this will prevent you from running more than one instance of JabRef at a time.")); + label1.setVisible(false); + builder.add(label1, 2, 22); + + Label textLabel1 = new Label(" This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For"); + textLabel1.setFont(FontSize.smallFont); + builder.add(textLabel1, 2, 3); + Label textLabel2 = new Label("instance, this is useful when you open a file in JabRef from your web browser. "); + textLabel2.setFont(FontSize.smallFont); + builder.add(textLabel2, 2, 4); + Label textLabel3 = new Label(" Note that this will prevent you from running more than one instance of JabRef at a time."); + textLabel3.setFont(FontSize.smallFont); + builder.add(textLabel3, 2, 5); + builder.add(new Line(), 2, 6); + builder.add(new Pane(), 2, 7); + + HBox p = new HBox(); + p.getChildren().add(useRemoteServer); + p.getChildren().add(remoteServerPort); + Button helpButton = new Button("?"); + helpButton.setFont(FontSize.smallFont); + helpButton.setOnAction(event -> new HelpAction(HelpFile.REMOTE).getHelpButton().doClick()); + p.getChildren().add(helpButton); + + builder.add(p, 2, 9); + builder.add(new Label(""), 1, 10); + + Label explore = new Label(Localization.lang("Search %0", "IEEEXplore") + " -----------------------------"); + explore.setFont(FontSize.bigFont); + builder.add(explore, 2, 11); + builder.add(new Separator(), 2, 11); + builder.add(new Pane(), 2, 12); + builder.add(useIEEEAbrv, 2, 13); + + builder.add(new Line(), 2, 16); + builder.add(new Label(""), 1, 17); + + Label importConversions = new Label(Localization.lang("Import conversions") + " ----------------------------"); + importConversions.setFont(FontSize.bigFont); + builder.add(importConversions, 2, 18); + + builder.add(useCaseKeeperOnSearch, 2, 19); + builder.add(new Pane(), 2, 20); + builder.add(useUnitFormatterOnSearch, 2, 21); + + } + public Node getBuilder() { + return builder; } @Override @@ -160,7 +182,7 @@ public boolean validateSettings() { } } catch (NumberFormatException ex) { - DefaultTaskExecutor.runInJavaFXThread(()-> dialogService.showErrorDialogAndWait(Localization.lang("Remote server port"), + DefaultTaskExecutor.runInJavaFXThread(()-> dialogService.showErrorDialogAndWait(Localization.lang("Remote server port"), Localization.lang("You must enter an integer value in the interval 1025-65535 in the text field for") + " '" + Localization.lang("Remote server port") + '\'')); @@ -172,5 +194,4 @@ public boolean validateSettings() { public String getTabName() { return Localization.lang("Advanced"); } - } diff --git a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java index 9f65eb85c3c..6defa3209b9 100644 --- a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java @@ -1,38 +1,26 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; import javafx.geometry.Insets; -import javafx.scene.Scene; +import javafx.scene.Node; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.ControlHelper; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class AppearancePrefsTab extends JPanel implements PrefsTab { - - private static final Logger LOGGER = LoggerFactory.getLogger(AppearancePrefsTab.class); +class AppearancePrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; - private final CheckBox fontTweaksLAF; private final TextField fontSize; private final CheckBox overrideFonts; - + private final VBox container = new VBox(); private final DialogService dialogService; /** @@ -43,7 +31,6 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) { this.dialogService = dialogService; this.prefs = prefs; - setLayout(new BorderLayout()); overrideFonts = new CheckBox(Localization.lang("Override default font settings")); fontSize = new TextField(); @@ -54,12 +41,12 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) fontSizeContainer.disableProperty().bind(overrideFonts.selectedProperty().not()); fontTweaksLAF = new CheckBox(Localization.lang("Tweak font rendering for entry editor on Linux")); - VBox container = new VBox(); container.getChildren().addAll(overrideFonts, fontSizeContainer, fontTweaksLAF); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(container)); - panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(panel, BorderLayout.CENTER); + } + + public Node getContainer() { + return container; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index 1d353967c07..194adda61b0 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -1,13 +1,11 @@ package org.jabref.gui.preftabs; -import java.awt.GridBagConstraints; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.BasePanel; @@ -16,35 +14,35 @@ import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * The Preferences panel for key generation. */ class BibtexKeyPatternPrefTab extends BibtexKeyPatternPanel implements PrefsTab { private final JabRefPreferences prefs; + private final GridPane builder = new GridPane(); + private final CheckBox dontOverwrite = new CheckBox(Localization.lang("Do not overwrite existing keys")); + private final CheckBox warnBeforeOverwriting = new CheckBox(Localization.lang("Warn before overwriting existing keys")); + private final CheckBox generateOnSave = new CheckBox(Localization.lang("Generate keys before saving (for entries without a key)")); + private final CheckBox autoGenerateOnImport = new CheckBox(Localization.lang("Generate keys for imported entries")); - private final JCheckBox dontOverwrite = new JCheckBox(Localization.lang("Do not overwrite existing keys")); - private final JCheckBox warnBeforeOverwriting = new JCheckBox(Localization.lang("Warn before overwriting existing keys")); - private final JCheckBox generateOnSave = new JCheckBox(Localization.lang("Generate keys before saving (for entries without a key)")); - private final JCheckBox autoGenerateOnImport = new JCheckBox(Localization.lang("Generate keys for imported entries")); + private final RadioButton letterStartA = new RadioButton(Localization.lang("Ensure unique keys using letters (a, b, ...)")); + private final RadioButton letterStartB = new RadioButton(Localization.lang("Ensure unique keys using letters (b, c, ...)")); + private final RadioButton alwaysAddLetter = new RadioButton(Localization.lang("Always add letter (a, b, ...) to generated keys")); - private final JRadioButton letterStartA = new JRadioButton(Localization.lang("Ensure unique keys using letters (a, b, ...)")); - private final JRadioButton letterStartB = new JRadioButton(Localization.lang("Ensure unique keys using letters (b, c, ...)")); - private final JRadioButton alwaysAddLetter = new JRadioButton(Localization.lang("Always add letter (a, b, ...) to generated keys")); - - private final JTextField keyPatternRegex = new JTextField(20); - private final JTextField keyPatternReplacement = new JTextField(20); + private final TextField keyPatternRegex = new TextField(); + private final TextField keyPatternReplacement = new TextField(); public BibtexKeyPatternPrefTab(JabRefPreferences prefs, BasePanel panel) { super(panel); + builder.add(super.getPanel(), 1, 1); + builder.add(new Label(""), 1, 2); this.prefs = prefs; appendKeyGeneratorSettings(); } + /** * Store changes to table preferences. This method is called when the user clicks Ok. * @@ -54,7 +52,6 @@ public void storeSettings() { // Set the default value: Globals.prefs.put(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN, defaultPat.getText()); - Globals.prefs.putBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY, warnBeforeOverwriting.isSelected()); Globals.prefs.putBoolean(JabRefPreferences.AVOID_OVERWRITING_KEY, dontOverwrite.isSelected()); @@ -81,55 +78,39 @@ public void storeSettings() { } private void appendKeyGeneratorSettings() { - ButtonGroup bg = new ButtonGroup(); - bg.add(letterStartA); - bg.add(letterStartB); - bg.add(alwaysAddLetter); - // Build a panel for checkbox settings: - FormLayout layout = new FormLayout - ("1dlu, 8dlu, left:pref, 8dlu, left:pref", ""); - JPanel pan = new JPanel(); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.appendSeparator(Localization.lang("Key generator settings")); - - builder.nextLine(); - builder.append(pan); - builder.append(autoGenerateOnImport); - builder.append(letterStartA); - builder.nextLine(); - builder.append(pan); - builder.append(warnBeforeOverwriting); - builder.append(letterStartB); - builder.nextLine(); - builder.append(pan); - builder.append(dontOverwrite); - builder.append(alwaysAddLetter); - builder.nextLine(); - builder.append(pan); - builder.append(generateOnSave); - builder.nextLine(); - builder.append(pan); - builder.append(Localization.lang("Replace (regular expression)") + ':'); - builder.append(Localization.lang("by") + ':'); - - builder.nextLine(); - builder.append(pan); - builder.append(keyPatternRegex); - builder.append(keyPatternReplacement); - - builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - con.gridx = 1; - con.gridy = 3; - con.gridwidth = GridBagConstraints.REMAINDER; - con.weightx = 1; - con.fill = GridBagConstraints.BOTH; - gbl.setConstraints(builder.getPanel(), con); - add(builder.getPanel()); - - dontOverwrite.addChangeListener(e -> + autoGenerateOnImport.setFont(FontSize.smallFont); + letterStartA.setFont(FontSize.smallFont); + warnBeforeOverwriting.setFont(FontSize.smallFont); + letterStartB.setFont(FontSize.smallFont); + dontOverwrite.setFont(FontSize.smallFont); + alwaysAddLetter.setFont(FontSize.smallFont); + generateOnSave.setFont(FontSize.smallFont); + + Label keyGeneratorSettings = new Label(Localization.lang("Key generator settings") + " --------------------------"); + keyGeneratorSettings.setFont(FontSize.bigFont); + builder.add(keyGeneratorSettings, 1, 10); + builder.add(autoGenerateOnImport, 1, 11); + builder.add(letterStartA, 2, 11); + builder.add(warnBeforeOverwriting, 1, 12); + builder.add(letterStartB, 2, 12); + builder.add(dontOverwrite, 1, 13); + builder.add(alwaysAddLetter, 2, 13); + builder.add(generateOnSave, 1, 14); + + builder.add((new Label(Localization.lang("Replace (regular expression)") + ':')), 1, 15); + builder.add(new Label(Localization.lang("by") + ':'), 2, 15); + + builder.add(keyPatternRegex, 1, 16); + builder.add(keyPatternReplacement, 2, 16); + + dontOverwrite.setOnAction(e -> // Warning before overwriting is only relevant if overwriting can happen: - warnBeforeOverwriting.setEnabled(!dontOverwrite.isSelected())); + warnBeforeOverwriting.setDisable(dontOverwrite.isSelected())); + } + + public Node getBuilder() { + return builder; } @Override @@ -157,7 +138,7 @@ public void setValues() { } // Warning before overwriting is only relevant if overwriting can happen: - warnBeforeOverwriting.setEnabled(!dontOverwrite.isSelected()); + warnBeforeOverwriting.setDisable(dontOverwrite.isSelected()); keyPatternRegex.setText(Globals.prefs.get(JabRefPreferences.KEY_PATTERN_REGEX)); keyPatternReplacement.setText(Globals.prefs.get(JabRefPreferences.KEY_PATTERN_REPLACEMENT)); diff --git a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java index 332ebc84de6..9d753245bde 100644 --- a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java @@ -1,15 +1,13 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; @@ -17,31 +15,28 @@ import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.FormLayout; - import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_ABBREVIATED; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_FULL; -class EntryEditorPrefsTab extends JPanel implements PrefsTab { - - private final JCheckBox autoOpenForm; - private final JCheckBox defSource; - private final JCheckBox emacsMode; - private final JCheckBox emacsRebindCtrlA; - private final JCheckBox emacsRebindCtrlF; - private final JCheckBox autoComplete; - private final JCheckBox recommendations; - private final JCheckBox validation; - private final JRadioButton autoCompBoth; - private final JRadioButton autoCompFF; - private final JRadioButton autoCompLF; - private final JRadioButton firstNameModeFull; - private final JRadioButton firstNameModeAbbr; - private final JRadioButton firstNameModeBoth; - - private final JTextField autoCompFields; +class EntryEditorPrefsTab extends Pane implements PrefsTab { + + private final CheckBox autoOpenForm; + private final CheckBox defSource; + private final CheckBox emacsMode; + private final CheckBox emacsRebindCtrlA; + private final CheckBox emacsRebindCtrlF; + private final CheckBox autoComplete; + private final CheckBox recommendations; + private final CheckBox validation; + private final RadioButton autoCompBoth; + private final RadioButton autoCompFF; + private final RadioButton autoCompLF; + private final RadioButton firstNameModeFull; + private final RadioButton firstNameModeAbbr; + private final RadioButton firstNameModeBoth; + private final GridPane builder = new GridPane(); + + private final TextField autoCompFields; private final JabRefPreferences prefs; private final AutoCompletePreferences autoCompletePreferences; @@ -49,104 +44,102 @@ class EntryEditorPrefsTab extends JPanel implements PrefsTab { public EntryEditorPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; autoCompletePreferences = prefs.getAutoCompletePreferences(); - setLayout(new BorderLayout()); - - autoOpenForm = new JCheckBox(Localization.lang("Open editor when a new entry is created")); - defSource = new JCheckBox(Localization.lang("Show BibTeX source by default")); - emacsMode = new JCheckBox(Localization.lang("Use Emacs key bindings")); - emacsRebindCtrlA = new JCheckBox(Localization.lang("Rebind C-a, too")); - emacsRebindCtrlF = new JCheckBox(Localization.lang("Rebind C-f, too")); - autoComplete = new JCheckBox(Localization.lang("Enable word/name autocompletion")); - recommendations = new JCheckBox(Localization.lang("Show 'Related Articles' tab")); - validation = new JCheckBox(Localization.lang("Show validation messages")); + autoOpenForm = new CheckBox(Localization.lang("Open editor when a new entry is created")); + autoOpenForm.setFont(FontSize.smallFont); + defSource = new CheckBox(Localization.lang("Show BibTeX source by default")); + defSource.setFont(FontSize.smallFont); + emacsMode = new CheckBox(Localization.lang("Use Emacs key bindings")); + emacsMode.setFont(FontSize.smallFont); + emacsRebindCtrlA = new CheckBox(Localization.lang("Rebind C-a, too")); + emacsRebindCtrlA.setFont(FontSize.smallFont); + emacsRebindCtrlF = new CheckBox(Localization.lang("Rebind C-f, too")); + emacsRebindCtrlF.setFont(FontSize.smallFont); + autoComplete = new CheckBox(Localization.lang("Enable word/name autocompletion")); + autoComplete.setFont(FontSize.smallFont); + recommendations = new CheckBox(Localization.lang("Show 'Related Articles' tab")); + recommendations.setFont(FontSize.smallFont); + validation = new CheckBox(Localization.lang("Show validation messages")); + validation.setFont(FontSize.smallFont); // allowed name formats - autoCompFF = new JRadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); - autoCompLF = new JRadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); - autoCompBoth = new JRadioButton(Localization.lang("Autocomplete names in both formats")); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(autoCompLF); - buttonGroup.add(autoCompFF); - buttonGroup.add(autoCompBoth); + autoCompFF = new RadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); + autoCompFF.setFont(FontSize.smallFont); + autoCompLF = new RadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); + autoCompLF.setFont(FontSize.smallFont); + autoCompBoth = new RadioButton(Localization.lang("Autocomplete names in both formats")); + autoCompBoth.setFont(FontSize.smallFont); // treatment of first name - firstNameModeFull = new JRadioButton(Localization.lang("Use full firstname whenever possible")); - firstNameModeAbbr = new JRadioButton(Localization.lang("Use abbreviated firstname whenever possible")); - firstNameModeBoth = new JRadioButton(Localization.lang("Use abbreviated and full firstname")); - ButtonGroup firstNameModeButtonGroup = new ButtonGroup(); - firstNameModeButtonGroup.add(firstNameModeFull); - firstNameModeButtonGroup.add(firstNameModeAbbr); - firstNameModeButtonGroup.add(firstNameModeBoth); - - Insets marg = new Insets(0, 20, 3, 0); + firstNameModeFull = new RadioButton(Localization.lang("Use full firstname whenever possible")); + firstNameModeFull.setFont(FontSize.smallFont); + firstNameModeAbbr = new RadioButton(Localization.lang("Use abbreviated firstname whenever possible")); + firstNameModeAbbr.setFont(FontSize.smallFont); + firstNameModeBoth = new RadioButton(Localization.lang("Use abbreviated and full firstname")); + firstNameModeBoth.setFont(FontSize.smallFont); - emacsRebindCtrlA.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: - emacsMode.addChangeListener(event -> emacsRebindCtrlA.setEnabled(emacsMode.isSelected())); + emacsMode.setOnAction(event -> emacsRebindCtrlA.setDisable(!emacsMode.isSelected())); - emacsRebindCtrlF.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: - emacsMode.addChangeListener(event -> emacsRebindCtrlF.setEnabled(emacsMode.isSelected())); + emacsMode.setOnAction(event -> emacsRebindCtrlF.setDisable(!emacsMode.isSelected())); - - autoCompFields = new JTextField(40); + autoCompFields = new TextField(); // We need a listener on autoComplete to enable and disable the // autoCompFields text field: - autoComplete.addChangeListener(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); - - FormLayout layout = new FormLayout - (// columns - "8dlu, left:pref, 8dlu, fill:150dlu, 4dlu, fill:pref", // 4dlu, left:pref, 4dlu", - // rows 1 to 10 - "pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu," + - // rows 11 to 16 - "pref, 6dlu, pref, 6dlu, pref, 6dlu, " + - // rows 17 to 27 - "pref, 6dlu, pref, pref, pref, pref, 6dlu, pref, pref, pref, pref, pref"); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - CellConstraints cc = new CellConstraints(); - builder.addSeparator(Localization.lang("Editor options"), cc.xyw(1, 1, 5)); - builder.add(autoOpenForm, cc.xy(2, 3)); - builder.add(defSource, cc.xy(2, 5)); - builder.add(emacsMode, cc.xy(2, 7)); - builder.add(emacsRebindCtrlA, cc.xy(2, 9)); - builder.add(emacsRebindCtrlF, cc.xy(2, 11)); - builder.add(recommendations, cc.xy(2,13)); - builder.add(validation, cc.xy(2,15)); - - builder.addSeparator(Localization.lang("Autocompletion options"), cc.xyw(1, 17, 5)); - builder.add(autoComplete, cc.xy(2, 19)); - - DefaultFormBuilder builder3 = new DefaultFormBuilder(new FormLayout("left:pref, 4dlu, fill:150dlu","")); - JLabel label = new JLabel(Localization.lang("Use autocompletion for the following fields") + ":"); - - builder3.append(label); - builder3.append(autoCompFields); - builder.add(builder3.getPanel(), cc.xyw(2, 21, 3)); - - builder.addSeparator(Localization.lang("Name format used for autocompletion"), cc.xyw(2, 23, 4)); - builder.add(autoCompFF, cc.xy(2, 24)); - builder.add(autoCompLF, cc.xy(2, 25)); - builder.add(autoCompBoth, cc.xy(2, 26)); - - builder.addSeparator(Localization.lang("Treatment of first names"), cc.xyw(2, 29, 4)); - builder.add(firstNameModeAbbr, cc.xy(2, 30)); - builder.add(firstNameModeFull, cc.xy(2, 31)); - builder.add(firstNameModeBoth, cc.xy(2, 32)); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + autoComplete.setOnAction(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); + + Label editorOptions = new Label(Localization.lang("Editor options") + " -------------------------------------"); + editorOptions.setFont(FontSize.bigFont); + builder.add(editorOptions, 1, 1); + builder.add(new Separator(), 2, 1); + builder.add(autoOpenForm, 1, 2); + builder.add(defSource, 1, 3); + builder.add(emacsMode, 1, 4); + builder.add(emacsRebindCtrlA, 1, 5); + builder.add(emacsRebindCtrlF, 1, 6); + builder.add(recommendations, 1, 7); + builder.add(validation, 1, 8); + builder.add(new Label(""), 1, 9); + + Label autocompletionOptions = new Label(Localization.lang("Autocompletion options") + " --------------------------"); + autocompletionOptions.setFont(FontSize.bigFont); + builder.add(autocompletionOptions, 1, 10); + builder.add(autoComplete, 1, 11); + + Label useFields = new Label(" " + Localization.lang("Use autocompletion for the following fields") + ":"); + useFields.setFont(FontSize.smallFont); + builder.add(useFields, 1, 12); + builder.add(autoCompFields, 2, 12); + builder.add(new Label(""), 1, 13); + + Label nameFormat = new Label(Localization.lang("Name format used for autocompletion") + " ----------"); + nameFormat.setFont(FontSize.bigFont); + builder.add(nameFormat, 1, 14); + builder.add(autoCompFF, 1, 15); + builder.add(autoCompLF, 1, 16); + builder.add(autoCompBoth, 1, 17); + builder.add(new Label(""), 1, 18); + + Label treatment = new Label(Localization.lang("Treatment of first names") + " --------------------------"); + treatment.setFont(FontSize.bigFont); + builder.add(treatment, 1, 19); + builder.add(firstNameModeAbbr, 1, 20); + builder.add(firstNameModeFull, 1, 21); + builder.add(firstNameModeBoth, 1, 22); + } + + public Node getBuilder() { + return builder; } private void setAutoCompleteElementsEnabled(boolean enabled) { - autoCompFields.setEnabled(enabled); - autoCompLF.setEnabled(enabled); - autoCompFF.setEnabled(enabled); - autoCompBoth.setEnabled(enabled); - firstNameModeAbbr.setEnabled(enabled); - firstNameModeFull.setEnabled(enabled); - firstNameModeBoth.setEnabled(enabled); + autoCompFields.setDisable(!enabled); + autoCompLF.setDisable(!enabled); + autoCompFF.setDisable(!enabled); + autoCompBoth.setDisable(!enabled); + firstNameModeAbbr.setDisable(!enabled); + firstNameModeFull.setDisable(!enabled); + firstNameModeBoth.setDisable(!enabled); } @Override @@ -181,7 +174,7 @@ public void setValues() { } // similar for emacs CTRL-a and emacs mode - emacsRebindCtrlA.setEnabled(emacsMode.isSelected()); + emacsRebindCtrlA.setDisable(!emacsMode.isSelected()); // Autocomplete fields is only enabled when autocompletion is selected setAutoCompleteElementsEnabled(autoComplete.isSelected()); diff --git a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java index 9fa67b99c12..aab52671263 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java @@ -1,81 +1,74 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JPanel; -import javax.swing.JRadioButton; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.shape.Line; import org.jabref.gui.SaveOrderConfigDisplay; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; /** * Preference tab for file sorting options. */ -class ExportSortingPrefsTab extends JPanel implements PrefsTab { +class ExportSortingPrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; - private final JRadioButton exportInOriginalOrder; - private final JRadioButton exportInTableOrder; - private final JRadioButton exportInSpecifiedOrder; + private final RadioButton exportInOriginalOrder; + private final RadioButton exportInTableOrder; + private final RadioButton exportInSpecifiedOrder; private final SaveOrderConfigDisplay exportOrderPanel; - + private final GridPane builder = new GridPane(); public ExportSortingPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - FormLayout layout = new FormLayout("4dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.leadingColumnOffset(1); - // EXPORT SORT ORDER // create Components - exportInOriginalOrder = new JRadioButton(Localization.lang("Export entries in their original order")); - exportInTableOrder = new JRadioButton(Localization.lang("Export in current table sort order")); - exportInSpecifiedOrder = new JRadioButton(Localization.lang("Export entries ordered as specified")); + exportInOriginalOrder = new RadioButton(Localization.lang("Export entries in their original order")); + exportInOriginalOrder.setFont(FontSize.smallFont); + exportInTableOrder = new RadioButton(Localization.lang("Export in current table sort order")); + exportInTableOrder.setFont(FontSize.smallFont); + exportInSpecifiedOrder = new RadioButton(Localization.lang("Export entries ordered as specified")); + exportInSpecifiedOrder.setFont(FontSize.smallFont); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(exportInOriginalOrder); - buttonGroup.add(exportInTableOrder); - buttonGroup.add(exportInSpecifiedOrder); - - ActionListener listener = new ActionListener() { + exportOrderPanel = new SaveOrderConfigDisplay(); - @Override - public void actionPerformed(ActionEvent e) { - boolean selected = e.getSource() == exportInSpecifiedOrder; + EventHandler listener = (event) -> { + boolean selected = event.getSource() == exportInSpecifiedOrder; exportOrderPanel.setEnabled(selected); - } }; - exportInOriginalOrder.addActionListener(listener); - exportInTableOrder.addActionListener(listener); - exportInSpecifiedOrder.addActionListener(listener); + exportInOriginalOrder.setOnAction(listener); + exportInTableOrder.setOnAction(listener); + exportInSpecifiedOrder.setOnAction(listener); + + Label exportSortOrder = new Label(Localization.lang("Export sort order") + " ------------------------"); + exportSortOrder.setFont(FontSize.bigFont); // create GUI - builder.appendSeparator(Localization.lang("Export sort order")); - builder.append(exportInOriginalOrder, 1); - builder.nextLine(); - builder.append(exportInTableOrder, 1); - builder.nextLine(); - builder.append(exportInSpecifiedOrder, 1); - builder.nextLine(); + builder.add(exportSortOrder, 1, 1); + builder.add(new Separator(), 2, 1); + builder.add(exportInOriginalOrder, 1, 2); + builder.add(new Line(), 2, 3); + builder.add(exportInTableOrder, 1, 4); + builder.add(new Line(), 2, 5); + builder.add(exportInSpecifiedOrder, 1, 6); + builder.add(new Line(), 2, 7); + + builder.add(exportOrderPanel.getJFXPanel(), 1, 8); + builder.add(new Line(), 2, 9); - exportOrderPanel = new SaveOrderConfigDisplay(); - builder.append(exportOrderPanel.getPanel()); - builder.nextLine(); - - // COMBINE EVERYTHING - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + } + + public Node getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index b8cab7e7e72..ffc193c0c05 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -1,23 +1,23 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; + import javax.swing.JFileChooser; -import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; + +import javafx.embed.swing.JFXPanel; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.externalfiletype.ExternalFileTypeEditor; import org.jabref.gui.push.PushToApplication; import org.jabref.gui.push.PushToApplicationSettings; @@ -27,182 +27,139 @@ import org.jabref.logic.util.OS; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - class ExternalTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; + private final TextField emailSubject; + private final TextField citeCommand; + private final CheckBox openFoldersOfAttachedFiles; - private final JTextField emailSubject; - private final JTextField citeCommand; - private final JCheckBox openFoldersOfAttachedFiles; + private final RadioButton defaultConsole; + private final RadioButton executeConsole; + private final TextField consoleCommand; + private final Button browseButton; - private final JRadioButton defaultConsole; - private final JRadioButton executeConsole; - private final JTextField consoleCommand; - private final JButton browseButton; - - private final JRadioButton adobeAcrobatReader; - private final JRadioButton sumatraReader; - private final JTextField adobeAcrobatReaderPath; - private final JTextField sumatraReaderPath; - private final JButton browseAdobeAcrobatReader; - private final JButton browseSumatraReader; + private final RadioButton adobeAcrobatReader; + private final RadioButton sumatraReader; + private final TextField adobeAcrobatReaderPath; + private final TextField sumatraReaderPath; + private final GridPane builder = new GridPane(); public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) { this.prefs = prefs; - - setLayout(new BorderLayout()); - - JButton editFileTypes = new JButton(Localization.lang("Manage external file types")); - citeCommand = new JTextField(25); - editFileTypes.addActionListener(ExternalFileTypeEditor.getAction()); - - defaultConsole = new JRadioButton(Localization.lang("Use default terminal emulator")); - executeConsole = new JRadioButton(Localization.lang("Execute command") + ":"); - consoleCommand = new JTextField(); - browseButton = new JButton(Localization.lang("Browse")); - - adobeAcrobatReader = new JRadioButton(Localization.lang("Adobe Acrobat Reader")); - adobeAcrobatReaderPath = new JTextField(); - browseAdobeAcrobatReader = new JButton(Localization.lang("Browse")); - - sumatraReader = new JRadioButton(Localization.lang("Sumatra Reader")); - sumatraReaderPath = new JTextField(); - browseSumatraReader = new JButton(Localization.lang("Browse")); - - JLabel commandDescription = new JLabel(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); - - ButtonGroup consoleOptions = new ButtonGroup(); - consoleOptions.add(defaultConsole); - consoleOptions.add(executeConsole); - - ButtonGroup readerOptions = new ButtonGroup(); - readerOptions.add(adobeAcrobatReader); - - JPanel pdfOptionPanel = new JPanel(new GridBagLayout()); - GridBagConstraints pdfLayoutConstrains = new GridBagConstraints(); - - JPanel consoleOptionPanel = new JPanel(new GridBagLayout()); - GridBagConstraints layoutConstraints = new GridBagConstraints(); - - defaultConsole.addActionListener(e -> updateExecuteConsoleButtonAndFieldEnabledState()); - executeConsole.addActionListener(e -> updateExecuteConsoleButtonAndFieldEnabledState()); - browseButton.addActionListener(e -> showConsoleChooser()); - - browseAdobeAcrobatReader.addActionListener(e -> showAdobeChooser()); - - layoutConstraints.fill = GridBagConstraints.HORIZONTAL; - - pdfLayoutConstrains.fill = GridBagConstraints.HORIZONTAL; - - layoutConstraints.gridx = 0; - layoutConstraints.gridy = 0; - layoutConstraints.insets = new Insets(0, 0, 6, 0); - consoleOptionPanel.add(defaultConsole, layoutConstraints); - - layoutConstraints.gridy = 1; - consoleOptionPanel.add(executeConsole, layoutConstraints); - - layoutConstraints.gridx = 1; - consoleOptionPanel.add(consoleCommand, layoutConstraints); - - layoutConstraints.gridx = 2; - layoutConstraints.insets = new Insets(0, 4, 6, 0); - consoleOptionPanel.add(browseButton, layoutConstraints); - - layoutConstraints.gridx = 1; - layoutConstraints.gridy = 2; - consoleOptionPanel.add(commandDescription, layoutConstraints); - - pdfLayoutConstrains.gridx = 0; - pdfLayoutConstrains.gridy = 0; - pdfLayoutConstrains.insets = new Insets(0, 0, 6, 0); - pdfOptionPanel.add(adobeAcrobatReader, pdfLayoutConstrains); - - pdfLayoutConstrains.gridx = 1; - pdfOptionPanel.add(adobeAcrobatReaderPath, pdfLayoutConstrains); - - pdfLayoutConstrains.gridx = 2; - pdfOptionPanel.add(browseAdobeAcrobatReader, pdfLayoutConstrains); + Button editFileTypes = new Button(Localization.lang("Manage external file types")); + editFileTypes.setFont(FontSize.smallFont); + citeCommand = new TextField(); + editFileTypes.setOnAction(e->ExternalFileTypeEditor.getAction()); + defaultConsole = new RadioButton(Localization.lang("Use default terminal emulator")); + defaultConsole.setFont(FontSize.smallFont); + executeConsole = new RadioButton(Localization.lang("Execute command") + ":"); + executeConsole.setFont(FontSize.smallFont); + consoleCommand = new TextField(); + browseButton = new Button(Localization.lang("Browse")); + browseButton.setFont(FontSize.smallFont); + adobeAcrobatReader = new RadioButton(Localization.lang("Adobe Acrobat Reader")); + adobeAcrobatReader.setFont(FontSize.smallFont); + adobeAcrobatReaderPath = new TextField(); + Button browseAdobeAcrobatReader = new Button(Localization.lang("Browse")); + browseAdobeAcrobatReader.setFont(FontSize.smallFont); + sumatraReader = new RadioButton(Localization.lang("Sumatra Reader")); + sumatraReader.setFont(FontSize.smallFont); + sumatraReaderPath = new TextField(); + Button browseSumatraReader = new Button(Localization.lang("Browse")); + browseSumatraReader.setFont(FontSize.smallFont); + + Label commandDescription = new Label(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); + commandDescription.setFont(FontSize.smallFont); + defaultConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); + executeConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); + browseButton.setOnAction(e -> showConsoleChooser()); + + browseAdobeAcrobatReader.setOnAction(e -> showAdobeChooser()); + + GridPane consoleOptionPanel = new GridPane(); + consoleOptionPanel.add(defaultConsole, 1, 1); + consoleOptionPanel.add(executeConsole, 1, 2); + consoleOptionPanel.add(consoleCommand, 2, 2); + consoleOptionPanel.add(browseButton, 3, 2); + consoleOptionPanel.add(commandDescription, 2, 3); + + GridPane pdfOptionPanel = new GridPane(); + pdfOptionPanel.add(adobeAcrobatReader, 1, 1); + pdfOptionPanel.add(adobeAcrobatReaderPath, 2, 1); + pdfOptionPanel.add(browseAdobeAcrobatReader, 3, 1); if (OS.WINDOWS) { - readerOptions.add(sumatraReader); - browseSumatraReader.addActionListener(e -> showSumatraChooser()); - pdfLayoutConstrains.gridy = 1; - pdfLayoutConstrains.gridx = 0; - pdfOptionPanel.add(sumatraReader, pdfLayoutConstrains); - - pdfLayoutConstrains.gridx = 1; - pdfOptionPanel.add(sumatraReaderPath, pdfLayoutConstrains); + browseSumatraReader.setOnAction(e -> showSumatraChooser()); + pdfOptionPanel.add(sumatraReader, 1, 2); + pdfOptionPanel.add(sumatraReaderPath, 2, 2); + pdfOptionPanel.add(browseSumatraReader, 3, 2); + } - pdfLayoutConstrains.gridx = 2; - pdfOptionPanel.add(browseSumatraReader, pdfLayoutConstrains); + Label sendingOfEmails = new Label(Localization.lang("Sending of emails") + " ----------------------------"); + sendingOfEmails.setFont(FontSize.bigFont); + builder.add(sendingOfEmails, 1, 1); + Label subject = new Label(Localization.lang("Subject for sending an email with references").concat(":")); + subject.setFont(FontSize.smallFont); + builder.add(subject, 1, 2); + emailSubject = new TextField(); + builder.add(emailSubject, 2, 2); + openFoldersOfAttachedFiles = new CheckBox(Localization.lang("Automatically open folders of attached files")); + openFoldersOfAttachedFiles.setFont(FontSize.smallFont); + builder.add(openFoldersOfAttachedFiles, 1, 3); + + builder.add(new Label(""), 1, 4); + Label externalPrograms = new Label(Localization.lang("External programs") + " ----------------------------"); + externalPrograms.setFont(FontSize.bigFont); + builder.add(externalPrograms, 1, 5); + + GridPane butpan = new GridPane(); + int index = 0; + for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()) { + addSettingsButton(pushToApplication, butpan, index); + index++; } - FormLayout layout = new FormLayout( - "1dlu, 8dlu, left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", ""); + builder.add(butpan, 1, 6); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); + Label citeCommandLabel = new Label(Localization.lang("Cite command") + ':'); + citeCommandLabel.setFont(FontSize.smallFont); + builder.add(citeCommandLabel, 1, 7); + builder.add(citeCommand, 2, 7); + builder.add(editFileTypes, 1, 8); + builder.add(new Label(""), 1, 9); + Label openConsole = new Label(Localization.lang("Open console") + " ---------------------------------"); + openConsole.setFont(FontSize.bigFont); + builder.add(openConsole, 1, 10); - builder.appendSeparator(Localization.lang("Sending of emails")); - builder.append(new JPanel()); - JLabel lab = new JLabel(Localization.lang("Subject for sending an email with references").concat(":")); - builder.append(lab); - emailSubject = new JTextField(25); - builder.append(emailSubject); - builder.nextLine(); - builder.append(new JPanel()); - openFoldersOfAttachedFiles = new JCheckBox(Localization.lang("Automatically open folders of attached files")); - builder.append(openFoldersOfAttachedFiles); - builder.nextLine(); + builder.add(consoleOptionPanel, 1, 11); + builder.add(new Label(""), 1, 12); - builder.appendSeparator(Localization.lang("External programs")); - builder.nextLine(); + Label openPdf = new Label(Localization.lang("Open PDF") + " -------------------------------------"); + openPdf.setFont(FontSize.bigFont); + builder.add(openPdf, 1, 12); - JPanel butpan = new JPanel(); - butpan.setLayout(new GridLayout(3, 3)); - for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()) { - addSettingsButton(pushToApplication, butpan); - } - builder.append(new JPanel()); - builder.append(butpan, 3); - - builder.nextLine(); - lab = new JLabel(Localization.lang("Cite command") + ':'); - JPanel pan = new JPanel(); - builder.append(pan); - builder.append(lab); - builder.append(citeCommand); - - builder.nextLine(); - builder.append(pan); - builder.append(editFileTypes); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Open console")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(consoleOptionPanel); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Open PDF")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(pdfOptionPanel); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + builder.add(pdfOptionPanel, 1, 13); + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + } + public Node getBuilder() { + return builder; } - private void addSettingsButton(final PushToApplication application, JPanel panel) { + private void addSettingsButton(final PushToApplication application, GridPane panel, int index) { PushToApplicationSettings settings = PushToApplications.getSettings(application); - JButton button = new JButton(Localization.lang("Settings for %0", application.getApplicationName()), application.getIcon().getIcon()); - button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); - panel.add(button); + Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); + button.setFont(FontSize.smallFont); + button.setPrefSize(150, 20); + button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings, index)); + if (index % 2 == 0) { + panel.add(button, 1, index / 2 + 1); + } else { + panel.add(button, 2, index / 2 + 1); + } } @Override @@ -257,8 +214,8 @@ public String getTabName() { } private void updateExecuteConsoleButtonAndFieldEnabledState() { - browseButton.setEnabled(executeConsole.isSelected()); - consoleCommand.setEnabled(executeConsole.isSelected()); + browseButton.setDisable(!executeConsole.isSelected()); + consoleCommand.setDisable(!executeConsole.isSelected()); } private void showConsoleChooser() { diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index 7bee312c92e..0e1ede1e543 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -1,21 +1,19 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ItemListener; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.gui.DialogService; import org.jabref.gui.help.HelpAction; @@ -28,156 +26,145 @@ import org.jabref.model.metadata.FileDirectoryPreferences; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * Preferences tab for file options. These options were moved out from GeneralTab to * resolve the space issue. */ -class FileTab extends JPanel implements PrefsTab { +class FileTab extends Pane implements PrefsTab { private final DialogService dialogService; private final JabRefPreferences prefs; - private final JCheckBox backup; - private final JCheckBox localAutoSave; - private final JCheckBox openLast; - private final JComboBox newlineSeparator; - private final JCheckBox reformatFileOnSaveAndExport; - private final JRadioButton resolveStringsStandard; - private final JRadioButton resolveStringsAll; - private final JTextField nonWrappableFields; - private final JTextField doNotResolveStringsFor; - - private final JTextField fileDir; - private final JCheckBox bibLocAsPrimaryDir; - private final JCheckBox runAutoFileSearch; - private final JCheckBox allowFileAutoOpenBrowse; - private final JRadioButton useRegExpComboBox; - private final JRadioButton matchExactKeyOnly = new JRadioButton( + private final CheckBox backup; + private final CheckBox localAutoSave; + private final CheckBox openLast; + private final ComboBox newlineSeparator; + private final CheckBox reformatFileOnSaveAndExport; + private final RadioButton resolveStringsStandard; + private final RadioButton resolveStringsAll; + private final TextField nonWrappableFields; + private final TextField doNotResolveStringsFor; + private final GridPane builder = new GridPane(); + + private final TextField fileDir; + private final CheckBox bibLocAsPrimaryDir; + private final CheckBox runAutoFileSearch; + private final CheckBox allowFileAutoOpenBrowse; + private final RadioButton useRegExpComboBox; + private final RadioButton matchExactKeyOnly = new RadioButton( Localization.lang("Autolink only files that match the BibTeX key")); - private final JRadioButton matchStartsWithKey = new JRadioButton( + private final RadioButton matchStartsWithKey = new RadioButton( Localization.lang("Autolink files with names starting with the BibTeX key")); - private final JTextField regExpTextField; + private final TextField regExpTextField; public FileTab(DialogService dialogService, JabRefPreferences prefs) { this.dialogService = dialogService; this.prefs = prefs; - - fileDir = new JTextField(25); - bibLocAsPrimaryDir = new JCheckBox(Localization.lang("Use the BIB file location as primary file directory")); - bibLocAsPrimaryDir.setToolTipText(Localization.lang("When downloading files, or moving linked files to the " + fileDir = new TextField(); + bibLocAsPrimaryDir = new CheckBox(Localization.lang("Use the BIB file location as primary file directory")); + bibLocAsPrimaryDir.setFont(FontSize.smallFont); + bibLocAsPrimaryDir.setAccessibleText(Localization.lang("When downloading files, or moving linked files to the " + "file directory, prefer the BIB file location rather than the file directory set above")); - runAutoFileSearch = new JCheckBox( + runAutoFileSearch = new CheckBox( Localization.lang("When opening file link, search for matching file if no link is defined")); - allowFileAutoOpenBrowse = new JCheckBox( + runAutoFileSearch.setFont(FontSize.smallFont); + allowFileAutoOpenBrowse = new CheckBox( Localization.lang("Automatically open browse dialog when creating new file link")); - regExpTextField = new JTextField(25); - useRegExpComboBox = new JRadioButton(Localization.lang("Use regular expression search")); - ItemListener regExpListener = e -> regExpTextField.setEditable(useRegExpComboBox.isSelected()); - useRegExpComboBox.addItemListener(regExpListener); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(matchExactKeyOnly); - buttonGroup.add(matchStartsWithKey); - buttonGroup.add(useRegExpComboBox); - - openLast = new JCheckBox(Localization.lang("Open last edited libraries at startup")); - backup = new JCheckBox(Localization.lang("Backup old file when saving")); - localAutoSave = new JCheckBox(Localization.lang("Autosave local libraries")); - resolveStringsAll = new JRadioButton(Localization.lang("Resolve strings for all fields except") + ":"); - resolveStringsStandard = new JRadioButton(Localization.lang("Resolve strings for standard BibTeX fields only")); - ButtonGroup bg = new ButtonGroup(); - bg.add(resolveStringsAll); - bg.add(resolveStringsStandard); + allowFileAutoOpenBrowse.setFont(FontSize.smallFont); + regExpTextField = new TextField(); + useRegExpComboBox = new RadioButton(Localization.lang("Use regular expression search")); + useRegExpComboBox.setFont(FontSize.smallFont); + useRegExpComboBox.setOnAction(e -> regExpTextField.setEditable(useRegExpComboBox.isSelected())); + + openLast = new CheckBox(Localization.lang("Open last edited libraries at startup")); + openLast.setFont(FontSize.smallFont); + backup = new CheckBox(Localization.lang("Backup old file when saving")); + backup.setFont(FontSize.smallFont); + localAutoSave = new CheckBox(Localization.lang("Autosave local libraries")); + localAutoSave.setFont(FontSize.smallFont); + resolveStringsAll = new RadioButton(Localization.lang("Resolve strings for all fields except") + ":"); + resolveStringsAll.setFont(FontSize.smallFont); + resolveStringsStandard = new RadioButton(Localization.lang("Resolve strings for standard BibTeX fields only")); + resolveStringsStandard.setFont(FontSize.smallFont); // This is sort of a quick hack - newlineSeparator = new JComboBox<>(new String[] {"CR", "CR/LF", "LF"}); - - reformatFileOnSaveAndExport = new JCheckBox(Localization.lang("Always reformat BIB file on save and export")); - - nonWrappableFields = new JTextField(25); - doNotResolveStringsFor = new JTextField(30); - - FormLayout layout = new FormLayout("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", ""); // left:pref, 4dlu, fill:pref - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - builder.appendSeparator(Localization.lang("General")); - builder.nextLine(); - builder.append(openLast, 3); - builder.nextLine(); - builder.append(backup, 3); - builder.nextLine(); - - JLabel label = new JLabel(Localization.lang("Do not wrap the following fields when saving") + ":"); - builder.append(label); - builder.append(nonWrappableFields); - builder.nextLine(); - builder.append(resolveStringsStandard, 3); - builder.nextLine(); - builder.append(resolveStringsAll); - builder.append(doNotResolveStringsFor); - builder.nextLine(); - - JLabel lab = new JLabel(Localization.lang("Newline separator") + ":"); - builder.append(lab); - builder.append(newlineSeparator); - builder.nextLine(); - - builder.append(reformatFileOnSaveAndExport, 3); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("External file links")); - builder.nextLine(); - lab = new JLabel(Localization.lang("Main file directory") + ':'); - builder.append(lab); - builder.append(fileDir); - - JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(e -> { - + newlineSeparator = new ComboBox<>(FXCollections.observableArrayList("CR", "CR/LF", "LF")); + + reformatFileOnSaveAndExport = new CheckBox(Localization.lang("Always reformat BIB file on save and export")); + reformatFileOnSaveAndExport.setFont(FontSize.smallFont); + + nonWrappableFields = new TextField(); + doNotResolveStringsFor = new TextField(); + nonWrappableFields.setPrefSize(80, 25); + doNotResolveStringsFor.setPrefSize(80, 25); + builder.setPrefSize(800, 600); + + Label general = new Label(Localization.lang("General") + " ----------------------------------------------"); + general.setFont(FontSize.bigFont); + builder.add(general, 1, 1); + builder.add(openLast, 1, 2); + builder.add(backup, 1, 3); + Label label = new Label(Localization.lang("Do not wrap the following fields when saving") + ":"); + label.setFont(FontSize.smallFont); + builder.add(label, 1, 4); + builder.add(nonWrappableFields, 2, 4); + builder.add(resolveStringsStandard, 1, 5); + builder.add(resolveStringsAll, 1, 6); + builder.add(doNotResolveStringsFor, 2, 6); + + Label newlineSeparatorLabel = new Label(Localization.lang("Newline separator") + ":"); + newlineSeparatorLabel.setFont(FontSize.smallFont); + builder.add(newlineSeparatorLabel, 1, 7); + builder.add(newlineSeparator, 2, 7); + builder.add(reformatFileOnSaveAndExport, 1, 8); + Label invisible = new Label(""); + builder.add(invisible, 1, 9); + + Label externalFileLinks = new Label(Localization.lang("External file links") + " ------------------------------------"); + externalFileLinks.setFont(FontSize.bigFont); + builder.add(externalFileLinks, 1, 11); + + label = new Label(Localization.lang("Main file directory") + ':'); + label.setFont(FontSize.smallFont); + builder.add(label, 1, 12); + builder.add(fileDir, 2, 12); + + Button browse = new Button(Localization.lang("Browse")); + browse.setPrefSize(80, 20); + browse.setFont(FontSize.smallFont); + browse.setOnAction(e -> { DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(Paths.get(fileDir.getText())).build(); - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) .ifPresent(f -> fileDir.setText(f.toString())); - }); - builder.append(browse); - - builder.nextLine(); - builder.append(bibLocAsPrimaryDir, 3); - builder.nextLine(); - builder.append(matchStartsWithKey, 3); - builder.nextLine(); - builder.append(matchExactKeyOnly, 3); - builder.nextLine(); - builder.append(useRegExpComboBox); - builder.append(regExpTextField); - - builder.append(new HelpAction(Localization.lang("Help on regular expression search"), - HelpFile.REGEX_SEARCH) - .getHelpButton()); - builder.nextLine(); - builder.append(runAutoFileSearch, 3); - builder.nextLine(); - builder.append(allowFileAutoOpenBrowse); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Autosave")); - builder.append(localAutoSave, 1); - JButton help = new HelpAction(HelpFile.AUTOSAVE).getHelpButton(); - help.setPreferredSize(new Dimension(24, 24)); - JPanel hPan = new JPanel(); - hPan.setLayout(new BorderLayout()); - hPan.add(help, BorderLayout.EAST); - builder.append(hPan); - builder.nextLine(); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + builder.add(browse, 3, 12); + builder.add(bibLocAsPrimaryDir, 1, 13); + builder.add(matchStartsWithKey, 1, 14); + builder.add(matchExactKeyOnly, 1, 15); + builder.add(useRegExpComboBox, 1, 16); + builder.add(regExpTextField, 2, 16); + + Button help = new Button("?"); + help.setFont(FontSize.smallFont); + help.setOnAction(event -> new HelpAction(Localization.lang("Help on regular expression search"), + HelpFile.REGEX_SEARCH).getHelpButton().doClick()); + + builder.add(help, 3, 16); + builder.add(runAutoFileSearch, 1, 17); + builder.add(allowFileAutoOpenBrowse, 1, 18); + + Label invisible1 = new Label(""); + builder.add(invisible1, 1, 19); + + Label autosave = new Label(Localization.lang("Autosave") + " ---------------------------------------------"); + autosave.setFont(FontSize.bigFont); + builder.add(autosave, 1, 20); + builder.add(localAutoSave, 1, 21); + Button help1 = new Button("?"); + help1.setFont(FontSize.smallFont); + help1.setOnAction(event -> new HelpAction(HelpFile.AUTOSAVE).getHelpButton().doClick()); + builder.add(help1, 2, 21); } @Override @@ -200,12 +187,12 @@ public void setValues() { String newline = prefs.get(JabRefPreferences.NEWLINE); if ("\r".equals(newline)) { - newlineSeparator.setSelectedIndex(0); + newlineSeparator.setValue("CR"); } else if ("\n".equals(newline)) { - newlineSeparator.setSelectedIndex(2); + newlineSeparator.setValue("LF"); } else { // fallback: windows standard - newlineSeparator.setSelectedIndex(1); + newlineSeparator.setValue("CR/LF"); } reformatFileOnSaveAndExport.setSelected(prefs.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT)); @@ -217,6 +204,10 @@ public void setValues() { localAutoSave.setSelected(prefs.getBoolean(JabRefPreferences.LOCAL_AUTO_SAVE)); } + public Node getBuilder() { + return builder; + } + @Override public void storeSettings() { prefs.put(FieldName.FILE + FileDirectoryPreferences.DIR_SUFFIX, fileDir.getText()); @@ -230,11 +221,11 @@ public void storeSettings() { } String newline; - switch (newlineSeparator.getSelectedIndex()) { - case 0: + switch (newlineSeparator.getPromptText()) { + case "CR": newline = "\r"; break; - case 2: + case "LF": newline = "\n"; break; default: diff --git a/src/main/java/org/jabref/gui/preftabs/FontSize.java b/src/main/java/org/jabref/gui/preftabs/FontSize.java new file mode 100644 index 00000000000..3c6e45c5046 --- /dev/null +++ b/src/main/java/org/jabref/gui/preftabs/FontSize.java @@ -0,0 +1,11 @@ +package org.jabref.gui.preftabs; + +import javafx.scene.text.Font; + +/** + * This class is used to save the font size of all the controls in the preferences dialog + */ +public class FontSize { + public static Font bigFont = new Font(14); + public static Font smallFont = new Font(10); +} diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 705b35a7de5..f7d0653a616 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -1,20 +1,19 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Component; import java.nio.charset.Charset; import java.time.format.DateTimeFormatter; -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JTextField; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.shape.Line; import org.jabref.Globals; import org.jabref.gui.DialogService; @@ -27,136 +26,129 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - import static org.jabref.logic.l10n.Languages.LANGUAGES; -class GeneralTab extends JPanel implements PrefsTab { - - private final JCheckBox useOwner; - private final JCheckBox overwriteOwner; - private final JCheckBox enforceLegalKeys; - private final JCheckBox shouldCollectTelemetry; - private final JCheckBox confirmDelete; - private final JCheckBox memoryStick; - private final JCheckBox inspectionWarnDupli; - private final JCheckBox useTimeStamp; - private final JCheckBox updateTimeStamp; - private final JCheckBox overwriteTimeStamp; - private final JTextField defOwnerField; - - private final JTextField timeStampFormat; - private final JTextField timeStampField; +class GeneralTab extends Pane implements PrefsTab { + + private final CheckBox useOwner; + private final CheckBox overwriteOwner; + private final CheckBox enforceLegalKeys; + private final CheckBox shouldCollectTelemetry; + private final CheckBox confirmDelete; + private final CheckBox memoryStick; + private final CheckBox inspectionWarnDupli; + private final CheckBox useTimeStamp; + private final CheckBox updateTimeStamp; + private final CheckBox overwriteTimeStamp; + private final TextField defOwnerField; + private final GridPane builder = new GridPane(); + + private final TextField timeStampFormat; + private final TextField timeStampField; private final JabRefPreferences prefs; - private final JComboBox language = new JComboBox<>(LANGUAGES.keySet().toArray(new String[LANGUAGES.keySet().size()])); - private final JComboBox encodings; - private final JComboBox biblatexMode; - private final DialogService dialogService; - - public class DefaultBibModeRenderer extends DefaultListCellRenderer { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, - boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - setText(((BibDatabaseMode) value).getFormattedName()); - return this; - } - } + private final ObservableList options = FXCollections.observableArrayList(LANGUAGES.keySet().toArray(new String[LANGUAGES.keySet().size()])); + private final ComboBox language = new ComboBox<>(options); + private final ComboBox encodings; + private final ComboBox biblatexMode; + private final DialogService dialogService; public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { this.prefs = prefs; this.dialogService = dialogService; - setLayout(new BorderLayout()); - - biblatexMode = new JComboBox<>(BibDatabaseMode.values()); - biblatexMode.setRenderer(new DefaultBibModeRenderer()); - - memoryStick = new JCheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); - useOwner = new JCheckBox(Localization.lang("Mark new entries with owner name") + ':'); - updateTimeStamp = new JCheckBox(Localization.lang("Update timestamp on modification")); - useTimeStamp = new JCheckBox(Localization.lang("Mark new entries with addition date") + ". " + biblatexMode = new ComboBox<>(FXCollections.observableArrayList(BibDatabaseMode.values())); + + memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); + memoryStick.setFont(FontSize.smallFont); + useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':'); + useOwner.setFont(FontSize.smallFont); + updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification")); + updateTimeStamp.setFont(FontSize.smallFont); + useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); - useTimeStamp.addChangeListener(e -> updateTimeStamp.setEnabled(useTimeStamp.isSelected())); - overwriteOwner = new JCheckBox(Localization.lang("Overwrite")); - overwriteTimeStamp = new JCheckBox(Localization.lang("Overwrite")); - overwriteOwner.setToolTipText(Localization.lang("If a pasted or imported entry already has " - + "the field set, overwrite.")); - overwriteTimeStamp.setToolTipText(Localization.lang("If a pasted or imported entry already has " - + "the field set, overwrite.")); - enforceLegalKeys = new JCheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); - confirmDelete = new JCheckBox(Localization.lang("Show confirmation dialog when deleting entries")); - - defOwnerField = new JTextField(); - timeStampFormat = new JTextField(); - timeStampField = new JTextField(); - inspectionWarnDupli = new JCheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window")); - - shouldCollectTelemetry = new JCheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef.")); - - encodings = new JComboBox<>(); - encodings.setModel(new DefaultComboBoxModel<>(Encodings.ENCODINGS)); - - FormLayout layout = new FormLayout( - "8dlu, 1dlu, left:pref:grow, 4dlu, fill:pref, 4dlu, fill:pref, 4dlu, left:pref, 1dlu, left:pref, 4dlu, left:pref", - ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - builder.appendSeparator(Localization.lang("General")); - builder.nextLine(); - builder.append(inspectionWarnDupli, 13); - builder.nextLine(); - builder.append(confirmDelete, 13); - builder.nextLine(); - builder.append(enforceLegalKeys, 13); - builder.nextLine(); - builder.append(memoryStick, 13); + useTimeStamp.setFont(FontSize.smallFont); + if (!useTimeStamp.isSelected()) { + updateTimeStamp.setDisable(true); + } + useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); + overwriteOwner = new CheckBox(Localization.lang("Overwrite")); + overwriteOwner.setFont(FontSize.smallFont); + overwriteTimeStamp = new CheckBox(Localization.lang("If a pasted or imported entry already has the field set, overwrite.")); + overwriteTimeStamp.setFont(FontSize.smallFont); + enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); + enforceLegalKeys.setFont(FontSize.smallFont); + confirmDelete = new CheckBox(Localization.lang("Show confirmation dialog when deleting entries")); + confirmDelete.setFont(FontSize.smallFont); + defOwnerField = new TextField(); + defOwnerField.setPrefSize(80, 20); + timeStampFormat = new TextField(); + timeStampFormat.setPrefSize(80, 20); + timeStampField = new TextField(); + timeStampField.setPrefSize(80, 20); + inspectionWarnDupli = new CheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window")); + inspectionWarnDupli.setFont(FontSize.smallFont); + shouldCollectTelemetry = new CheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef.")); + shouldCollectTelemetry.setFont(FontSize.smallFont); + encodings = new ComboBox<>(FXCollections.observableArrayList(Encodings.ENCODINGS)); + + Label general = new Label(Localization.lang("General") + " -----------------------------------------------"); + general.setFont(FontSize.bigFont); + builder.add(general, 1, 1); + builder.add(new Line(), 1, 2); + builder.add(inspectionWarnDupli, 1, 3); + builder.add(new Line(), 1, 4); + builder.add(confirmDelete, 1, 5); + builder.add(new Line(), 1, 6); + builder.add(enforceLegalKeys, 1, 7); + builder.add(new Line(), 1, 8); + builder.add(memoryStick, 1, 9); // Create a new panel with its own FormLayout for the last items: - builder.append(useOwner, 3); - builder.append(defOwnerField); - builder.append(overwriteOwner); - builder.append(new JPanel(), 3); - - JButton help = new HelpAction(HelpFile.OWNER).getHelpButton(); - builder.append(help); - builder.nextLine(); - - builder.append(useTimeStamp, 3); - builder.append(timeStampFormat); - builder.append(overwriteTimeStamp); - builder.append(Localization.lang("Field name") + ':'); - builder.append(timeStampField); - - help = new HelpAction(HelpFile.TIMESTAMP).getHelpButton(); - builder.append(help); - builder.nextLine(); - - builder.append(new JPanel()); - builder.append(updateTimeStamp, 11); - builder.nextLine(); - - builder.append(shouldCollectTelemetry, 13); - builder.nextLine(); - JLabel lab; - lab = new JLabel(Localization.lang("Language") + ':'); - builder.append(lab, 3); - builder.append(language); - builder.nextLine(); - lab = new JLabel(Localization.lang("Default encoding") + ':'); - builder.append(lab, 3); - builder.append(encodings); - - builder.nextLine(); - builder.appendSeparator(Localization.lang("Default bibliography mode")); - builder.append(new JPanel()); - builder.append(biblatexMode); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + builder.add(useOwner, 1, 10); + builder.add(defOwnerField, 2, 10); + builder.add(overwriteOwner, 3, 10); + + Button help = new Button("?"); + help.setFont(FontSize.smallFont); + help.setPrefSize(10, 10); + help.setOnAction(event -> new HelpAction(HelpFile.OWNER).getHelpButton().doClick()); + builder.add(help, 4, 10); + + builder.add(useTimeStamp, 1, 13); + builder.add(timeStampFormat, 2, 13); + builder.add(overwriteTimeStamp, 3, 13); + Label fieldName = new Label(Localization.lang("Field name") + ':'); + fieldName.setFont(FontSize.smallFont); + builder.add(fieldName, 4, 13); + builder.add(timeStampField, 5, 13); + + Button help1 = new Button("?"); + help1.setFont(FontSize.smallFont); + help1.setOnAction(event -> new HelpAction(HelpFile.TIMESTAMP).getHelpButton().doClick()); + builder.add(help1, 6, 13); + + builder.add(updateTimeStamp, 1, 14); + builder.add(new Line(), 1, 15); + + builder.add(shouldCollectTelemetry, 1, 15); + builder.add(new Line(), 1, 16); + Label languageLabel = new Label(Localization.lang("Language") + ':'); + languageLabel.setFont(FontSize.smallFont); + builder.add(languageLabel, 1, 17); + builder.add(language, 2, 17); + builder.add(new Line(), 2, 18); + Label defaultEncoding = new Label(Localization.lang("Default encoding") + ':'); + defaultEncoding.setFont(FontSize.smallFont); + builder.add(defaultEncoding, 1, 19); + builder.add(encodings, 2, 19); + Label defaultBibliographyMode = new Label(Localization.lang("Default bibliography mode")); + defaultBibliographyMode.setFont(FontSize.smallFont); + builder.add(defaultBibliographyMode, 1, 20); + builder.add(biblatexMode, 2, 20); + } + public Node getBuilder() { + return builder; } @Override @@ -166,7 +158,7 @@ public void setValues() { useTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP)); overwriteTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP)); updateTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP)); - updateTimeStamp.setEnabled(useTimeStamp.isSelected()); + updateTimeStamp.setSelected(useTimeStamp.isSelected()); enforceLegalKeys.setSelected(prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); shouldCollectTelemetry.setSelected(prefs.shouldCollectTelemetry()); memoryStick.setSelected(prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE)); @@ -176,13 +168,13 @@ public void setValues() { timeStampField.setText(prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); inspectionWarnDupli.setSelected(prefs.getBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION)); if (Globals.prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE)) { - biblatexMode.setSelectedItem(BibDatabaseMode.BIBLATEX); + biblatexMode.setValue(BibDatabaseMode.BIBLATEX); } else { - biblatexMode.setSelectedItem(BibDatabaseMode.BIBTEX); + biblatexMode.setValue(BibDatabaseMode.BIBTEX); } Charset enc = Globals.prefs.getDefaultEncoding(); - encodings.setSelectedItem(enc); + encodings.setValue(enc); String oldLan = prefs.get(JabRefPreferences.LANGUAGE); @@ -190,7 +182,7 @@ public void setValues() { int ilk = 0; for (String lan : LANGUAGES.values()) { if (lan.equals(oldLan)) { - language.setSelectedIndex(ilk); + language.setVisibleRowCount(ilk); } ilk++; } @@ -221,12 +213,12 @@ public void storeSettings() { prefs.put(JabRefPreferences.TIME_STAMP_FIELD, timeStampField.getText().trim()); // Update name of the time stamp field based on preferences InternalBibtexFields.updateTimeStampField(Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); - prefs.setDefaultEncoding((Charset) encodings.getSelectedItem()); - prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getSelectedItem() == BibDatabaseMode.BIBLATEX); + prefs.setDefaultEncoding(encodings.getValue()); + prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getValue().equals(BibDatabaseMode.BIBLATEX)); - if (!LANGUAGES.get(language.getSelectedItem()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { - prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getSelectedItem())); - Localization.setLanguage(LANGUAGES.get(language.getSelectedItem())); + if (!LANGUAGES.get(language.getValue()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { + prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getValue())); + Localization.setLanguage(LANGUAGES.get(language.getValue())); // Update any defaults that might be language dependent: Globals.prefs.setLanguageDependentDefaultValues(); // Warn about restart needed: diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index aa071674220..38af586d31c 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -1,108 +1,73 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.gui.groups.GroupViewMode; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +class GroupsPrefsTab extends Pane implements PrefsTab { -class GroupsPrefsTab extends JPanel implements PrefsTab { - - private final JCheckBox hideNonHits = new JCheckBox(Localization.lang("Hide non-hits")); - private final JCheckBox grayOut = new JCheckBox(Localization.lang("Gray out non-hits")); - private final JCheckBox autoAssignGroup = new JCheckBox(Localization.lang("Automatically assign new entry to selected groups")); - private final JRadioButton multiSelectionModeIntersection = new JRadioButton(Localization.lang("Intersection")); - private final JRadioButton multiSelectionModeUnion = new JRadioButton(Localization.lang("Union")); - - private final JTextField groupingField = new JTextField(20); - private final JTextField keywordSeparator = new JTextField(2); + private final CheckBox hideNonHits = new CheckBox(Localization.lang("Hide non-hits")); + private final CheckBox grayOut = new CheckBox(Localization.lang("Gray out non-hits")); + private final CheckBox autoAssignGroup = new CheckBox(Localization.lang("Automatically assign new entry to selected groups")); + private final RadioButton multiSelectionModeIntersection = new RadioButton(Localization.lang("Intersection")); + private final RadioButton multiSelectionModeUnion = new RadioButton(Localization.lang("Union")); + private final TextField groupingField = new TextField(); + private final TextField keywordSeparator = new TextField(); + private final GridPane builder = new GridPane(); private final JabRefPreferences prefs; public GroupsPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - keywordSeparator.addFocusListener(new FocusListener() { - + keywordSeparator.setOnAction(new EventHandler() { @Override - public void focusGained(FocusEvent e) { + public void handle(ActionEvent event) { keywordSeparator.selectAll(); } - - @Override - public void focusLost(FocusEvent e) { - // deselection is automatic - } }); - ButtonGroup hideMode = new ButtonGroup(); - hideMode.add(grayOut); - hideMode.add(hideNonHits); - - ButtonGroup multiSelectionMode = new ButtonGroup(); - multiSelectionMode.add(multiSelectionModeIntersection); - multiSelectionMode.add(multiSelectionModeUnion); - multiSelectionModeIntersection.setToolTipText(Localization.lang("Display only entries belonging to all selected groups.")); - multiSelectionModeUnion.setToolTipText(Localization.lang("Display all entries belonging to one or more of the selected groups.")); - - FormLayout layout = new FormLayout("9dlu, pref", //500px", - "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p"); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.appendSeparator(Localization.lang("View")); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(hideNonHits); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(grayOut); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(multiSelectionModeIntersection); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(multiSelectionModeUnion); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(autoAssignGroup); - builder.nextLine(); - builder.nextLine(); - builder.appendSeparator(Localization.lang("Dynamic groups")); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - // build subcomponent - FormLayout layout2 = new FormLayout("left:pref, 2dlu, left:pref", "p, 3dlu, p"); - DefaultFormBuilder builder2 = new DefaultFormBuilder(layout2); - builder2.append(new JLabel(Localization.lang("Default grouping field") + ":")); - builder2.append(groupingField); - builder2.nextLine(); - builder2.nextLine(); - builder2.append(new JLabel(Localization.lang("When adding/removing keywords, separate them by") + ":")); - builder2.append(keywordSeparator); - builder.append(builder2.getPanel()); - - setLayout(new BorderLayout()); - JPanel panel = builder.getPanel(); - panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(panel, BorderLayout.CENTER); + multiSelectionModeIntersection.setText(Localization.lang("Display only entries belonging to all selected groups.")); + multiSelectionModeIntersection.setFont(FontSize.smallFont); + multiSelectionModeUnion.setText(Localization.lang("Display all entries belonging to one or more of the selected groups.")); + multiSelectionModeUnion.setFont(FontSize.smallFont); + + Label view = new Label(Localization.lang("View") + " ---------------------------------------"); + view.setFont(FontSize.bigFont); + builder.add(view, 1, 1); + builder.add(hideNonHits, 2, 2); + builder.add(grayOut, 2, 3); + builder.add(multiSelectionModeIntersection, 2, 4); + builder.add(multiSelectionModeUnion, 2, 5); + builder.add(autoAssignGroup, 2, 6); + builder.add(new Label(""), 1, 7); + + Label dynamicGroups = new Label(Localization.lang("Dynamic groups") + " --------------------------"); + dynamicGroups.setFont(FontSize.bigFont); + builder.add(dynamicGroups, 1, 8); + + Label defaultGrouping = new Label(Localization.lang("Default grouping field") + ":"); + defaultGrouping.setFont(FontSize.smallFont); + builder.add(defaultGrouping, 1, 9); + builder.add(groupingField, 2, 9); + Label label = new Label(Localization.lang("When adding/removing keywords, separate them by") + ":"); + label.setFont(FontSize.smallFont); + builder.add(label, 1, 10); + builder.add(keywordSeparator, 2, 10); + } + + public Node getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 1aea509991f..a47bf24ce17 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -1,27 +1,23 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Objects; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.logic.l10n.Localization; import org.jabref.pdfimport.ImportDialog; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -public class ImportSettingsTab extends JPanel implements PrefsTab { +public class ImportSettingsTab extends Pane implements PrefsTab { public static final String[] DEFAULT_FILENAMEPATTERNS = new String[] {"[bibtexkey]", "[bibtexkey] - [title]"}; @@ -30,84 +26,70 @@ public class ImportSettingsTab extends JPanel implements PrefsTab { private static final String[] DEFAULT_FILENAMEPATTERNS_DISPLAY = new String[] {"bibtexkey", "bibtexkey - title",}; private final JabRefPreferences prefs; - private final JRadioButton radioButtonXmp; - private final JRadioButton radioButtonPDFcontent; - private final JRadioButton radioButtonNoMeta; - private final JRadioButton radioButtononlyAttachPDF; - private final JCheckBox useDefaultPDFImportStyle; + private final RadioButton radioButtonXmp; + private final RadioButton radioButtonPDFcontent; + private final RadioButton radioButtonNoMeta; + private final RadioButton radioButtononlyAttachPDF; + private final CheckBox useDefaultPDFImportStyle; + private final GridPane builder = new GridPane(); + private final TextField fileNamePattern; + private final ComboBox selectFileNamePattern; - private final JTextField fileNamePattern; - private final JButton selectFileNamePattern; - private final JTextField fileDirPattern; + private final TextField fileDirPattern; public ImportSettingsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - - setLayout(new BorderLayout()); - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu"); - radioButtonNoMeta = new JRadioButton(Localization.lang("Create blank entry linking the PDF")); - radioButtonXmp = new JRadioButton(Localization.lang("Create entry based on XMP-metadata")); - radioButtonPDFcontent = new JRadioButton(Localization.lang("Create entry based on content")); - radioButtononlyAttachPDF = new JRadioButton(Localization.lang("Only attach PDF")); - ButtonGroup bg = new ButtonGroup(); - bg.add(radioButtonNoMeta); - bg.add(radioButtonXmp); - bg.add(radioButtonPDFcontent); - bg.add(radioButtononlyAttachPDF); - - useDefaultPDFImportStyle = new JCheckBox( + radioButtonNoMeta = new RadioButton(Localization.lang("Create blank entry linking the PDF")); + radioButtonNoMeta.setFont(FontSize.smallFont); + radioButtonXmp = new RadioButton(Localization.lang("Create entry based on XMP-metadata")); + radioButtonXmp.setFont(FontSize.smallFont); + radioButtonPDFcontent = new RadioButton(Localization.lang("Create entry based on content")); + radioButtonPDFcontent.setFont(FontSize.smallFont); + radioButtononlyAttachPDF = new RadioButton(Localization.lang("Only attach PDF")); + radioButtononlyAttachPDF.setFont(FontSize.smallFont); + + useDefaultPDFImportStyle = new CheckBox( Localization.lang("Always use this PDF import style (and do not ask for each import)")); + useDefaultPDFImportStyle.setFont(FontSize.smallFont); + + fileNamePattern = new TextField(); + fileDirPattern = new TextField(); + selectFileNamePattern = new ComboBox<>(); + selectFileNamePattern.getItems().addAll(FXCollections.observableArrayList(DEFAULT_FILENAMEPATTERNS_DISPLAY)); + selectFileNamePattern.setValue(Localization.lang("Choose pattern")); + selectFileNamePattern.setOnAction(e -> { + fileNamePattern.setText(selectFileNamePattern.getValue()); + }); + + Label defaultImportStyle = new Label(Localization.lang("Default import style for drag and drop of PDFs")); + defaultImportStyle.setFont(FontSize.bigFont); + builder.add(defaultImportStyle, 1, 1); + builder.add(new Separator(), 2, 1); + builder.add(radioButtonNoMeta, 2, 2); + builder.add(radioButtonXmp, 2, 3); + builder.add(radioButtonPDFcontent, 2, 4); + builder.add(radioButtononlyAttachPDF, 2, 5); + builder.add(useDefaultPDFImportStyle, 2, 6); + builder.add(new Label(""), 1, 7); + + Label defaultPdfFileLinkAction = new Label(Localization.lang("Default PDF file link action") + " ------------------------"); + defaultPdfFileLinkAction.setFont(FontSize.bigFont); + builder.add(defaultPdfFileLinkAction, 1, 8); + Label filenameFormatPattern = new Label(Localization.lang("Filename format pattern").concat(":")); + filenameFormatPattern.setFont(FontSize.smallFont); + builder.add(filenameFormatPattern, 1, 9); + builder.add(fileNamePattern, 2, 9); + builder.add(selectFileNamePattern, 3, 9); + + Label lbfileDirPattern = new Label(Localization.lang("File directory pattern").concat(":")); + lbfileDirPattern.setFont(FontSize.smallFont); + builder.add(lbfileDirPattern, 1, 10); + builder.add(fileDirPattern, 2, 10); + } - fileNamePattern = new JTextField(50); - fileDirPattern = new JTextField(50); - selectFileNamePattern = new JButton(Localization.lang("Choose pattern")); - selectFileNamePattern.addActionListener(e -> openFilePatternMenu()); - - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Default import style for drag and drop of PDFs")); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonNoMeta); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonXmp); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonPDFcontent); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtononlyAttachPDF); - builder.nextLine(); - builder.append(pan); - builder.append(useDefaultPDFImportStyle); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Default PDF file link action")); - builder.nextLine(); - builder.append(pan); - - JPanel pan2 = new JPanel(); - JLabel lab = new JLabel(Localization.lang("Filename format pattern").concat(":")); - pan2.add(lab); - pan2.add(fileNamePattern); - pan2.add(selectFileNamePattern); - builder.append(pan2); - - JPanel pan3 = new JPanel(); - JLabel lbfileDirPattern = new JLabel(Localization.lang("File directory pattern").concat(":")); - pan3.add(lbfileDirPattern); - pan3.add(fileDirPattern); - - builder.nextLine(); - builder.append(pan); - builder.append(pan3); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + public Node getBuilder() { + return builder; } @Override @@ -116,22 +98,22 @@ public void setValues() { useDefaultPDFImportStyle.setSelected(prefs.getBoolean(JabRefPreferences.IMPORT_ALWAYSUSE)); int style = prefs.getInt(JabRefPreferences.IMPORT_DEFAULT_PDF_IMPORT_STYLE); switch (style) { - case ImportDialog.NOMETA: - radioButtonNoMeta.setSelected(true); - break; - case ImportDialog.XMP: - radioButtonXmp.setSelected(true); - break; - case ImportDialog.CONTENT: - radioButtonPDFcontent.setSelected(true); - break; - case ImportDialog.ONLYATTACH: - radioButtononlyAttachPDF.setSelected(true); - break; - default: - // fallback - radioButtonPDFcontent.setSelected(true); - break; + case ImportDialog.NOMETA: + radioButtonNoMeta.setSelected(true); + break; + case ImportDialog.XMP: + radioButtonXmp.setSelected(true); + break; + case ImportDialog.CONTENT: + radioButtonPDFcontent.setSelected(true); + break; + case ImportDialog.ONLYATTACH: + radioButtononlyAttachPDF.setSelected(true); + break; + default: + // fallback + radioButtonPDFcontent.setSelected(true); + break; } fileNamePattern.setText(prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN)); fileDirPattern.setText(prefs.get(JabRefPreferences.IMPORT_FILEDIRPATTERN)); @@ -165,14 +147,4 @@ public String getTabName() { return Localization.lang("Import"); } - private void openFilePatternMenu() { - JPopupMenu popup = new JPopupMenu(); - for (int i = 0; i < ImportSettingsTab.DEFAULT_FILENAMEPATTERNS.length; i++) { - final JMenuItem item = new JMenuItem(ImportSettingsTab.DEFAULT_FILENAMEPATTERNS_DISPLAY[i]); - final String toSet = ImportSettingsTab.DEFAULT_FILENAMEPATTERNS[i]; - item.addActionListener(e -> fileNamePattern.setText(toSet)); - popup.add(item); - } - popup.show(selectFileNamePattern, 0, selectFileNamePattern.getHeight()); - } } diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 21491994a99..3a91d0ad879 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -1,197 +1,166 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; -import org.jabref.gui.OSXCompatibleToolbar; import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.logic.layout.format.NameFormatter; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -public class NameFormatterTab extends JPanel implements PrefsTab { +public class NameFormatterTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; - - private final JTable table; - - private int rowCount = -1; - + private final TableView table; + private final GridPane builder = new GridPane(); private final List tableRows = new ArrayList<>(10); + private final ObservableList data = FXCollections.observableArrayList(); - static class TableRow { - - private String name; + public static class TableRow { + private SimpleStringProperty name; + private SimpleStringProperty format; - private String format; - - - public TableRow() { + TableRow() { this(""); } - public TableRow(String name) { + TableRow(String name) { this(name, NameFormatter.DEFAULT_FORMAT); } - public TableRow(String name, String format) { - this.name = name; - this.format = format; + TableRow(String name, String format) { + this.name = new SimpleStringProperty(name); + this.format = new SimpleStringProperty(format); } public String getName() { - return name; + return name.get(); } public void setName(String name) { - this.name = name; + this.name.set(name); } public String getFormat() { - return format; + return format.get(); } public void setFormat(String format) { - this.format = format; + this.format.set(format); } } - /** * Tab to create custom Name Formatters * */ public NameFormatterTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - setLayout(new BorderLayout()); - - TableModel tableModel = new AbstractTableModel() { - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int row, int column) { - if (row >= tableRows.size()) { - return ""; - } - TableRow tr = tableRows.get(row); - if (tr == null) { - return ""; - } - // Only two columns - if (column == 0) { - return tr.getName(); - } else { - return tr.getFormat(); - } - } - - @Override - public String getColumnName(int col) { - return col == 0 ? Localization.lang("Formatter name") : - Localization.lang("Format string"); - } - - @Override - public Class getColumnClass(int column) { - return String.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return true; - } - - @Override - public void setValueAt(Object value, int row, int col) { + TableColumn firstCol = new TableColumn<>(Localization.lang("Formatter name")); + TableColumn lastCol = new TableColumn<>(Localization.lang("Format string")); + table = new TableView(); + table.setEditable(true); + firstCol.setCellValueFactory(new PropertyValueFactory<>("name")); + firstCol.setCellFactory(TextFieldTableCell.forTableColumn()); + firstCol.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + lastCol.setCellValueFactory(new PropertyValueFactory<>("format")); + lastCol.setCellFactory(TextFieldTableCell.forTableColumn()); + lastCol.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setFormat(t.getNewValue()); + }); + firstCol.setPrefWidth(140); + lastCol.setPrefWidth(200); + table.setItems(data); + table.getColumns().addAll(firstCol, lastCol); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setMaxWidth(100); + final TextField addLast = new TextField(); + addLast.setMaxWidth(100); + addLast.setPromptText("format"); + + BorderPane tabPanel = new BorderPane(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setMaxHeight(400); + scrollPane.setMaxWidth(360); + scrollPane.setContent(table); + tabPanel.setCenter(scrollPane); + + Label insertRows = new Label(Localization.lang("Insert rows")); + insertRows.setVisible(false); + Button add = new Button("Insert"); + add.setFont(FontSize.smallFont); + add.setOnAction(e-> { + if (!addName.getText().isEmpty() && !addLast.getText().isEmpty()) { + TableRow tableRow = new TableRow(addName.getText(), addLast.getText()); + addName.clear(); + addLast.clear(); + data.add(tableRow); + tableRows.add(tableRow); + table.setItems(data); tableChanged = true; - - // Make sure the vector is long enough. - while (row >= tableRows.size()) { - tableRows.add(new TableRow()); - } - - TableRow rowContent = tableRows.get(row); - - if (col == 0) { - rowContent.setName(value.toString()); - } else { - rowContent.setFormat(value.toString()); - } + table.refresh(); } - }; - - table = new JTable(tableModel); - - TableColumnModel columnModel = table.getColumnModel(); - columnModel.getColumn(0).setPreferredWidth(140); - columnModel.getColumn(1).setPreferredWidth(400); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - JPanel pan = new JPanel(); - - JPanel tabPanel = new JPanel(); - tabPanel.setLayout(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - table.setPreferredScrollableViewportSize(new Dimension(250, 200)); - scrollPane.setMinimumSize(new Dimension(250, 300)); - scrollPane.setPreferredSize(new Dimension(600, 300)); - tabPanel.add(scrollPane, BorderLayout.CENTER); - - JToolBar toolBar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolBar.setFloatable(false); - toolBar.setBorder(null); - toolBar.add(new AddRowAction()); - toolBar.add(new DeleteRowAction()); - toolBar.add(new HelpAction(Localization.lang("Help on Name Formatting"), - HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton()); - - tabPanel.add(toolBar, BorderLayout.EAST); - - builder.appendSeparator(Localization.lang("Special name formatters")); - builder.nextLine(); - builder.append(pan); - builder.append(tabPanel); - builder.nextLine(); + }); + Label deleteRows = new Label(Localization.lang("Delete rows")); + deleteRows.setVisible(false); + Button delete = new Button("Delete"); + delete.setFont(FontSize.smallFont); + delete.setOnAction(e-> { + if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex() != -1) { + tableChanged = true; + int row = table.getFocusModel().getFocusedIndex(); + TableRow tableRow = tableRows.get(row); + tableRows.remove(tableRow); + data.remove(tableRow); + table.setItems(data); + table.refresh(); + }}); + Button help = new Button("?"); + help.setFont(FontSize.smallFont); + help.setOnAction(e-> new HelpAction(Localization.lang("Help on Name Formatting"), + HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton().doClick()); + HBox toolbar = new HBox(); + toolbar.getChildren().addAll(addName, addLast,add,delete,help); + tabPanel.setBottom(toolbar); + + Label specialNameFormatters = new Label(Localization.lang("Special name formatters") + " ------------------------------------"); + specialNameFormatters.setFont(FontSize.bigFont); + builder.add(specialNameFormatters, 1, 1); + builder.add(tabPanel, 1, 2); + } - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + public Node getBuilder() { + return builder; } @Override @@ -207,75 +176,8 @@ public void setValues() { tableRows.add(new TableRow(names.get(i))); } } - rowCount = tableRows.size() + 5; } - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - tableChanged = true; - - int[] selectedRows = table.getSelectedRows(); - - int numberDeleted = 0; - - for (int i = selectedRows.length - 1; i >= 0; i--) { - if (selectedRows[i] < tableRows.size()) { - tableRows.remove(selectedRows[i]); - numberDeleted++; - } - } - - rowCount -= numberDeleted; - - if (selectedRows.length > 1) { - table.clearSelection(); - } - - table.revalidate(); - table.repaint(); - } - } - - class AddRowAction extends AbstractAction { - - public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - table.revalidate(); - table.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if (((rows[i] + i) - 1) < tableRows.size()) { - tableRows.add(Math.max(0, (rows[i] + i) - 1), new TableRow()); - } - } - rowCount += rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); - tableChanged = true; - } - } - - /** * Store changes to table preferences. This method is called when the user * clicks Ok. @@ -284,12 +186,6 @@ public void actionPerformed(ActionEvent e) { @Override public void storeSettings() { - if (table.isEditing()) { - int col = table.getEditingColumn(); - int row = table.getEditingRow(); - table.getCellEditor(row, col).stopCellEditing(); - } - // Now we need to make sense of the contents the user has made to the // table setup table. if (tableChanged) { diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index fbff70a1b18..860b8b2af37 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -1,15 +1,14 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Paint; import org.jabref.gui.DialogService; import org.jabref.gui.util.DefaultTaskExecutor; @@ -18,83 +17,83 @@ import org.jabref.logic.net.ProxyRegisterer; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -public class NetworkTab extends JPanel implements PrefsTab { +public class NetworkTab extends Pane implements PrefsTab { - private final JCheckBox useProxyCheckBox; - private final JTextField hostnameTextField; - private final JTextField portTextField; - private final JCheckBox useAuthenticationCheckBox; - private final JTextField usernameTextField; - private final JPasswordField passwordTextField; + private final CheckBox useProxyCheckBox; + private final TextField hostnameTextField; + private final TextField portTextField; + private final CheckBox useAuthenticationCheckBox; + private final TextField usernameTextField; + private final PasswordField passwordTextField; private final JabRefPreferences preferences; private ProxyPreferences oldProxyPreferences; private final DialogService dialogService; + private final GridPane builder = new GridPane(); public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { this.dialogService = dialogService; this.preferences = preferences; - setLayout(new BorderLayout()); - - useProxyCheckBox = new JCheckBox(Localization.lang("Use custom proxy configuration")); - - hostnameTextField = new JTextField(); - hostnameTextField.setEnabled(false); - portTextField = new JTextField(); - portTextField.setEnabled(false); - - useAuthenticationCheckBox = new JCheckBox(Localization.lang("Proxy requires authentication")); - useAuthenticationCheckBox.setEnabled(false); - - usernameTextField = new JTextField(); - usernameTextField.setEnabled(false); - passwordTextField = new JPasswordField(); - passwordTextField.setEnabled(false); - JLabel passwordWarningLabel = new JLabel(Localization.lang("Attention: Password is stored in plain text!")); - passwordWarningLabel.setEnabled(false); - passwordWarningLabel.setForeground(Color.RED); - - Insets margin = new Insets(0, 12, 3, 0); - useProxyCheckBox.setMargin(margin); - portTextField.setMargin(margin); - useAuthenticationCheckBox.setMargin(margin); + useProxyCheckBox = new CheckBox(Localization.lang("Use custom proxy configuration")); + useProxyCheckBox.setFont(FontSize.smallFont); + hostnameTextField = new TextField(); + hostnameTextField.setDisable(true); + portTextField = new TextField(); + portTextField.setDisable(true); + + useAuthenticationCheckBox = new CheckBox(Localization.lang("Proxy requires authentication")); + useAuthenticationCheckBox.setFont(FontSize.smallFont); + useAuthenticationCheckBox.setDisable(true); + + usernameTextField = new TextField(); + usernameTextField.setDisable(true); + passwordTextField = new PasswordField(); + passwordTextField.setDisable(true); + Label passwordWarningLabel = new Label(Localization.lang("Attention: Password is stored in plain text!")); + passwordWarningLabel.setFont(FontSize.smallFont); + passwordWarningLabel.setDisable(true); + passwordWarningLabel.setTextFill(Paint.valueOf("Red")); // Listener on useProxyCheckBox to enable and disable the proxy related settings; - useProxyCheckBox.addChangeListener(event -> { - hostnameTextField.setEnabled(useProxyCheckBox.isSelected()); - portTextField.setEnabled(useProxyCheckBox.isSelected()); - useAuthenticationCheckBox.setEnabled(useProxyCheckBox.isSelected()); + useProxyCheckBox.setOnAction(event -> { + hostnameTextField.setDisable(!useProxyCheckBox.isSelected()); + portTextField.setDisable(!useProxyCheckBox.isSelected()); + useAuthenticationCheckBox.setDisable(!useProxyCheckBox.isSelected()); }); - useAuthenticationCheckBox.addChangeListener(event -> { - usernameTextField.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); - passwordTextField.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); - passwordWarningLabel.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); + useAuthenticationCheckBox.setOnAction(event -> { + usernameTextField.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); + passwordTextField.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); + passwordWarningLabel.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); }); - FormLayout layout = new FormLayout("8dlu, left:pref, 4dlu, left:pref, 4dlu, fill:150dlu", - "p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, p"); - FormBuilder builder = FormBuilder.create().layout(layout); - - builder.addSeparator(Localization.lang("Network")).xyw(1, 1, 6); - builder.add(useProxyCheckBox).xyw(2, 3, 5); - builder.add(Localization.lang("Hostname") + ':').xy(2, 5); - builder.add(hostnameTextField).xyw(4, 5, 3); - builder.add(Localization.lang("Port") + ':').xy(2, 7); - builder.add(portTextField).xyw(4, 7, 3); - builder.add(useAuthenticationCheckBox).xyw(4, 9, 3); - builder.add(Localization.lang("Username") + ':').xy(4, 11); - builder.add(usernameTextField).xy(6, 11); - builder.add(Localization.lang("Password") + ':').xy(4, 13); - builder.add(passwordTextField).xy(6, 13); - builder.add(passwordWarningLabel).xy(6, 14); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + Label network = new Label(Localization.lang("Network") + " ---------------------------------"); + network.setFont(FontSize.bigFont); + builder.add(network, 1, 1); + builder.add(new Separator(), 2, 1); + builder.add(useProxyCheckBox, 2, 2); + Label hostname = new Label(Localization.lang("Hostname") + ':'); + hostname.setFont(FontSize.smallFont); + builder.add(hostname, 1, 3); + builder.add(hostnameTextField, 2, 3); + Label port = new Label(Localization.lang("Port") + ':'); + port.setFont(FontSize.smallFont); + builder.add(port, 1, 4); + builder.add(portTextField, 2, 4); + builder.add(useAuthenticationCheckBox, 2, 5); + Label username = new Label(Localization.lang("Username") + ':'); + username.setFont(FontSize.smallFont); + builder.add(username, 2, 6); + builder.add(usernameTextField, 3, 6); + Label password = new Label(Localization.lang("Password") + ':'); + password.setFont(FontSize.smallFont); + builder.add(password, 2, 7); + builder.add(passwordTextField, 3, 7); + builder.add(passwordWarningLabel, 3, 8); + } + + public Node getBuilder() { + return builder; } @Override @@ -118,7 +117,7 @@ public void storeSettings() { String port = portTextField.getText().trim(); Boolean useAuthentication = useAuthenticationCheckBox.isSelected(); String username = usernameTextField.getText().trim(); - String password = new String(passwordTextField.getPassword()); + String password = passwordTextField.getText(); ProxyPreferences proxyPreferences = new ProxyPreferences(useProxy, hostname, port, useAuthentication, username, password); if (!proxyPreferences.equals(oldProxyPreferences)) { @@ -147,9 +146,9 @@ public boolean validateSettings() { } if (useAuthenticationCheckBox.isSelected()) { String userName = usernameTextField.getText(); - char[] password = passwordTextField.getPassword(); + char[] password = passwordTextField.getText().toCharArray(); // no empty proxy passwords currently supported (they make no sense in this case anyway) - if ((userName == null) || userName.trim().isEmpty() || (password == null) || (password.length == 0)) { + if ((userName == null) || userName.trim().isEmpty() || (password.length == 0)) { validAuthenticationSetting = false; validSetting = false; } else { diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java index 61b497f8c8d..5596f47920a 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java @@ -1,29 +1,22 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Component; -import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.nio.file.Path; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.prefs.BackingStoreException; import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.ListSelectionModel; +import javafx.geometry.Pos; +import javafx.scene.control.Button; import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.layout.BorderPane; import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; import org.jabref.Globals; import org.jabref.JabRefException; @@ -61,166 +54,201 @@ public class PreferencesDialog extends BaseDialog { private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesDialog.class); - private final JPanel main; + private final BorderPane main; private final DialogService dialogService; private final JabRefFrame frame; private final JabRefPreferences prefs; + private final AdvancedTab advancedTab; + private final AppearancePrefsTab appearancePrefsTab; + private final BibtexKeyPatternPrefTab bibtexKeyPatternPrefTab; + private final EntryEditorPrefsTab entryEditorPrefsTab; + private final ExportSortingPrefsTab exportSortingPrefsTab; + private final ExternalTab externalTab; + private final FileTab fileTab; + private final GeneralTab generalTab; + private final GroupsPrefsTab groupsPrefsTab; + private final ImportSettingsTab importSettingsTab; + private final NameFormatterTab nameFormatterTab; + private final NetworkTab networkTab; + private final PreviewPrefsTab previewPrefsTab; + private final TableColumnsTab tableColumnsTab; + private final TablePrefsTab tablePrefsTab; + private final XmpPrefsTab xmpPrefsTab; + private ArrayList arrayList = new ArrayList<>(); public PreferencesDialog(JabRefFrame parent) { setTitle(Localization.lang("JabRef preferences")); - getDialogPane().setPrefSize(1000, 800); + getDialogPane().setPrefSize(1250, 800); getDialogPane().setMinHeight(Region.USE_PREF_SIZE); setResizable(true); - ButtonType save = new ButtonType(Localization.lang("Save"), ButtonData.OK_DONE); - getDialogPane().getButtonTypes().addAll(save, ButtonType.CANCEL); ControlHelper.setAction(save, getDialogPane(), event -> { - storeAllSettings(); + storeAllSettings(); close(); }); prefs = JabRefPreferences.getInstance(); frame = parent; dialogService = frame.getDialogService(); + advancedTab = new AdvancedTab(dialogService,prefs); + appearancePrefsTab = new AppearancePrefsTab(dialogService,prefs); + bibtexKeyPatternPrefTab = new BibtexKeyPatternPrefTab(prefs,frame.getCurrentBasePanel()); + entryEditorPrefsTab = new EntryEditorPrefsTab(prefs); + exportSortingPrefsTab = new ExportSortingPrefsTab(prefs); + externalTab = new ExternalTab(frame,this,prefs); + fileTab = new FileTab(dialogService,prefs); + generalTab = new GeneralTab(dialogService,prefs); + groupsPrefsTab = new GroupsPrefsTab(prefs); + importSettingsTab = new ImportSettingsTab(prefs); + nameFormatterTab = new NameFormatterTab(prefs); + networkTab = new NetworkTab(dialogService,prefs); + previewPrefsTab = new PreviewPrefsTab(dialogService); + tableColumnsTab = new TableColumnsTab(prefs,frame); + tablePrefsTab = new TablePrefsTab(prefs); + xmpPrefsTab = new XmpPrefsTab(prefs); + + if (arrayList.isEmpty()) { + arrayList.add(advancedTab); + arrayList.add(appearancePrefsTab); + arrayList.add(bibtexKeyPatternPrefTab); + arrayList.add(entryEditorPrefsTab); + arrayList.add(exportSortingPrefsTab); + arrayList.add(externalTab); + arrayList.add(fileTab); + arrayList.add(generalTab); + arrayList.add(groupsPrefsTab); + arrayList.add(importSettingsTab); + arrayList.add(nameFormatterTab); + arrayList.add(networkTab); + arrayList.add(previewPrefsTab); + arrayList.add(tableColumnsTab); + arrayList.add(tablePrefsTab); + arrayList.add(xmpPrefsTab); + } - main = new JPanel(); - - ControlHelper.setSwingContent(getDialogPane(), constructSwingContent()); + main = new BorderPane(); + main.setCenter(generalTab.getBuilder()); + getDialogPane().setContent(main); + construct(); } - private JComponent constructSwingContent() { - JPanel mainPanel = new JPanel(); - final CardLayout cardLayout = new CardLayout(); - main.setLayout(cardLayout); - - List tabs = new ArrayList<>(); - tabs.add(new GeneralTab(dialogService, prefs)); - tabs.add(new FileTab(dialogService, prefs)); - tabs.add(new TablePrefsTab(prefs)); - tabs.add(new TableColumnsTab(prefs, frame)); - tabs.add(new PreviewPrefsTab(dialogService)); - tabs.add(new ExternalTab(frame, this, prefs)); - tabs.add(new GroupsPrefsTab(prefs)); - tabs.add(new EntryEditorPrefsTab(prefs)); - tabs.add(new BibtexKeyPatternPrefTab(prefs, frame.getCurrentBasePanel())); - tabs.add(new ImportSettingsTab(prefs)); - tabs.add(new ExportSortingPrefsTab(prefs)); - tabs.add(new NameFormatterTab(prefs)); - tabs.add(new XmpPrefsTab(prefs)); - tabs.add(new NetworkTab(dialogService, prefs)); - tabs.add(new AdvancedTab(dialogService, prefs)); - tabs.add(new AppearancePrefsTab(dialogService, prefs)); - - // add all tabs - tabs.forEach(tab -> main.add((Component) tab, tab.getTabName())); - - mainPanel.setBorder(BorderFactory.createEtchedBorder()); - - String[] tabNames = tabs.stream().map(PrefsTab::getTabName).toArray(String[]::new); - JList chooser = new JList<>(tabNames); - chooser.setBorder(BorderFactory.createEtchedBorder()); - // Set a prototype value to control the width of the list: - chooser.setPrototypeCellValue("This should be wide enough"); - chooser.setSelectedIndex(0); - chooser.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - // Add the selection listener that will show the correct panel when - // selection changes: - chooser.addListSelectionListener(e -> { - if (e.getValueIsAdjusting()) { - return; - } - String o = chooser.getSelectedValue(); - cardLayout.show(main, o); - }); + private void construct() { + VBox vBox = new VBox(); + vBox.setPrefSize(160,800); + Button []button = new Button[20]; + + button[0] = new Button(Localization.lang("General")); + button[0].setOnAction( e -> main.setCenter(generalTab.getBuilder())); + button[1] = new Button(Localization.lang("File")); + button[1].setOnAction( e-> main.setCenter(fileTab.getBuilder())); + button[2] = new Button(Localization.lang("Entry table")); + button[2].setOnAction(e -> main.setCenter(tablePrefsTab.getBuilder())); + button[3] = new Button(Localization.lang("Entry table columns")); + button[3].setOnAction( e -> main.setCenter(tableColumnsTab.getBuilder())); + button[4] = new Button(Localization.lang("Entry preview")); + button[4].setOnAction( e -> main.setCenter(previewPrefsTab.getGridPane())); + button[5] = new Button(Localization.lang("External programs")); + button[5].setOnAction(e -> main.setCenter(externalTab.getBuilder())); + button[6] = new Button(Localization.lang("Groups")); + button[6].setOnAction( e -> main.setCenter(groupsPrefsTab.getBuilder())); + button[7] = new Button(Localization.lang("Entry editor")); + button[7].setOnAction( e -> main.setCenter(entryEditorPrefsTab.getBuilder())); + button[8] = new Button(Localization.lang("BibTeX key generator")); + button[8].setOnAction( e -> main.setCenter(bibtexKeyPatternPrefTab.getBuilder())); + button[9] = new Button(Localization.lang("Import")); + button[9].setOnAction( e -> main.setCenter(importSettingsTab.getBuilder())); + button[10] = new Button(Localization.lang("Export sorting")); + button[10].setOnAction( e -> main.setCenter(exportSortingPrefsTab.getBuilder())); + button[11] = new Button(Localization.lang("Name formatter")); + button[11].setOnAction( e -> main.setCenter(nameFormatterTab.getBuilder())); + button[12] = new Button(Localization.lang("XMP-metadata")); + button[12].setOnAction( e -> main.setCenter(xmpPrefsTab.getBuilder())); + button[13] = new Button(Localization.lang("Network")); + button[13].setOnAction(e -> main.setCenter(networkTab.getBuilder())); + button[14] = new Button(Localization.lang("Advanced")); + button[14].setOnAction( e -> main.setCenter(advancedTab.getBuilder())); + button[15] = new Button(Localization.lang("Appearance")); + button[15].setOnAction( e -> main.setCenter(appearancePrefsTab.getContainer())); + button[16] = new Button(Localization.lang("Import preferences")); + button[17] = new Button(Localization.lang("Export preferences")); + button[18] = new Button(Localization.lang("Show preferences")); + button[19] = new Button(Localization.lang("Reset preferences")); + for (int i = 0; i < button.length; i++) { + button[i].setFont(FontSize.smallFont); + button[i].setEffect(null); + button[i].setAlignment(Pos.BASELINE_LEFT); + button[i].setPrefSize(130,20); + } + + for (int i = 0; i < 16; i++) { + vBox.getChildren().add(button[i]); + } + for (int i = 0; i < 12; i++) { + vBox.getChildren().add(new Label("")); + } - JPanel buttons = new JPanel(); - buttons.setLayout(new GridLayout(4, 1)); - JButton importPreferences = new JButton(Localization.lang("Import preferences")); - buttons.add(importPreferences, 0); - JButton exportPreferences = new JButton(Localization.lang("Export preferences")); - buttons.add(exportPreferences, 1); - JButton showPreferences = new JButton(Localization.lang("Show preferences")); - buttons.add(showPreferences, 2); - JButton resetPreferences = new JButton(Localization.lang("Reset preferences")); - buttons.add(resetPreferences, 3); - - JPanel westPanel = new JPanel(); - westPanel.setLayout(new BorderLayout()); - westPanel.add(chooser, BorderLayout.CENTER); - westPanel.add(buttons, BorderLayout.SOUTH); - mainPanel.setLayout(new BorderLayout()); - mainPanel.add(putPanelInScrollPane(main), BorderLayout.CENTER); - mainPanel.add(putPanelInScrollPane(westPanel), BorderLayout.WEST); + vBox.getChildren().addAll(button[16], button[17], button[18], button[19]); + main.setLeft(vBox); // TODO: Key bindings: // KeyBinder.bindCloseDialogKeyToCancelAction(this.getRootPane(), cancelAction); - // Import and export actions: - exportPreferences.setToolTipText(Localization.lang("Export preferences to file")); - exportPreferences.addActionListener(new ExportAction()); + button[17].setAccessibleText(Localization.lang("Export preferences to file")); + button[17].setOnAction( e -> new ExportAction()); - importPreferences.setToolTipText(Localization.lang("Import preferences from file")); - importPreferences.addActionListener(e -> { + button[16].setAccessibleText(Localization.lang("Import preferences from file")); + button[16].setOnAction(e -> importPreferences()); - FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .addExtensionFilter(StandardFileType.XML) - .withDefaultExtension(StandardFileType.XML) - .withInitialDirectory(getPrefsExportPath()).build(); + button[18].setOnAction( + e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).setVisible(true)); + button[19].setOnAction(e -> resetPreferences()); - Optional fileName = DefaultTaskExecutor - .runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)); + setValues(); - if (fileName.isPresent()) { - try { - prefs.importPreferences(fileName.get().toString()); - updateAfterPreferenceChanges(); + } - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showWarningDialogAndWait(Localization.lang("Import preferences"), - Localization.lang("You must restart JabRef for this to come into effect."))); - } catch (JabRefException ex) { - LOGGER.warn(ex.getMessage(), ex); - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Import preferences"), ex)); - } + private void resetPreferences() { + boolean resetPreferencesClicked = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogAndWait(Localization.lang("Reset preferences"), + Localization.lang("Are you sure you want to reset all settings to default values?"), + Localization.lang("Reset preferences"), Localization.lang("Cancel"))); + if (resetPreferencesClicked) { + try { + prefs.clear(); + new SharedDatabasePreferences().clear(); + + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showWarningDialogAndWait(Localization.lang("Reset preferences"), + Localization.lang("You must restart JabRef for this to come into effect."))); + } catch (BackingStoreException ex) { + LOGGER.warn(ex.getMessage(), ex); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Reset preferences"), ex)); } - }); - - showPreferences.addActionListener( - e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).setVisible(true)); - resetPreferences.addActionListener(e -> { + updateAfterPreferenceChanges(); + } + } - boolean resetPreferencesClicked = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogAndWait(Localization.lang("Reset preferences"), - Localization.lang("Are you sure you want to reset all settings to default values?"), - Localization.lang("Reset preferences"), Localization.lang("Cancel"))); + private void importPreferences() { + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .addExtensionFilter(StandardFileType.XML) + .withDefaultExtension(StandardFileType.XML) + .withInitialDirectory(getPrefsExportPath()).build(); - if (resetPreferencesClicked) { - try { - prefs.clear(); - new SharedDatabasePreferences().clear(); + Optional fileName = DefaultTaskExecutor + .runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)); - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showWarningDialogAndWait(Localization.lang("Reset preferences"), - Localization.lang("You must restart JabRef for this to come into effect."))); - } catch (BackingStoreException ex) { - LOGGER.warn(ex.getMessage(), ex); - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Reset preferences"), ex)); - } + if (fileName.isPresent()) { + try { + prefs.importPreferences(fileName.get().toString()); updateAfterPreferenceChanges(); - } - }); - setValues(); - - return mainPanel; - } - - private JScrollPane putPanelInScrollPane(JPanel panel) { - JScrollPane scrollPane = new JScrollPane(panel); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setBorder(null); - return scrollPane; + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showWarningDialogAndWait(Localization.lang("Import preferences"), + Localization.lang("You must restart JabRef for this to come into effect."))); + } catch (JabRefException ex) { + LOGGER.warn(ex.getMessage(), ex); + DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Import preferences"), ex)); + } + } } private String getPrefsExportPath() { @@ -229,7 +257,6 @@ private String getPrefsExportPath() { private void updateAfterPreferenceChanges() { setValues(); - Map customExporters = prefs.customExports.getCustomExportFormats(prefs, Globals.journalAbbreviationLoader); LayoutFormatterPreferences layoutPreferences = prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader); SavePreferences savePreferences = prefs.loadForExportFromPreferences(); @@ -240,15 +267,14 @@ private void updateAfterPreferenceChanges() { private void storeAllSettings() { // First check that all tabs are ready to close: - Component[] preferenceTabs = main.getComponents(); - for (Component tab : preferenceTabs) { - if (!((PrefsTab) tab).validateSettings()) { + for (PrefsTab tab : arrayList) { + if (!tab.validateSettings()) { return; // If not, break off. } } // Then store settings and close: - for (Component tab : preferenceTabs) { - ((PrefsTab) tab).storeSettings(); + for (PrefsTab tab : arrayList) { + tab.storeSettings(); } prefs.flush(); @@ -259,10 +285,8 @@ private void storeAllSettings() { public void setValues() { // Update all field values in the tabs: - int count = main.getComponentCount(); - Component[] comps = main.getComponents(); - for (int i = 0; i < count; i++) { - ((PrefsTab) comps[i]).setValues(); + for (PrefsTab prefsTab : arrayList) { + prefsTab.setValues(); } } diff --git a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java index 1b1c1bbcf68..b639c4a952f 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java @@ -1,25 +1,26 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.ArrayList; import java.util.Comparator; -import java.util.Enumeration; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; -import javax.swing.BoxLayout; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.ListSelectionModel; import javax.swing.SwingWorker; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextArea; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; import org.jabref.Globals; import org.jabref.JabRefGUI; @@ -33,9 +34,6 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.preferences.PreviewPreferences; -import com.google.common.primitives.Ints; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.factories.Paddings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,22 +43,21 @@ public class PreviewPrefsTab extends JPanel implements PrefsTab { private SwingWorker, Void> discoverCitationStyleWorker; - private final DefaultListModel availableModel = new DefaultListModel<>(); - private final DefaultListModel chosenModel = new DefaultListModel<>(); - - private final JList available = new JList<>(availableModel); - private final JList chosen = new JList<>(chosenModel); - - private final JButton btnRight = new JButton("»"); - private final JButton btnLeft = new JButton("«"); - private final JButton btnUp = new JButton(Localization.lang("Up")); - private final JButton btnDown = new JButton(Localization.lang("Down")); - - private final JTextArea layout = new JTextArea("", 1, 1); - private final JButton btnTest = new JButton(Localization.lang("Test")); - private final JButton btnDefault = new JButton(Localization.lang("Default")); - private final JScrollPane scrollPane = new JScrollPane(layout); - + private final ObservableList availableModel = FXCollections.observableArrayList(); + private final ObservableList chosenModel = FXCollections.observableArrayList(); + + private final ListView available = new ListView<>(availableModel); + private final ListView chosen = new ListView<>(chosenModel); + + private final Button btnRight = new Button("»"); + private final Button btnLeft = new Button("«"); + private final Button btnUp = new Button(Localization.lang("Up")); + private final Button btnDown = new Button(Localization.lang("Down")); + private final GridPane gridPane = new GridPane(); + private final TextArea layout = new TextArea(); + private final Button btnTest = new Button(Localization.lang("Test")); + private final Button btnDefault = new Button(Localization.lang("Default")); + private final ScrollPane scrollPane = new ScrollPane(layout); private final DialogService dialogService; public PreviewPrefsTab(DialogService dialogService) { @@ -70,73 +67,71 @@ public PreviewPrefsTab(DialogService dialogService) { } private void setupLogic() { - chosen.getSelectionModel().addListSelectionListener(event -> { - boolean selectionEmpty = ((ListSelectionModel) event.getSource()).isSelectionEmpty(); - btnLeft.setEnabled(!selectionEmpty); - btnDown.setEnabled(!selectionEmpty); - btnUp.setEnabled(!selectionEmpty); + chosen.getSelectionModel().selectedItemProperty().addListener(event -> { + if (chosen.getSelectionModel().getSelectedIndices().isEmpty()) { + btnLeft.setDisable(true); + btnDown.setDisable(true); + btnUp.setDisable(true); + } }); - available.getSelectionModel() - .addListSelectionListener(e -> btnRight.setEnabled(!((ListSelectionModel) e.getSource()).isSelectionEmpty())); + available.getSelectionModel().selectedItemProperty().addListener( + e -> btnRight.setDisable(available.getSelectionModel().getSelectedIndices().isEmpty())); - btnRight.addActionListener(event -> { - for (Object object : available.getSelectedValuesList()) { - availableModel.removeElement(object); - chosenModel.addElement(object); + btnRight.setOnAction(event -> { + for (Object object : available.getSelectionModel().getSelectedItems()) { + availableModel.remove(object); + chosenModel.add(object); } storeSettings(); }); - btnLeft.addActionListener(event -> { - for (Object object : chosen.getSelectedValuesList()) { - availableModel.addElement(object); - chosenModel.removeElement(object); + btnLeft.setOnAction(event -> { + for (Object object : chosen.getSelectionModel().getSelectedItems()) { + availableModel.add(object); + chosenModel.remove(object); } storeSettings(); }); - btnUp.addActionListener(event -> { + btnUp.setOnAction(event -> { List newSelectedIndices = new ArrayList<>(); - for (int oldIndex : chosen.getSelectedIndices()) { + for (int oldIndex : chosen.getSelectionModel().getSelectedIndices()) { boolean alreadyTaken = newSelectedIndices.contains(oldIndex - 1); int newIndex = ((oldIndex > 0) && !alreadyTaken) ? oldIndex - 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); - newSelectedIndices.add(newIndex); + chosen.getSelectionModel().select(newIndex); } - chosen.setSelectedIndices(Ints.toArray(newSelectedIndices)); storeSettings(); }); - btnDown.addActionListener(event -> { + btnDown.setOnAction(event -> { List newSelectedIndices = new ArrayList<>(); - int[] selectedIndices = chosen.getSelectedIndices(); - for (int i = selectedIndices.length - 1; i >= 0; i--) { - int oldIndex = selectedIndices[i]; + ObservableList selectedIndices = chosen.getSelectionModel().getSelectedIndices(); + for (int i = selectedIndices.size() - 1; i >= 0; i--) { + int oldIndex = (int)selectedIndices.get(i); boolean alreadyTaken = newSelectedIndices.contains(oldIndex + 1); - int newIndex = ((oldIndex < (chosenModel.getSize() - 1)) && !alreadyTaken) ? oldIndex + 1 : oldIndex; + int newIndex = ((oldIndex < (chosenModel.size() - 1)) && !alreadyTaken) ? oldIndex + 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); - newSelectedIndices.add(newIndex); + chosen.getSelectionModel().select(newIndex); } - chosen.setSelectedIndices(Ints.toArray(newSelectedIndices)); storeSettings(); }); - btnDefault.addActionListener(event -> layout.setText(Globals.prefs.getPreviewPreferences() + btnDefault.setOnAction(event -> layout.setText(Globals.prefs.getPreviewPreferences() .getPreviewStyleDefault() .replace("__NEWLINE__", "\n"))); - btnTest.addActionListener(event -> { + btnTest.setOnAction(event -> { try { DefaultTaskExecutor.runInJavaFXThread(() -> { - PreviewPanel testPane = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), dialogService); - if (chosen.isSelectionEmpty()) { + if (chosen.getSelectionModel().getSelectedItems().isEmpty()) { testPane.setFixedLayout(layout.getText()); testPane.setEntry(TestEntry.getTestEntry()); } else { - int indexStyle = chosen.getSelectedIndex(); + int indexStyle = chosen.getSelectionModel().getSelectedIndex(); PreviewPreferences preferences = Globals.prefs.getPreviewPreferences(); preferences = new PreviewPreferences(preferences.getPreviewCycle(),indexStyle,preferences.getPreviewPanelDividerPosition(),preferences.isPreviewPanelEnabled(), preferences.getPreviewStyle(),preferences.getPreviewStyleDefault()); @@ -164,46 +159,28 @@ private void setupLogic() { } private void setupGui() { - JPanel chooseStyle = FormBuilder.create() - .columns("0:grow, $lcgap, pref, $lcgap, 0:grow") - .rows("pref, $lg, fill:pref:grow, $lg, pref:grow, $lg, pref:grow, $lg, pref:grow") - .padding(Paddings.DIALOG) - - .addSeparator(Localization.lang("Current Preview")) - .xyw(1, 1, 5) - .add(available) - .xywh(1, 3, 1, 7) - .add(chosen) - .xywh(5, 3, 1, 7) - - .add(btnRight) - .xy(3, 3, "fill, bottom") - .add(btnLeft) - .xy(3, 5, "fill, top") - .add(btnUp) - .xy(3, 7, "fill, bottom") - .add(btnDown) - .xy(3, 9, "fill, top") - .build(); - - JPanel preview = FormBuilder.create() - .columns("pref:grow, $lcgap, pref, $lcgap, pref") - .rows("pref, $lg, fill:pref:grow") - .padding(Paddings.DIALOG) - - .addSeparator(Localization.lang("Preview")) - .xy(1, 1) - .add(btnTest) - .xy(3, 1) - .add(btnDefault) - .xy(5, 1) - .add(scrollPane) - .xyw(1, 3, 5) - .build(); + VBox vBox = new VBox(); + btnRight.setPrefSize(80, 20); + btnLeft.setPrefSize(80, 20); + btnUp.setPrefSize(80, 20); + btnDown.setPrefSize(80, 20); + vBox.getChildren().addAll(new Label(""), new Label(""), new Label(""), new Label(""), new Label(""), + new Label(""), new Label(""), btnRight, btnLeft, new Label(""), new Label(""), new Label(""), + btnUp, btnDown); + Label currentPreview = new Label(Localization.lang("Current Preview") + " ------------------------------------------"); + currentPreview.setFont(FontSize.bigFont); + gridPane.add(currentPreview, 1, 1); + gridPane.add(available, 1, 2); + gridPane.add(vBox, 2, 2); + gridPane.add(chosen, 3, 2); + gridPane.add(btnTest, 2, 6); + gridPane.add(btnDefault, 3, 6); + layout.setPrefSize(600, 300); + gridPane.add(scrollPane, 1, 9); + } - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - add(chooseStyle, BorderLayout.CENTER); - add(preview, BorderLayout.PAGE_END); + public Node getGridPane() { + return gridPane; } @Override @@ -216,33 +193,32 @@ public void setValues() { // in case the style is not a valid citation style file, an empty Optional is returned Optional citationStyle = CitationStyle.createCitationStyleFromFile(style); if (citationStyle.isPresent()) { - chosenModel.addElement(citationStyle.get()); + chosenModel.add(citationStyle.get()); } else { if (isPreviewChosen) { LOGGER.error("Preview is already in the list, something went wrong"); continue; } isPreviewChosen = true; - chosenModel.addElement(Localization.lang("Preview")); + chosenModel.add(Localization.lang("Preview")); } } availableModel.clear(); if (!isPreviewChosen) { - availableModel.addElement(Localization.lang("Preview")); + availableModel.add(Localization.lang("Preview")); } - btnLeft.setEnabled(!chosen.isSelectionEmpty()); - btnRight.setEnabled(!available.isSelectionEmpty()); - btnUp.setEnabled(!chosen.isSelectionEmpty()); - btnDown.setEnabled(!chosen.isSelectionEmpty()); + btnLeft.setDisable(!chosen.getSelectionModel().getSelectedItems().isEmpty()); + btnRight.setDisable(available.getSelectionModel().getSelectedIndices().isEmpty()); + btnUp.setDisable(!chosen.getSelectionModel().getSelectedIndices().isEmpty()); + btnDown.setDisable(!chosen.getSelectionModel().getSelectedIndices().isEmpty()); if (discoverCitationStyleWorker != null) { discoverCitationStyleWorker.cancel(true); } discoverCitationStyleWorker = new SwingWorker, Void>() { - @Override protected List doInBackground() throws Exception { return CitationStyle.discoverCitationStyles(); @@ -257,9 +233,9 @@ public void done() { get().stream() .filter(style -> !previewPreferences.getPreviewCycle().contains(style.getFilePath())) .sorted(Comparator.comparing(CitationStyle::getTitle)) - .forEach(availableModel::addElement); + .forEach(availableModel::add); - btnRight.setEnabled(!availableModel.isEmpty()); + btnRight.setDisable(availableModel.isEmpty()); } catch (InterruptedException | ExecutionException e) { LOGGER.error("something went wrong while adding the discovered CitationStyles to the list "); } @@ -273,9 +249,7 @@ public void done() { @Override public void storeSettings() { List styles = new ArrayList<>(); - Enumeration elements = chosenModel.elements(); - while (elements.hasMoreElements()) { - Object obj = elements.nextElement(); + for (Object obj : chosenModel) { if (obj instanceof CitationStyle) { styles.add(((CitationStyle) obj).getFilePath()); } else if (obj instanceof String) { diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index b68b94710fe..8f0c1eec7c4 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -1,10 +1,7 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -12,74 +9,72 @@ import java.util.Locale; import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; + +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.RadioButton; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.OSXCompatibleToolbar; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibtexSingleField; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.FormLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class TableColumnsTab extends JPanel implements PrefsTab { +class TableColumnsTab extends Pane implements PrefsTab { private static final Logger LOGGER = LoggerFactory.getLogger(TableColumnsTab.class); private final JabRefPreferences prefs; private boolean tableChanged; - private final JTable colSetup; - private int rowCount = -1; + private final TableView colSetup; private final List tableRows = new ArrayList<>(10); private final JabRefFrame frame; - private final JCheckBox urlColumn; - private final JCheckBox fileColumn; - private final JCheckBox arxivColumn; - - private final JCheckBox extraFileColumns; - private final JList listOfFileColumns; + private final CheckBox urlColumn; + private final CheckBox fileColumn; + private final CheckBox arxivColumn; - private final JRadioButton preferUrl; - private final JRadioButton preferDoi; + private final CheckBox extraFileColumns; + private final ListView listOfFileColumns; + private final RadioButton preferUrl; + private final RadioButton preferDoi; /*** begin: special fields ***/ - private final JCheckBox specialFieldsEnabled; - private final JCheckBox rankingColumn; - private final JCheckBox qualityColumn; - private final JCheckBox priorityColumn; - private final JCheckBox relevanceColumn; - private final JCheckBox printedColumn; - private final JCheckBox readStatusColumn; - private final JRadioButton syncKeywords; - private final JRadioButton writeSpecialFields; + private final CheckBox specialFieldsEnabled; + private final CheckBox rankingColumn; + private final CheckBox qualityColumn; + private final CheckBox priorityColumn; + private final CheckBox relevanceColumn; + private final CheckBox printedColumn; + private final CheckBox readStatusColumn; + private final RadioButton syncKeywords; + private final RadioButton writeSpecialFields; private boolean oldSpecialFieldsEnabled; private boolean oldRankingColumn; private boolean oldQualityColumn; @@ -89,7 +84,9 @@ class TableColumnsTab extends JPanel implements PrefsTab { private boolean oldReadStatusColumn; private boolean oldSyncKeyWords; private boolean oldWriteSpecialFields; - + private final VBox listOfFileColumnsVBox; + private final ObservableList data; + private final GridPane builder = new GridPane(); /** * Customization of external program paths. * @@ -98,126 +95,138 @@ class TableColumnsTab extends JPanel implements PrefsTab { public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { this.prefs = prefs; this.frame = frame; - setLayout(new BorderLayout()); - - TableModel tm = new AbstractTableModel() { - - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int row, int column) { - int internalRow = row; - internalRow--; - if ((internalRow == -1) || (internalRow >= tableRows.size())) { - return ""; - } - - TableRow rowContent = tableRows.get(internalRow); - if (rowContent == null) { - return ""; - } - // Only two columns - if (column == 0) { - return rowContent.getName(); - } else { - return rowContent.getLength() > 0 ? Double.toString(rowContent.getLength()) : ""; - } - } - - @Override - public String getColumnName(int col) { - return col == 0 ? Localization.lang("Field name") : Localization.lang("Column width"); + this.data = FXCollections.observableArrayList( + new TableRow("entrytype",75), + new TableRow("author/editor",300), + new TableRow("title",470), + new TableRow("year",60), + new TableRow("journal",130), + new TableRow("bibtexkey",100)); + + colSetup = new TableView<>(); + TableColumn field = new TableColumn<>(Localization.lang("Field name")); + TableColumn column = new TableColumn<>(Localization.lang("Column width")); + field.setPrefWidth(400); + column.setPrefWidth(240); + field.setCellValueFactory(new PropertyValueFactory<>("name")); + field.setCellFactory(TextFieldTableCell.forTableColumn()); + field.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + column.setCellValueFactory(new PropertyValueFactory<>("length")); + column.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setLength(t.getNewValue()); + }); + + colSetup.setItems(data); + colSetup.getColumns().addAll(field,column); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setMaxWidth(field.getPrefWidth()); + addName.setPrefHeight(30); + final TextField addLast = new TextField(); + addLast.setMaxWidth(column.getPrefWidth()); + addLast.setPromptText("width"); + addLast.setPrefHeight(30); + BorderPane tabPanel = new BorderPane(); + ScrollPane sp = new ScrollPane(); + sp.setContent(colSetup); + tabPanel.setCenter(sp); + + HBox toolBar = new HBox(); + Button addRow = new Button("Add"); + addRow.setPrefSize(80, 20); + addRow.setOnAction( e -> { + if (!addLast.getText().isEmpty()) { + TableRow tableRow = addLast.getText().matches("[1-9][0-9]") ? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())) : new TableRow(addName.getText()); + addName.clear(); + addLast.clear(); + data.add(tableRow); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + tableChanged = true; + colSetup.refresh(); } + }); - @Override - public Class getColumnClass(int column) { - if (column == 0) { - return String.class; + Button deleteRow = new Button("Delete"); + deleteRow.setPrefSize(80, 20); + deleteRow.setOnAction(e -> { + if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex() != -1) { + tableChanged = true; + int row = colSetup.getFocusModel().getFocusedIndex(); + TableRow tableRow = data.get(row); + data.remove(tableRow); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + colSetup.refresh(); + }}); + Button up = new Button("Up"); + up.setPrefSize(80, 20); + up.setOnAction(e-> { + if (colSetup.getFocusModel() != null) { + int row = colSetup.getFocusModel().getFocusedIndex(); + if (row > data.size() || row == 0) { + return; } - return Integer.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return !((row == 0) && (col == 0)); + TableRow tableRow1 = data.get(row); + TableRow tableRow2 = data.get(row - 1); + data.set(row - 1, tableRow1); + data.set(row, tableRow2); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + colSetup.refresh(); + } else { + return; } - - @Override - public void setValueAt(Object value, int row, int col) { - tableChanged = true; - // Make sure the vector is long enough. - while (row >= tableRows.size()) { - tableRows.add(new TableRow("", -1)); - } - - TableRow rowContent = tableRows.get(row - 1); - - if (col == 0) { - rowContent.setName(value.toString()); - if ("".equals(getValueAt(row, 1))) { - setValueAt(String.valueOf(BibtexSingleField.DEFAULT_FIELD_LENGTH), row, 1); - } - } else { - if (value == null) { - rowContent.setLength(-1); - } else { - rowContent.setLength(Integer.parseInt(value.toString())); - } + }); + Button down = new Button("Down"); + down.setPrefSize(80, 20); + down.setOnAction(e-> { + if (colSetup.getFocusModel() != null) { + int row = colSetup.getFocusModel().getFocusedIndex(); + if (row + 1 > data.size()) { + return; } + TableRow tableRow1 = data.get(row); + TableRow tableRow2 = data.get(row + 1); + data.set(row + 1, tableRow1); + data.set(row, tableRow2); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + colSetup.refresh(); + } else { + return; } - - }; - - colSetup = new JTable(tm); - TableColumnModel cm = colSetup.getColumnModel(); - cm.getColumn(0).setPreferredWidth(140); - cm.getColumn(1).setPreferredWidth(80); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - JPanel tabPanel = new JPanel(); - tabPanel.setLayout(new BorderLayout()); - JScrollPane sp = new JScrollPane(colSetup, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - colSetup.setPreferredScrollableViewportSize(new Dimension(250, 200)); - sp.setMinimumSize(new Dimension(250, 300)); - tabPanel.add(sp, BorderLayout.CENTER); - JToolBar toolBar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolBar.setFloatable(false); - AddRowAction addRow = new AddRowAction(); - DeleteRowAction deleteRow = new DeleteRowAction(); - MoveRowUpAction moveUp = new MoveRowUpAction(); - MoveRowDownAction moveDown = new MoveRowDownAction(); - toolBar.setBorder(null); - toolBar.add(addRow); - toolBar.add(deleteRow); - toolBar.addSeparator(); - toolBar.add(moveUp); - toolBar.add(moveDown); - tabPanel.add(toolBar, BorderLayout.EAST); - - fileColumn = new JCheckBox(Localization.lang("Show file column")); - urlColumn = new JCheckBox(Localization.lang("Show URL/DOI column")); - preferUrl = new JRadioButton(Localization.lang("Show URL first")); - preferDoi = new JRadioButton(Localization.lang("Show DOI first")); - ButtonGroup preferUrlDoiGroup = new ButtonGroup(); - preferUrlDoiGroup.add(preferUrl); - preferUrlDoiGroup.add(preferDoi); - - urlColumn.addChangeListener(arg0 -> { - preferUrl.setEnabled(urlColumn.isSelected()); - preferDoi.setEnabled(urlColumn.isSelected()); }); - arxivColumn = new JCheckBox(Localization.lang("Show ArXiv column")); + toolBar.getChildren().addAll(addName, addLast, addRow, deleteRow, up, down); + tabPanel.setBottom(toolBar); + + fileColumn = new CheckBox(Localization.lang("Show file column")); + fileColumn.setFont(FontSize.smallFont); + urlColumn = new CheckBox(Localization.lang("Show URL/DOI column")); + urlColumn.setFont(FontSize.smallFont); + preferUrl = new RadioButton(Localization.lang("Show URL first")); + preferUrl.setFont(FontSize.smallFont); + preferDoi = new RadioButton(Localization.lang("Show DOI first")); + preferDoi.setFont(FontSize.smallFont); + + urlColumn.setOnAction(arg0 -> { + preferUrl.setDisable(!urlColumn.isSelected()); + preferDoi.setDisable(!urlColumn.isSelected()); + }); + arxivColumn = new CheckBox(Localization.lang("Show ArXiv column")); + arxivColumn.setFont(FontSize.smallFont); Collection fileTypes = ExternalFileTypes.getInstance().getExternalFileTypeSelection(); String[] fileTypeNames = new String[fileTypes.size()]; @@ -225,97 +234,109 @@ public void setValueAt(Object value, int row, int col) { for (ExternalFileType fileType : fileTypes) { fileTypeNames[i++] = fileType.getName(); } - listOfFileColumns = new JList<>(fileTypeNames); - JScrollPane listOfFileColumnsScrollPane = new JScrollPane(listOfFileColumns); - listOfFileColumns.setVisibleRowCount(3); - extraFileColumns = new JCheckBox(Localization.lang("Show extra columns")); - extraFileColumns.addChangeListener(arg0 -> listOfFileColumns.setEnabled(extraFileColumns.isSelected())); - - /*** begin: special table columns and special fields ***/ - - JButton helpButton = new HelpAction(Localization.lang("Help on special fields"), - HelpFile.SPECIAL_FIELDS).getHelpButton(); - - rankingColumn = new JCheckBox(Localization.lang("Show rank")); - qualityColumn = new JCheckBox(Localization.lang("Show quality")); - priorityColumn = new JCheckBox(Localization.lang("Show priority")); - relevanceColumn = new JCheckBox(Localization.lang("Show relevance")); - printedColumn = new JCheckBox(Localization.lang("Show printed status")); - readStatusColumn = new JCheckBox(Localization.lang("Show read status")); + listOfFileColumns = new ListView<>(FXCollections.observableArrayList(fileTypeNames)); + listOfFileColumnsVBox = new VBox(); + listOfFileColumnsVBox.getChildren().add(listOfFileColumns); + ScrollPane listOfFileColumnsScrollPane = new ScrollPane(); + listOfFileColumnsScrollPane.setMaxHeight(80); + listOfFileColumnsScrollPane.setContent(listOfFileColumnsVBox); + extraFileColumns = new CheckBox(Localization.lang("Show extra columns")); + extraFileColumns.setFont(FontSize.smallFont); + if (!extraFileColumns.isSelected()) { + listOfFileColumnsVBox.setDisable(true); + } + extraFileColumns.setOnAction(arg0 -> listOfFileColumnsVBox.setDisable(!extraFileColumns.isSelected())); + + /** begin: special table columns and special fields ***/ + + Button helpButton = new Button("?"); + helpButton.setPrefSize(20, 20); + helpButton.setOnAction(e->new HelpAction(Localization.lang("Help on special fields"), + HelpFile.SPECIAL_FIELDS).getHelpButton().doClick()); + + rankingColumn = new CheckBox(Localization.lang("Show rank")); + rankingColumn.setFont(FontSize.smallFont); + qualityColumn = new CheckBox(Localization.lang("Show quality")); + qualityColumn.setFont(FontSize.smallFont); + priorityColumn = new CheckBox(Localization.lang("Show priority")); + priorityColumn.setFont(FontSize.smallFont); + relevanceColumn = new CheckBox(Localization.lang("Show relevance")); + relevanceColumn.setFont(FontSize.smallFont); + printedColumn = new CheckBox(Localization.lang("Show printed status")); + printedColumn.setFont(FontSize.smallFont); + readStatusColumn = new CheckBox(Localization.lang("Show read status")); + readStatusColumn.setFont(FontSize.smallFont); // "sync keywords" and "write special" fields may be configured mutually exclusive only // The implementation supports all combinations (TRUE+TRUE and FALSE+FALSE, even if the latter does not make sense) // To avoid confusion, we opted to make the setting mutually exclusive - syncKeywords = new JRadioButton(Localization.lang("Synchronize with keywords")); - writeSpecialFields = new JRadioButton(Localization.lang("Write values of special fields as separate fields to BibTeX")); - ButtonGroup group = new ButtonGroup(); - group.add(syncKeywords); - group.add(writeSpecialFields); - - specialFieldsEnabled = new JCheckBox(Localization.lang("Enable special fields")); - specialFieldsEnabled.addChangeListener(event -> { + syncKeywords = new RadioButton(Localization.lang("Synchronize with keywords")); + syncKeywords.setFont(FontSize.smallFont); + writeSpecialFields = new RadioButton(Localization.lang("Write values of special fields as separate fields to BibTeX")); + writeSpecialFields.setFont(FontSize.smallFont); + + specialFieldsEnabled = new CheckBox(Localization.lang("Enable special fields")); + specialFieldsEnabled.setFont(FontSize.smallFont); + specialFieldsEnabled.setOnAction(event -> { boolean isEnabled = specialFieldsEnabled.isSelected(); - rankingColumn.setEnabled(isEnabled); - qualityColumn.setEnabled(isEnabled); - priorityColumn.setEnabled(isEnabled); - relevanceColumn.setEnabled(isEnabled); - printedColumn.setEnabled(isEnabled); - readStatusColumn.setEnabled(isEnabled); - syncKeywords.setEnabled(isEnabled); - writeSpecialFields.setEnabled(isEnabled); + rankingColumn.setDisable(!isEnabled); + qualityColumn.setDisable(!isEnabled); + priorityColumn.setDisable(!isEnabled); + relevanceColumn.setDisable(!isEnabled); + printedColumn.setDisable(!isEnabled); + readStatusColumn.setDisable(!isEnabled); + syncKeywords.setDisable(!isEnabled); + writeSpecialFields.setDisable(!isEnabled); }); - builder.appendSeparator(Localization.lang("Special table columns")); - builder.nextLine(); - builder.append(pan); - - DefaultFormBuilder specialTableColumnsBuilder = new DefaultFormBuilder(new FormLayout( - "8dlu, 8dlu, 8cm, 8dlu, 8dlu, left:pref:grow", "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref")); - CellConstraints cc = new CellConstraints(); - - specialTableColumnsBuilder.add(specialFieldsEnabled, cc.xyw(1, 1, 3)); - specialTableColumnsBuilder.add(rankingColumn, cc.xyw(2, 2, 2)); - specialTableColumnsBuilder.add(relevanceColumn, cc.xyw(2, 3, 2)); - specialTableColumnsBuilder.add(qualityColumn, cc.xyw(2, 4, 2)); - specialTableColumnsBuilder.add(priorityColumn, cc.xyw(2, 5, 2)); - specialTableColumnsBuilder.add(printedColumn, cc.xyw(2, 6, 2)); - specialTableColumnsBuilder.add(readStatusColumn, cc.xyw(2, 7, 2)); - specialTableColumnsBuilder.add(syncKeywords, cc.xyw(2, 10, 2)); - specialTableColumnsBuilder.add(writeSpecialFields, cc.xyw(2, 11, 2)); - specialTableColumnsBuilder.add(helpButton, cc.xyw(1, 12, 2)); - - specialTableColumnsBuilder.add(fileColumn, cc.xyw(5, 1, 2)); - specialTableColumnsBuilder.add(urlColumn, cc.xyw(5, 2, 2)); - specialTableColumnsBuilder.add(preferUrl, cc.xy(6, 3)); - specialTableColumnsBuilder.add(preferDoi, cc.xy(6, 4)); - specialTableColumnsBuilder.add(arxivColumn, cc.xyw(5, 5, 2)); - - specialTableColumnsBuilder.add(extraFileColumns, cc.xyw(5, 6, 2)); - specialTableColumnsBuilder.add(listOfFileColumnsScrollPane, cc.xywh(5, 7, 2, 6)); - - builder.append(specialTableColumnsBuilder.getPanel()); - builder.nextLine(); + Label specialTableColumns = new Label(Localization.lang("Special table columns") + " ------------------------------------"); + specialTableColumns.setFont(FontSize.bigFont); + builder.add(specialTableColumns, 1, 1); + + GridPane specialTableColumnsBuilder = new GridPane(); + specialTableColumnsBuilder.add(specialFieldsEnabled, 1, 1); + specialTableColumnsBuilder.add(rankingColumn, 1, 2); + specialTableColumnsBuilder.add(relevanceColumn, 1, 3); + specialTableColumnsBuilder.add(qualityColumn, 1, 4); + specialTableColumnsBuilder.add(priorityColumn, 1, 5); + specialTableColumnsBuilder.add(printedColumn, 1, 6); + specialTableColumnsBuilder.add(readStatusColumn, 1, 7); + specialTableColumnsBuilder.add(syncKeywords, 1, 8); + specialTableColumnsBuilder.add(writeSpecialFields, 1, 9); + specialTableColumnsBuilder.add(helpButton, 1, 10); + + specialTableColumnsBuilder.add(fileColumn, 2, 1); + specialTableColumnsBuilder.add(urlColumn, 2, 2); + specialTableColumnsBuilder.add(preferUrl, 2 ,3); + specialTableColumnsBuilder.add(preferDoi, 2, 4); + specialTableColumnsBuilder.add(arxivColumn, 2, 5); + + specialTableColumnsBuilder.add(extraFileColumns,2, 6); + specialTableColumnsBuilder.add(listOfFileColumnsScrollPane, 2, 10); + + builder.add(specialTableColumnsBuilder, 1, 2); /*** end: special table columns and special fields ***/ + builder.add(new Label(""), 1, 3); + Label entryTableColumns = new Label(Localization.lang("Entry table columns") + " --------------------------------------"); + entryTableColumns.setFont(FontSize.bigFont); + builder.add(entryTableColumns, 1, 4); + builder.add(tabPanel, 1, 5); + + Button buttonWidth = new Button("Update to current column widths"); + buttonWidth.setPrefSize(200, 30); + buttonWidth.setFont(FontSize.smallFont); + buttonWidth.setOnAction(e->new UpdateWidthsAction()); + Button buttonOrder = new Button("Update to current column order"); + buttonOrder.setPrefSize(200, 30); + buttonOrder.setFont(FontSize.smallFont); + buttonOrder.setOnAction(e->new UpdateOrderAction()); + builder.add(buttonWidth, 1, 6); + builder.add(buttonOrder, 1, 7); + } - builder.appendSeparator(Localization.lang("Entry table columns")); - builder.nextLine(); - builder.append(pan); - builder.append(tabPanel); - builder.nextLine(); - builder.append(pan); - JButton buttonWidth = new JButton(new UpdateWidthsAction()); - JButton buttonOrder = new JButton(new UpdateOrderAction()); - builder.append(buttonWidth); - builder.nextLine(); - builder.append(pan); - builder.append(buttonOrder); - builder.nextLine(); - builder.append(pan); - builder.nextLine(); - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + public Node getBuilder() { + return builder; } @Override @@ -330,20 +351,22 @@ public void setValues() { extraFileColumns.setSelected(prefs.getBoolean(JabRefPreferences.EXTRA_FILE_COLUMNS)); if (extraFileColumns.isSelected()) { List desiredColumns = prefs.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); - int listSize = listOfFileColumns.getModel().getSize(); + int listSize = listOfFileColumns.getSelectionModel().getSelectedIndex(); int[] indicesToSelect = new int[listSize]; for (int i = 0; i < listSize; i++) { indicesToSelect[i] = listSize + 1; for (String desiredColumn : desiredColumns) { - if (listOfFileColumns.getModel().getElementAt(i).equals(desiredColumn)) { + if (listOfFileColumns.getAccessibleText().equals(desiredColumn)) { indicesToSelect[i] = i; break; } } } - listOfFileColumns.setSelectedIndices(indicesToSelect); + for (int i = 0; i < listSize; i++) { + listOfFileColumns.getSelectionModel().select(indicesToSelect[i]); + } } else { - listOfFileColumns.setSelectedIndices(new int[] {}); + listOfFileColumns.getSelectionModel().select(new int[] {}); } /*** begin: special fields ***/ @@ -389,192 +412,44 @@ public void setValues() { tableRows.add(new TableRow(names.get(i))); } } - rowCount = tableRows.size() + 5; } /*** end: special fields ***/ - static class TableRow { + public static class TableRow { - private String name; - private double length; + private SimpleStringProperty name; + private SimpleDoubleProperty length; public TableRow() { - name = ""; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + name = new SimpleStringProperty(""); + length = new SimpleDoubleProperty(BibtexSingleField.DEFAULT_FIELD_LENGTH); } public TableRow(String name) { - this.name = name; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + this.name = new SimpleStringProperty(name); + length = new SimpleDoubleProperty(BibtexSingleField.DEFAULT_FIELD_LENGTH); } public TableRow(String name, double length) { - this.name = name; - this.length = length; + this.name = new SimpleStringProperty(name); + this.length = new SimpleDoubleProperty(length); } public String getName() { - return name; + return name.get(); } public void setName(String name) { - this.name = name; + this.name.set(name); } public double getLength() { - return length; - } - - public void setLength(int length) { - this.length = length; - } - } - - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = colSetup.getSelectedRows(); - if (rows.length == 0) { - return; - } - int offs = 0; - for (int i = rows.length - 1; i >= 0; i--) { - if ((rows[i] <= tableRows.size()) && (rows[i] != 0)) { - tableRows.remove(rows[i] - 1); - offs++; - } - } - rowCount -= offs; - if (rows.length > 1) { - colSetup.clearSelection(); - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - - class AddRowAction extends AbstractAction { - - public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = colSetup.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - colSetup.revalidate(); - colSetup.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if (((rows[i] + i) - 1) < tableRows.size()) { - tableRows.add(Math.max(0, (rows[i] + i) - 1), new TableRow()); - } - } - rowCount += rows.length; - if (rows.length > 1) { - colSetup.clearSelection(); - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - - abstract class AbstractMoveRowAction extends AbstractAction { - - public AbstractMoveRowAction(String string, Icon image) { - super(string, image); - } - - public void swap(int i, int j) { - if ((i < 0) || (i >= tableRows.size())) { - return; - } - if ((j < 0) || (j >= tableRows.size())) { - return; - } - TableRow tmp = tableRows.get(i); - tableRows.set(i, tableRows.get(j)); - tableRows.set(j, tmp); - } - } - - class MoveRowUpAction extends AbstractMoveRowAction { - - public MoveRowUpAction() { - super("Up", IconTheme.JabRefIcons.UP.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Move up")); + return length.get(); } - @Override - public void actionPerformed(ActionEvent e) { - int[] selected = colSetup.getSelectedRows(); - Arrays.sort(selected); - // first element (#) not inside tableRows - // don't move if a selected element is at bounce - if ((selected.length > 0) && (selected[0] > 1)) { - boolean[] newSelected = new boolean[colSetup.getRowCount()]; - for (int i : selected) { - swap(i - 1, i - 2); - newSelected[i - 1] = true; - } - // select all and remove unselected - colSetup.setRowSelectionInterval(0, colSetup.getRowCount() - 1); - for (int i = 0; i < colSetup.getRowCount(); i++) { - if (!newSelected[i]) { - colSetup.removeRowSelectionInterval(i, i); - } - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - } - - class MoveRowDownAction extends AbstractMoveRowAction { - - public MoveRowDownAction() { - super("Down", IconTheme.JabRefIcons.DOWN.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Down")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] selected = colSetup.getSelectedRows(); - Arrays.sort(selected); - final int last = selected.length - 1; - boolean[] newSelected = new boolean[colSetup.getRowCount()]; - // don't move if a selected element is at bounce - if ((selected.length > 0) && (selected[last] < tableRows.size())) { - for (int i = last; i >= 0; i--) { - swap(selected[i] - 1, selected[i]); - newSelected[selected[i] + 1] = true; - } - // select all and remove unselected - colSetup.setRowSelectionInterval(0, colSetup.getRowCount() - 1); - for (int i = 0; i < colSetup.getRowCount(); i++) { - if (!newSelected[i]) { - colSetup.removeRowSelectionInterval(i, i); - } - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } + public void setLength(double length) { + this.length.set(length); } } @@ -612,8 +487,10 @@ public void actionPerformed(ActionEvent e) { return n1.compareTo(n2); }); - colSetup.revalidate(); - colSetup.repaint(); + data.clear(); + data.addAll(tableRows); + colSetup.setItems(data); + colSetup.refresh(); tableChanged = true; } } @@ -671,12 +548,8 @@ public void storeSettings() { prefs.putBoolean(JabRefPreferences.ARXIV_COLUMN, arxivColumn.isSelected()); prefs.putBoolean(JabRefPreferences.EXTRA_FILE_COLUMNS, extraFileColumns.isSelected()); - if (extraFileColumns.isSelected() && !listOfFileColumns.isSelectionEmpty()) { - int numberSelected = listOfFileColumns.getSelectedIndices().length; - List selections = new ArrayList<>(numberSelected); - for (int i = 0; i < numberSelected; i++) { - selections.add(listOfFileColumns.getModel().getElementAt(listOfFileColumns.getSelectedIndices()[i])); - } + if (extraFileColumns.isSelected() && !listOfFileColumns.getSelectionModel().isEmpty()) { + ObservableList selections = listOfFileColumns.getSelectionModel().getSelectedItems(); prefs.putStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS, selections); } else { prefs.putStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS, new ArrayList<>()); @@ -728,11 +601,11 @@ public void storeSettings() { /*** end: special fields ***/ - if (colSetup.isEditing()) { - int col = colSetup.getEditingColumn(); - int row = colSetup.getEditingRow(); - colSetup.getCellEditor(row, col).stopCellEditing(); - } +// if (colSetup.isEditing()) { +// int col = colSetup.getEditingColumn(); +// int row = colSetup.getEditingRow(); +// colSetup.getCellEditor(row, col).stopCellEditing(); +// } // Now we need to make sense of the contents the user has made to the // table setup table. diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index acbee5be563..c563b75848d 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -1,19 +1,19 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import org.jabref.Globals; import org.jabref.logic.l10n.Localization; @@ -21,34 +21,31 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -class TablePrefsTab extends JPanel implements PrefsTab { +class TablePrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; - private final JCheckBox autoResizeMode; - private final JCheckBox priDesc; - private final JCheckBox secDesc; - private final JCheckBox terDesc; - - private final JRadioButton namesAsIs; - private final JRadioButton namesFf; - private final JRadioButton namesFl; - private final JRadioButton namesNatbib; - private final JRadioButton abbrNames; - private final JRadioButton noAbbrNames; - private final JRadioButton lastNamesOnly; - - private final JTextField priField; - private final JTextField secField; - private final JTextField terField; - private final JTextField numericFields; - private final JComboBox priSort; - private final JComboBox secSort; - private final JComboBox terSort; - + private final CheckBox autoResizeMode; + private final CheckBox priDesc; + private final CheckBox secDesc; + private final CheckBox terDesc; + + private final RadioButton namesAsIs; + private final RadioButton namesFf; + private final RadioButton namesFl; + private final RadioButton namesNatbib; + private final RadioButton abbrNames; + private final RadioButton noAbbrNames; + private final RadioButton lastNamesOnly; + + private final TextField priField; + private final TextField secField; + private final TextField terField; + private final TextField numericFields; + private final ComboBox priSort; + private final ComboBox secSort; + private final ComboBox terSort; + private final GridPane builder = new GridPane(); /** * Customization of external program paths. @@ -58,8 +55,6 @@ class TablePrefsTab extends JPanel implements PrefsTab { */ public TablePrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - setLayout(new BorderLayout()); - /** * Added Bibtexkey to combobox. * @@ -71,134 +66,121 @@ public TablePrefsTab(JabRefPreferences prefs) { fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - priSort = new JComboBox<>(allPlusKey); - secSort = new JComboBox<>(allPlusKey); - terSort = new JComboBox<>(allPlusKey); - - autoResizeMode = new JCheckBox(Localization.lang("Fit table horizontally on screen")); - - namesAsIs = new JRadioButton(Localization.lang("Show names unchanged")); - namesFf = new JRadioButton(Localization.lang("Show 'Firstname Lastname'")); - namesFl = new JRadioButton(Localization.lang("Show 'Lastname, Firstname'")); - namesNatbib = new JRadioButton(Localization.lang("Natbib style")); - noAbbrNames = new JRadioButton(Localization.lang("Do not abbreviate names")); - abbrNames = new JRadioButton(Localization.lang("Abbreviate names")); - lastNamesOnly = new JRadioButton(Localization.lang("Show last names only")); - - priField = new JTextField(10); - secField = new JTextField(10); - terField = new JTextField(10); - - numericFields = new JTextField(30); - - priSort.insertItemAt(Localization.lang(""), 0); - terSort.insertItemAt(Localization.lang("")); + secSort.setValue(Localization.lang("")); + + priSort.setOnAction(e -> { + if (priSort.getBaselineOffset() > 0) { + priField.setText(priSort.getItems().toString()); } }); - secSort.addActionListener(e -> { - if (secSort.getSelectedIndex() > 0) { - secField.setText(secSort.getSelectedItem().toString()); - secSort.setSelectedIndex(0); + secSort.setOnAction(e -> { + if (secSort.getBaselineOffset() > 0) { + secField.setText(secSort.getItems().toString()); } }); - terSort.addActionListener(e -> { - if (terSort.getSelectedIndex() > 0) { - terField.setText(terSort.getSelectedItem().toString()); - terSort.setSelectedIndex(0); + terSort.setOnAction(e -> { + if (terSort.getBaselineOffset() > 0) { + terField.setText(terSort.getItems().toString()); } }); - ButtonGroup nameStyle = new ButtonGroup(); - nameStyle.add(namesAsIs); - nameStyle.add(namesNatbib); - nameStyle.add(namesFf); - nameStyle.add(namesFl); - ButtonGroup nameAbbrev = new ButtonGroup(); - nameAbbrev.add(lastNamesOnly); - nameAbbrev.add(abbrNames); - nameAbbrev.add(noAbbrNames); - priDesc = new JCheckBox(Localization.lang("Descending")); - secDesc = new JCheckBox(Localization.lang("Descending")); - terDesc = new JCheckBox(Localization.lang("Descending")); - - FormLayout layout = new FormLayout( - "1dlu, 8dlu, left:pref, 4dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JLabel lab; - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Format of author and editor names")); - DefaultFormBuilder nameBuilder = new DefaultFormBuilder(new FormLayout( - "left:pref, 8dlu, left:pref", "")); - - nameBuilder.append(namesAsIs); - nameBuilder.append(noAbbrNames); - nameBuilder.nextLine(); - nameBuilder.append(namesFf); - nameBuilder.append(abbrNames); - nameBuilder.nextLine(); - nameBuilder.append(namesFl); - nameBuilder.append(lastNamesOnly); - nameBuilder.nextLine(); - nameBuilder.append(namesNatbib); - builder.append(pan); - builder.append(nameBuilder.getPanel()); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Default sort criteria")); + priDesc = new CheckBox(Localization.lang("Descending")); + priDesc.setFont(FontSize.smallFont); + secDesc = new CheckBox(Localization.lang("Descending")); + secDesc.setFont(FontSize.smallFont); + terDesc = new CheckBox(Localization.lang("Descending")); + terDesc.setFont(FontSize.smallFont); + + Label formatOfAuthor = new Label(Localization.lang("Format of author and editor names") + " ----------------------"); + formatOfAuthor.setFont(FontSize.bigFont); + builder.add(formatOfAuthor, 1, 1); + builder.add(namesAsIs, 1, 2); + builder.add(noAbbrNames, 2, 2); + builder.add(namesFf, 1, 3); + builder.add(abbrNames, 2, 3); + builder.add(namesFl, 1, 4); + builder.add(lastNamesOnly, 2, 4); + builder.add(namesNatbib, 1, 5); + + Label label1 = new Label(""); + builder.add(label1, 1, 6); + + Label defaultSortCriteria = new Label(Localization.lang("Default sort criteria") + " ----------------------------------------"); + defaultSortCriteria.setFont(FontSize.bigFont); + builder.add(defaultSortCriteria, 1, 7); // Create a new panel with its own FormLayout for these items: - FormLayout layout2 = new FormLayout( - "left:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", ""); - DefaultFormBuilder builder2 = new DefaultFormBuilder(layout2); - lab = new JLabel(Localization.lang("Primary sort criterion")); - builder2.append(lab); - builder2.append(priSort); - builder2.append(priField); - builder2.append(priDesc); - builder2.nextLine(); - lab = new JLabel(Localization.lang("Secondary sort criterion")); - builder2.append(lab); - builder2.append(secSort); - builder2.append(secField); - builder2.append(secDesc); - builder2.nextLine(); - lab = new JLabel(Localization.lang("Tertiary sort criterion")); - builder2.append(lab); - builder2.append(terSort); - builder2.append(terField); - builder2.append(terDesc); - builder.nextLine(); - builder.append(pan); - builder.append(builder2.getPanel()); - builder.nextLine(); - builder.append(pan); - builder2 = new DefaultFormBuilder(new FormLayout("left:pref, 8dlu, fill:pref", "")); - builder2.append(Localization.lang("Sort the following fields as numeric fields") + ':'); - builder2.append(numericFields); - builder.append(builder2.getPanel(), 5); - builder.nextLine(); - builder.appendSeparator(Localization.lang("General")); - builder.append(pan); - builder.append(autoResizeMode); - builder.nextLine(); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); - - namesNatbib.addChangeListener(e -> { - abbrNames.setEnabled(!namesNatbib.isSelected()); - lastNamesOnly.setEnabled(!namesNatbib.isSelected()); - noAbbrNames.setEnabled(!namesNatbib.isSelected()); + Label primarySortCriterion = new Label(Localization.lang("Primary sort criterion")); + primarySortCriterion.setFont(FontSize.smallFont); + builder.add(primarySortCriterion, 1, 8); + builder.add(priSort, 2, 8); + builder.add(priField, 3, 8); + builder.add(priDesc, 4, 8); + + Label secondarySortCriterion = new Label(Localization.lang("Secondary sort criterion")); + secondarySortCriterion.setFont(FontSize.smallFont); + builder.add(secondarySortCriterion, 1, 9); + builder.add(secSort, 2, 9); + builder.add(secField, 3, 9); + builder.add(secDesc, 4, 9); + + Label tertiarySortCriterion = new Label(Localization.lang("Tertiary sort criterion")); + tertiarySortCriterion.setFont(FontSize.smallFont); + builder.add(tertiarySortCriterion, 1, 10); + builder.add(terSort, 2, 10); + builder.add(terField, 3, 10); + builder.add(terDesc, 4, 10); + + Label sortFields = new Label(Localization.lang("Sort the following fields as numeric fields") + ':'); + sortFields.setFont(FontSize.smallFont); + builder.add(sortFields, 1, 11); + builder.add(numericFields, 2, 11); + + builder.add(new Label(""), 1, 12); + + Label general = new Label(Localization.lang("General") + " ------------------------------------------------------"); + general.setFont(FontSize.bigFont); + builder.add(general, 1, 13); + builder.add(autoResizeMode, 1, 14); + namesNatbib.setOnAction(e -> { + abbrNames.setDisable(namesNatbib.isSelected()); + lastNamesOnly.setDisable(namesNatbib.isSelected()); + noAbbrNames.setDisable(namesNatbib.isSelected()); }); } + public Node getBuilder() { + return builder; + } + @Override public void setValues() { autoResizeMode.setSelected(prefs.getBoolean(JabRefPreferences.AUTO_RESIZE_MODE)); @@ -206,9 +188,6 @@ public void setValues() { priField.setText(prefs.get(JabRefPreferences.TABLE_PRIMARY_SORT_FIELD)); secField.setText(prefs.get(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD)); terField.setText(prefs.get(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD)); - priSort.setSelectedIndex(0); - secSort.setSelectedIndex(0); - terSort.setSelectedIndex(0); if (prefs.getBoolean(JabRefPreferences.NAMES_AS_IS)) { namesAsIs.setSelected(true); @@ -230,9 +209,9 @@ public void setValues() { secDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING)); terDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING)); - abbrNames.setEnabled(!namesNatbib.isSelected()); - lastNamesOnly.setEnabled(!namesNatbib.isSelected()); - noAbbrNames.setEnabled(!namesNatbib.isSelected()); + abbrNames.setDisable(namesNatbib.isSelected()); + lastNamesOnly.setDisable(namesNatbib.isSelected()); + noAbbrNames.setDisable(namesNatbib.isSelected()); String numF = prefs.get(JabRefPreferences.NUMERIC_FIELDS); if (numF == null) { diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index aa78b4cd65b..18c1aa56d86 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -1,228 +1,141 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; -import org.jabref.gui.OSXCompatibleToolbar; -import org.jabref.gui.icon.IconTheme; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * Preference Tab for XMP. * * Allows the user to enable and configure the XMP privacy filter. */ -class XmpPrefsTab extends JPanel implements PrefsTab { - +class XmpPrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; - - private int rowCount; - - private final JTable table; - - private final JCheckBox privacyFilterCheckBox = new JCheckBox( + private final GridPane builder = new GridPane(); + private final ObservableList data = FXCollections.observableArrayList(); + private final CheckBox privacyFilterCheckBox = new CheckBox( Localization.lang("Do not write the following fields to XMP Metadata:")); - - private final List tableRows = new ArrayList<>(10); - + private final List tableRows = new ArrayList<>(10); /** * Customization of external program paths. */ public XmpPrefsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - setLayout(new BorderLayout()); - - TableModel tableModel = new AbstractTableModel() { - - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 1; - } - - @Override - public Object getValueAt(int row, int column) { - if (row >= tableRows.size()) { - return ""; - } - Object rowContent = tableRows.get(row); - if (rowContent == null) { - return ""; - } - return rowContent; - } - - @Override - public String getColumnName(int col) { - return Localization.lang("Field to filter"); - } - - @Override - public Class getColumnClass(int column) { - return String.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return true; + TableView tableView = new TableView(); + TableColumn column = new TableColumn<>(Localization.lang("Field to filter")); + column.setCellValueFactory(new PropertyValueFactory<>("name")); + column.setCellFactory(TextFieldTableCell.forTableColumn()); + column.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + column.setPrefWidth(350); + tableView.setItems(data); + tableView.getColumns().add(column); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setPrefSize(200, 30); + BorderPane tablePanel = new BorderPane(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setMaxHeight(400); + scrollPane.setMaxWidth(400); + scrollPane.setContent(tableView); + tablePanel.setCenter(scrollPane); + + Button add = new Button("Add"); + add.setPrefSize(80, 20); + add.setOnAction(e-> { + if (!addName.getText().isEmpty()) { + TableRow tableRow = new TableRow(addName.getText()); + addName.clear(); + data.add(tableRow); + tableRows.clear(); + tableRows.addAll(data); + tableView.setItems(data); + tableChanged = true; + tableView.refresh(); } - - @Override - public void setValueAt(Object value, int row, int col) { + }); + Button delete = new Button("Delete"); + delete.setPrefSize(80, 20); + delete.setOnAction(e-> { + if (tableView.getFocusModel() != null && tableView.getFocusModel().getFocusedIndex() != -1) { tableChanged = true; - - if (tableRows.size() <= row) { - ((ArrayList) tableRows).ensureCapacity(row + 1); - } - - tableRows.set(row, value); + int row = tableView.getFocusModel().getFocusedIndex(); + TableRow tableRow = data.get(row); + data.remove(tableRow); + tableRows.clear(); + tableRows.addAll(data); + tableView.setItems(data); + tableView.refresh(); } - - }; - - table = new JTable(tableModel); - - TableColumnModel columnModel = table.getColumnModel(); - columnModel.getColumn(0).setPreferredWidth(140); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - JPanel tablePanel = new JPanel(); - tablePanel.setLayout(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - table.setPreferredScrollableViewportSize(new Dimension(250, 200)); - scrollPane.setMinimumSize(new Dimension(250, 300)); - tablePanel.add(scrollPane, BorderLayout.CENTER); - - JToolBar toolbar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolbar.setFloatable(false); - toolbar.setBorder(null); - toolbar.add(new AddRowAction()); - toolbar.add(new DeleteRowAction()); - - tablePanel.add(toolbar, BorderLayout.EAST); + }); + HBox toolbar = new HBox(addName,add,delete); + tablePanel.setBottom(toolbar); // Build Prefs Tabs - builder.appendSeparator(Localization.lang("XMP export privacy settings")); - builder.nextLine(); - - builder.append(pan); - builder.append(privacyFilterCheckBox); - builder.nextLine(); + Label xmpExportPrivacySettings = new Label(Localization.lang("XMP export privacy settings") + " -------------------------"); + xmpExportPrivacySettings.setFont(FontSize.bigFont); + builder.add(xmpExportPrivacySettings, 1, 1); + privacyFilterCheckBox.setFont(FontSize.smallFont); + builder.add(privacyFilterCheckBox, 1, 2); + builder.add(tablePanel, 1, 3); - builder.append(pan); - builder.append(tablePanel); - builder.nextLine(); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); } - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } + public Node getBuilder() { + return builder; + } - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - return; - } + public static class TableRow { + private SimpleStringProperty name; - for (int i = rows.length - 1; i >= 0; i--) { - if (rows[i] < tableRows.size()) { - tableRows.remove(rows[i]); - } - } - rowCount -= rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); - tableChanged = true; + TableRow(String name) { + this.name = new SimpleStringProperty(name); } - } - - class AddRowAction extends AbstractAction { - public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); + public void setName(String name) { + this.name.set(name); } - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - table.revalidate(); - table.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if ((rows[i] + i) < tableRows.size()) { - tableRows.add(rows[i] + i, ""); - } - } - rowCount += rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); - tableChanged = true; + public String getName() { + return name.get(); } } - /** * Load settings from the preferences and initialize the table. */ @Override public void setValues() { tableRows.clear(); - List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); - tableRows.addAll(names); - rowCount = tableRows.size() + 5; - + tableRows.addAll(data); privacyFilterCheckBox.setSelected(JabRefPreferences.getInstance().getBoolean( JabRefPreferences.USE_XMP_PRIVACY_FILTER)); } @@ -234,13 +147,6 @@ public void setValues() { */ @Override public void storeSettings() { - - if (table.isEditing()) { - int col = table.getEditingColumn(); - int row = table.getEditingRow(); - table.getCellEditor(row, col).stopCellEditing(); - } - // Now we need to make sense of the contents the user has made to the // table setup table. This needs to be done either if changes were made, or // if the checkbox is checked and no field values have been stored previously: diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java index 30c1faf65d9..7f35bb9f59a 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -4,6 +4,11 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.util.DefaultTaskExecutor; @@ -16,7 +21,9 @@ public class PushToApplicationSettings { protected final JTextField path = new JTextField(30); + protected final TextField path1 = new TextField(); protected JPanel settings; + protected GridPane jfxSettings; protected FormBuilder builder; protected AbstractPushToApplication application; private DialogService dialogService; @@ -29,7 +36,23 @@ public class PushToApplicationSettings { * * @return a JPanel containing options, or null if options are not needed. */ - public JPanel getSettingsPanel() { + public JPanel getSettingsPanel(int n) { + switch (n) { + case 0: application = new PushToEmacs(dialogService); + break; + case 1: application = new PushToLyx(dialogService); + break; + case 2: application = new PushToTexmaker(dialogService); + break; + case 3: application = new PushToTeXstudio(dialogService); + break; + case 4: application = new PushToVim(dialogService); + break; + case 5: application = new PushToWinEdt(dialogService); + break; + default: application = null; + break; + } application.initParameters(); String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); if (settings == null) { @@ -39,13 +62,23 @@ public JPanel getSettingsPanel() { return settings; } + public GridPane getJFXSettingPane() { + application.initParameters(); + String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); + if (jfxSettings == null) { + initJFXSettingsPanel(); + } + path1.setText(commandPath); + return jfxSettings; + } + /** * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings */ protected void initSettingsPanel() { builder = FormBuilder.create(); builder.layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "p")); - StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName())); + StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.commandPathPreferenceKey)); // In case the application name and the actual command is not the same, add the command in brackets if (application.getCommandName() == null) { label.append(':'); @@ -66,6 +99,28 @@ protected void initSettingsPanel() { settings = builder.build(); } + protected void initJFXSettingsPanel() { + jfxSettings = new GridPane(); + StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName())); + // In case the application name and the actual command is not the same, add the command in brackets + if (application.getCommandName() == null) { + label.append(':'); + } else { + label.append(" (").append(application.getCommandName()).append("):"); + } + jfxSettings.add(new Label(label.toString()),1,1); + jfxSettings.add(path1,2, 1); + Button browse = new Button(Localization.lang("Browse")); + + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + + browse.setOnAction( + e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) + .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); + jfxSettings.add(browse,3, 1); + } + /** * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been * shown to the user and that the user has indicated that the settings should be stored. This method must store the diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java index 099956c4bed..f754941839e 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java @@ -20,9 +20,9 @@ import com.jgoodies.forms.builder.ButtonBarBuilder; public class PushToApplicationSettingsDialog { - public static void showSettingsDialog(JFrame parent, PushToApplicationSettings toApp) { + public static void showSettingsDialog(JFrame parent, PushToApplicationSettings toApp, int n) { final JDialog diag = new JDialog(parent, Localization.lang("Settings"), true); - JPanel options = toApp.getSettingsPanel(); + JPanel options = toApp.getSettingsPanel(n); options.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); diag.getContentPane().add(options, BorderLayout.CENTER); ButtonBarBuilder bb = new ButtonBarBuilder(); diff --git a/src/main/java/org/jabref/gui/push/PushToApplications.java b/src/main/java/org/jabref/gui/push/PushToApplications.java index 335123dbdb3..0fe5024dee7 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplications.java +++ b/src/main/java/org/jabref/gui/push/PushToApplications.java @@ -13,7 +13,6 @@ public PushToApplications(DialogService dialogService) { // Set up the current available choices: applications = new ArrayList<>(); - applications.add(new PushToEmacs(dialogService)); applications.add(new PushToLyx(dialogService)); applications.add(new PushToTexmaker(dialogService)); diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 3f0665b5a81..e0a44562625 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -3,6 +3,8 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -12,9 +14,15 @@ public class PushToEmacsSettings extends PushToApplicationSettings { private final JTextField additionalParams = new JTextField(30); @Override - public JPanel getSettingsPanel() { + public JPanel getSettingsPanel(int n) { + additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); + return super.getSettingsPanel(n); + } + + @Override + public GridPane getJFXSettingPane() { additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); - return super.getSettingsPanel(); + return super.getJFXSettingPane(); } @Override diff --git a/src/main/java/org/jabref/gui/push/PushToVimSettings.java b/src/main/java/org/jabref/gui/push/PushToVimSettings.java index 20fbe337729..89ceab1d37b 100644 --- a/src/main/java/org/jabref/gui/push/PushToVimSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToVimSettings.java @@ -12,9 +12,9 @@ public class PushToVimSettings extends PushToApplicationSettings { private final JTextField vimServer = new JTextField(30); @Override - public JPanel getSettingsPanel() { + public JPanel getSettingsPanel(int n) { vimServer.setText(Globals.prefs.get(JabRefPreferences.VIM_SERVER)); - return super.getSettingsPanel(); + return super.getSettingsPanel(n); } @Override diff --git a/src/main/java/org/jabref/gui/util/ThemeLoader.java b/src/main/java/org/jabref/gui/util/ThemeLoader.java index 31295289a14..87eeb0a83e9 100644 --- a/src/main/java/org/jabref/gui/util/ThemeLoader.java +++ b/src/main/java/org/jabref/gui/util/ThemeLoader.java @@ -77,7 +77,7 @@ private void addAndWatchForChanges(Scene scene, String cssUrl, int index) { DefaultTaskExecutor.runInJavaFXThread(() -> { scene.getStylesheets().remove(cssUrl); - scene.getStylesheets().add(index, cssUrl); + scene.getStylesheets().add(index, cssUrl); } ); }); diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java index 87c2ecf1dd5..e14b717dd64 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java @@ -38,7 +38,8 @@ public String format(String value) { Matcher matcher = PATTERN_URL.matcher(value); if (matcher.find()) { - toDecode = matcher.group(1); + toDecode = matcher.group(1); + } try { decodedLink = URLDecoder.decode(toDecode, StandardCharsets.UTF_8.name()); diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 52fd0017aa7..3d49f0abcb2 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -1913,5 +1913,3 @@ View\ change\ log=查看变更记录 View\ event\ log=查看事件日志 Website=网站 Write\ XMP-metadata\ to\ PDFs=将 XMP 元数据写入到 PDF 中 - -Removes\ all\ line\ breaks\ in\ the\ field\ content.=删除字段内容中所有的换行。 \ No newline at end of file diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml index 0422d0bd80d..8c6a336420a 100644 --- a/src/test/resources/log4j2-test.xml +++ b/src/test/resources/log4j2-test.xml @@ -4,7 +4,7 @@ - +