diff --git a/src/main/java/io/github/eb4j/ebview/EBViewer.java b/src/main/java/io/github/eb4j/ebview/EBViewer.java index aad7273..23bfd3e 100644 --- a/src/main/java/io/github/eb4j/ebview/EBViewer.java +++ b/src/main/java/io/github/eb4j/ebview/EBViewer.java @@ -19,6 +19,7 @@ package io.github.eb4j.ebview; import com.formdev.flatlaf.FlatLightLaf; +import io.github.eb4j.ebview.core.Core; import io.github.eb4j.ebview.dictionary.DictionariesManager; import io.github.eb4j.ebview.gui.MainWindow; import io.github.eb4j.ebview.gui.MainWindowMenu; @@ -32,29 +33,7 @@ public class EBViewer implements Runnable { - private final DictionariesManager dictionariesManager; - private final MainWindow mw; - - public EBViewer(final File dictionaryDirectory, final boolean remote) { - dictionariesManager = new DictionariesManager(); - if (dictionaryDirectory != null) { - dictionariesManager.loadDictionaries(dictionaryDirectory); - } - mw = new MainWindow(dictionariesManager); - if (!remote) { - new MainWindowMenu(this); - mw.showMessage("Please add dictionaries from Dictionary menu at first."); - } else { - mw.showMessage("Please enter search word above input box."); - } - } - - public DictionariesManager getDictionariesManager() { - return dictionariesManager; - } - - public JFrame getApplicationFrame() { - return mw.getApplicationFrame(); + public EBViewer() { } /** @@ -76,7 +55,8 @@ public static void main(final String... args) { } try { Preferences.init(); - EBViewer viewer = new EBViewer(dictionaryDirectory, remote); + Core.initializeGUI(dictionaryDirectory, remote); + EBViewer viewer = new EBViewer(); Thread t = new Thread(viewer); t.start(); } catch (Exception e) { @@ -97,6 +77,6 @@ public static void main(final String... args) { */ @Override public void run() { - mw.setVisible(true); + Core.run(); } } diff --git a/src/main/java/io/github/eb4j/ebview/core/Core.java b/src/main/java/io/github/eb4j/ebview/core/Core.java new file mode 100644 index 0000000..f60f9bd --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/core/Core.java @@ -0,0 +1,101 @@ +/* + * EBViewer, a dictionary viewer application. + * Copyright (C) 2022 Hiroshi Miura. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.eb4j.ebview.core; + +import io.github.eb4j.ebview.data.DictionaryEntry; +import io.github.eb4j.ebview.dictionary.DictionariesManager; +import io.github.eb4j.ebview.gui.IMainWindow; +import io.github.eb4j.ebview.gui.MainWindow; +import io.github.eb4j.ebview.gui.MainWindowMenu; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import java.awt.Font; +import java.io.File; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class Core { + + private static final List FONT_CHANGED_EVENT_LISTENERS = new CopyOnWriteArrayList<>(); + private static DictionariesManager dictionariesManager; + private static MainWindow mw; + + private Core() { + } + + public static void initializeGUI(final File dictionaryDirectory, final boolean remote) { + dictionariesManager = new DictionariesManager(); + mw = new MainWindow(); + if (dictionaryDirectory != null) { + dictionariesManager.loadDictionaries(dictionaryDirectory); + } + if (!remote) { + new MainWindowMenu(); + mw.showMessage("Please add dictionaries from Dictionary menu at first."); + } else { + mw.showMessage("Please enter search word above input box."); + } + } + + public static void run() { + mw.setVisible(true); + } + + public static IMainWindow getMainWindow() { + return mw; + } + public static DictionariesManager getDictionariesManager() { + return dictionariesManager; + } + + public static JFrame getApplicationFrame() { + return mw.getApplicationFrame(); + } + + /** Register listener. */ + public static void registerFontChangedEventListener(final IFontChangedListener listener) { + FONT_CHANGED_EVENT_LISTENERS.add(listener); + } + + /** Unregister listener. */ + public static void unregisterFontChangedEventListener(final IFontChangedListener listener) { + FONT_CHANGED_EVENT_LISTENERS.remove(listener); + } + + /** Fire event. */ + public static void fireFontChanged(final Font newFont) { + SwingUtilities.invokeLater(() -> { + for (IFontChangedListener listener : FONT_CHANGED_EVENT_LISTENERS) { + try { + listener.onFontChanged(newFont); + } catch (Throwable ignored) { + } + } + }); + } + + public static void updateDictionaryPane(final List entries) { + mw.updateDictionaryPane(entries); + } + + public static void moveTo(final int index) { + mw.moveTo(index); + } +} diff --git a/src/main/java/io/github/eb4j/ebview/core/IFontChangedListener.java b/src/main/java/io/github/eb4j/ebview/core/IFontChangedListener.java new file mode 100644 index 0000000..006b98b --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/core/IFontChangedListener.java @@ -0,0 +1,25 @@ +/* + * EBViewer, a dictionary viewer application. + * Copyright (C) 2022 Hiroshi Miura. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.eb4j.ebview.core; + +import java.awt.Font; + +public interface IFontChangedListener { + void onFontChanged(Font newFont); +} diff --git a/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java index 8911c82..ca037ca 100644 --- a/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java +++ b/src/main/java/io/github/eb4j/ebview/dictionary/oxford/OxfordDriver.java @@ -1,3 +1,21 @@ +/* + * EBViewer, a dictionary viewer application. + * Copyright (C) 2021-2022 Hiroshi Miura. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package io.github.eb4j.ebview.dictionary.oxford; import io.github.eb4j.ebview.data.DictionaryEntry; diff --git a/src/main/java/io/github/eb4j/ebview/gui/DictionaryPane.java b/src/main/java/io/github/eb4j/ebview/gui/DictionaryPane.java index 5f84f96..4841ab5 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/DictionaryPane.java +++ b/src/main/java/io/github/eb4j/ebview/gui/DictionaryPane.java @@ -1,5 +1,6 @@ package io.github.eb4j.ebview.gui; +import io.github.eb4j.ebview.core.Core; import io.github.eb4j.ebview.data.DictionaryEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,17 +40,12 @@ public class DictionaryPane extends JTextPane implements IThreadPane { private final HTMLEditorKit htmlEditorKit = new HTMLEditorKit(); - private StyleSheet baseStyleSheet; - private int zoomLevel = 0; - - public DictionaryPane() { + public DictionaryPane(final Font font) { super(); setContentType("text/html"); ((HTMLDocument) getDocument()).setPreservesUnknownTags(false); - setFont(getFont()); - setStyle(); - htmlEditorKit.setStyleSheet(baseStyleSheet); - setEditorKit(htmlEditorKit); + setFont(font); + Core.registerFontChangedEventListener(this::setFont); FocusListener listener = new FocusAdapter() { @Override public void focusGained(final FocusEvent e) { @@ -70,58 +66,27 @@ public void setFont(final Font font) { Map attributes = font.getAttributes(); attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON); super.setFont(font.deriveFont(attributes)); - Document doc = getDocument(); - if (!(doc instanceof HTMLDocument)) { - return; + if (htmlEditorKit != null) { + setStyle(); } } @SuppressWarnings({"avoidinlineconditionals"}) private void setStyle() { Font font = getFont(); - baseStyleSheet = new StyleSheet(); + StyleSheet baseStyleSheet = new StyleSheet(); baseStyleSheet.addRule("body { font-family: " + font.getName() + "; " + " font-size: " + font.getSize() + "; " + " font-style: " + (font.getStyle() == Font.BOLD ? "bold" : font.getStyle() == Font.ITALIC ? "italic" : "normal") + "; " + " color: " + toHex(UIManager.getColor("TextPane.foreground")) + "; " + " background: " + toHex(UIManager.getColor("TextPane.background")) + "; } " - + ".word {font-size: " + (zoomLevel + 2 + font.getSize()) + "; font-style: bold; }" - + ".article {font-size: " + (zoomLevel + font.getSize()) + "; }" + + ".word {font-size: " + (2 + font.getSize()) + "; font-style: bold; }" + + ".article {font-size: " + (font.getSize()) + "; }" + ".reference { font-style: italic; }" ); htmlEditorKit.setStyleSheet(baseStyleSheet); - } - - private void limitZoom() { - int size = getFont().getSize(); - if (size + zoomLevel > 64) { - zoomLevel = 64 - size; - return; - } - if (size + zoomLevel < 6) { - zoomLevel = size - 6; - } - } - - public void increaseZoom() { - zoomLevel++; - limitZoom(); - setStyle(); - } - - public void decreaseZoom() { - zoomLevel--; - limitZoom(); - setStyle(); - } - - public String getZoomLevel() { - if (zoomLevel > 0) { - return "+" + zoomLevel; - } else { - return String.valueOf(zoomLevel); - } + setEditorKit(htmlEditorKit); } @Override diff --git a/src/main/java/io/github/eb4j/ebview/gui/EBViewerModel.java b/src/main/java/io/github/eb4j/ebview/gui/EBViewerModel.java index ddc90ce..30b4498 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/EBViewerModel.java +++ b/src/main/java/io/github/eb4j/ebview/gui/EBViewerModel.java @@ -18,6 +18,7 @@ package io.github.eb4j.ebview.gui; +import io.github.eb4j.ebview.core.Core; import io.github.eb4j.ebview.data.DictionaryEntry; import javax.swing.DefaultListModel; @@ -113,7 +114,7 @@ public void updateResult() { } } updateHeadingsModel(wordList); - MainWindow.updateDictionaryPane(entries); + Core.updateDictionaryPane(entries); } } diff --git a/src/main/java/io/github/eb4j/ebview/gui/IMainWindow.java b/src/main/java/io/github/eb4j/ebview/gui/IMainWindow.java index 3d2d61c..cf262fe 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/IMainWindow.java +++ b/src/main/java/io/github/eb4j/ebview/gui/IMainWindow.java @@ -3,10 +3,12 @@ import io.github.eb4j.ebview.dictionary.DictionariesManager; import javax.swing.JFrame; +import java.awt.Font; public interface IMainWindow { - - DictionariesManager getDictionariesManager(); + void showMessage(String msg); JFrame getApplicationFrame(); + + Font getApplicationFont(); } diff --git a/src/main/java/io/github/eb4j/ebview/gui/MainWindow.java b/src/main/java/io/github/eb4j/ebview/gui/MainWindow.java index 53436a2..ebe5ed6 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/MainWindow.java +++ b/src/main/java/io/github/eb4j/ebview/gui/MainWindow.java @@ -18,8 +18,9 @@ package io.github.eb4j.ebview.gui; +import io.github.eb4j.ebview.core.Core; import io.github.eb4j.ebview.data.DictionaryEntry; -import io.github.eb4j.ebview.dictionary.DictionariesManager; +import io.github.eb4j.ebview.utils.Preferences; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -32,10 +33,10 @@ import javax.swing.ScrollPaneConstants; import javax.swing.WindowConstants; import javax.swing.border.TitledBorder; -import javax.swing.plaf.basic.BasicArrowButton; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Font; import java.awt.Image; import java.awt.SystemTray; import java.awt.Window; @@ -55,28 +56,34 @@ */ public final class MainWindow extends JFrame implements IMainWindow { private final JButton searchButton = new JButton(); - private final BasicArrowButton zoomUpButton = new BasicArrowButton(BasicArrowButton.NORTH); - private final BasicArrowButton zoomDownButton = new BasicArrowButton(BasicArrowButton.SOUTH); - private final DictionariesManager dictionariesManager; private final EBViewerModel ebViewerModel; private static JList dictionaryInfoList; - private static final DictionaryPane DICTIONARY_PANE = new DictionaryPane(); private static final JTextField SEARCH_WORD_FIELD = new JTextField(); - private JLabel zoomLevel; + private final DictionaryPane dictionaryPane; + private JLabel selectAllDictionary; private JList headingsList; private JList history; - public MainWindow(final DictionariesManager dictionariesManager) { + private final Font font; + + public MainWindow() { super("EBViewer"); - this.dictionariesManager = dictionariesManager; ebViewerModel = new EBViewerModel(); + String fontName = Preferences.getPreferenceDefault(Preferences.APPEARANCE_FONT_NAME, + Preferences.APPEARANCE_FONT_DEFAULT); + int fontSize = Preferences.getPreferenceDefault(Preferences.APPEARANCE_FONT_SIZE, + Preferences.APPEARANCE_FONT_SIZE_DEFAULT); + font = new Font(fontName, Font.PLAIN, fontSize); + setFont(font); setWindowIcon(this); + dictionaryPane = new DictionaryPane(font); initializeGUI(); + Core.registerFontChangedEventListener(this::setFont); setActions(); pack(); setResizable(true); @@ -88,28 +95,18 @@ public static void setWindowIcon(final Window window) { window.setIconImages(icons); } - public static String getSearchWord() { return SEARCH_WORD_FIELD.getText(); } - public static void setMessage(final String message) { - DICTIONARY_PANE.setText(message); - } - - @Override - public DictionariesManager getDictionariesManager() { - return dictionariesManager; - } - @Override public JFrame getApplicationFrame() { return this; } - public static void updateDictionaryPane(final List entries) { - DICTIONARY_PANE.setFoundResult(entries); - DICTIONARY_PANE.setCaretPosition(0); + @Override + public Font getApplicationFont() { + return font; } public static void updateDictionaryList(final int[] indecs) { @@ -127,24 +124,17 @@ private void initializeGUI() { // // GUI parts JPanel panel1 = new JPanel(); - JLabel zoomLabel = new JLabel("zoom:"); - zoomLevel = new JLabel(); - zoomLevel.setText(DICTIONARY_PANE.getZoomLevel()); panel1.setLayout(new FlowLayout()); SEARCH_WORD_FIELD.setPreferredSize(new Dimension(500, 30)); searchButton.setText("Search"); panel1.add(SEARCH_WORD_FIELD); panel1.add(searchButton); - panel1.add(zoomLabel); - panel1.add(zoomDownButton); - panel1.add(zoomLevel); - panel1.add(zoomUpButton); // headingsList = new JList<>(ebViewerModel.getHeadingsModel()); JScrollPane headingsPane = new JScrollPane(headingsList); headingsPane.setPreferredSize(new Dimension(140, -1)); // - JScrollPane articlePane = new JScrollPane(DICTIONARY_PANE); + JScrollPane articlePane = new JScrollPane(dictionaryPane); articlePane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); // JPanel infoPanel = new JPanel(); @@ -173,11 +163,11 @@ private void initializeGUI() { } public void showMessage(final String msg) { - DICTIONARY_PANE.setText(msg); + dictionaryPane.setText(msg); } private void startSearch() { - Searcher searchSwingWorker = new Searcher(ebViewerModel, dictionariesManager); + Searcher searchSwingWorker = new Searcher(ebViewerModel, Core.getDictionariesManager()); searchSwingWorker.execute(); } @@ -190,16 +180,6 @@ private void setActions() { startSearch(); }); - zoomDownButton.addActionListener(e -> { - DICTIONARY_PANE.decreaseZoom(); - zoomLevel.setText(DICTIONARY_PANE.getZoomLevel()); - }); - - zoomUpButton.addActionListener(e -> { - DICTIONARY_PANE.increaseZoom(); - zoomLevel.setText(DICTIONARY_PANE.getZoomLevel()); - }); - headingsList.addListSelectionListener(e -> { if (e.getValueIsAdjusting()) { return; @@ -208,7 +188,7 @@ private void setActions() { if (index == -1) { return; } - DICTIONARY_PANE.moveTo(index); + Core.moveTo(index); headingsList.clearSelection(); }); @@ -265,4 +245,13 @@ public void mouseClicked(final MouseEvent e) { } }); } + + public void updateDictionaryPane(final List entries) { + dictionaryPane.setFoundResult(entries); + dictionaryPane.setCaretPosition(0); + } + + public void moveTo(final int index) { + dictionaryPane.moveTo(index); + } } diff --git a/src/main/java/io/github/eb4j/ebview/gui/MainWindowMenu.java b/src/main/java/io/github/eb4j/ebview/gui/MainWindowMenu.java index dfae9fb..b0bf1fe 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/MainWindowMenu.java +++ b/src/main/java/io/github/eb4j/ebview/gui/MainWindowMenu.java @@ -19,6 +19,7 @@ package io.github.eb4j.ebview.gui; import io.github.eb4j.ebview.EBViewer; +import io.github.eb4j.ebview.core.Core; import io.github.eb4j.ebview.dictionary.DictionariesManager; import io.github.eb4j.ebview.gui.dialogs.AboutDialog; import io.github.eb4j.ebview.gui.preferences.PreferenceController; @@ -51,9 +52,9 @@ public class MainWindowMenu implements ActionListener, MenuListener { private final DictionariesManager manager; private final TrayIcon trayIcon; - public MainWindowMenu(final EBViewer ebViewer) { - app = ebViewer.getApplicationFrame(); - manager = ebViewer.getDictionariesManager(); + public MainWindowMenu() { + app = Core.getApplicationFrame(); + manager = Core.getDictionariesManager(); trayIcon = new TrayIcon(APP_ICON_32X32, "EBViewer", null); initMenuComponents(); initTray(); @@ -96,7 +97,7 @@ public void openActionPerformed() { sb.append("
  • ").append(dict).append("
  • "); } sb.append(""); - MainWindow.setMessage(sb.toString()); + Core.getMainWindow().showMessage(sb.toString()); } public void closeActionPerformed() { diff --git a/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearanceController.java b/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearanceController.java new file mode 100644 index 0000000..0c87797 --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearanceController.java @@ -0,0 +1,86 @@ +/* + * EBViewer, a dictionary viewer application. + * Copyright (C) 2022 Hiroshi Miura. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.eb4j.ebview.gui.preferences; + +import io.github.eb4j.ebview.utils.Preferences; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComponent; +import java.awt.Font; +import java.awt.GraphicsEnvironment; + +public class AppearanceController implements IPreferencesController { + + private AppearancePanel panel; + + public AppearanceController() { + } + + public JComponent getGui() { + if (panel == null) { + panel = new AppearancePanel(); + panel.fontComboBox.setModel(new DefaultComboBoxModel<>(getFontNames())); + panel.fontComboBox.addActionListener(e -> panel.previewTextArea.setFont(getSelectedFont())); + panel.sizeSpinner.addChangeListener(e -> panel.previewTextArea.setFont(getSelectedFont())); + initFromPrefs(); + } + return panel; + } + + private void initFromPrefs() { + panel.condensedModeCB.setSelected(Preferences.isPreferenceDefault(Preferences.APPEARANCE_CONDENSED_VIEW, false)); + String fontName = Preferences.getPreferenceDefault(Preferences.APPEARANCE_FONT_NAME, Preferences.APPEARANCE_FONT_DEFAULT); + int fontSize = Preferences.getPreferenceDefault(Preferences.APPEARANCE_FONT_SIZE, Preferences.APPEARANCE_FONT_SIZE_DEFAULT); + Font oldFont = new Font(fontName, Font.PLAIN, fontSize); + panel.previewTextArea.setFont(oldFont); + panel.fontComboBox.setSelectedItem(oldFont.getName()); + panel.sizeSpinner.setValue(oldFont.getSize()); + } + + public void persist() { + Font newFont = getSelectedFont(); + Preferences.setPreference(Preferences.APPEARANCE_CONDENSED_VIEW, panel.condensedModeCB.isSelected()); + Preferences.setPreference(Preferences.APPEARANCE_FONT_NAME, newFont.getName()); + Preferences.setPreference(Preferences.APPEARANCE_FONT_SIZE, newFont.getSize()); + } + + /** + * Restore preferences controlled by this view to their current persisted + * state. + */ + @Override + public void undoChanges() { + initFromPrefs(); + } + + public void restoreDefaults() { + panel.condensedModeCB.setSelected(false); + } + + private Font getSelectedFont() { + return new Font((String) panel.fontComboBox.getSelectedItem(), Font.PLAIN, + ((Number) panel.sizeSpinner.getValue()).intValue()); + } + + private static String[] getFontNames() { + GraphicsEnvironment graphics; + graphics = GraphicsEnvironment.getLocalGraphicsEnvironment(); + return graphics.getAvailableFontFamilyNames(); + } +} diff --git a/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearancePanel.java b/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearancePanel.java new file mode 100644 index 0000000..8b17dca --- /dev/null +++ b/src/main/java/io/github/eb4j/ebview/gui/preferences/AppearancePanel.java @@ -0,0 +1,129 @@ +/* + * EBViewer, a dictionary viewer application. + * Copyright (C) 2022 Hiroshi Miura. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.eb4j.ebview.gui.preferences; + +import io.github.eb4j.ebview.utils.LStrings; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.JTextArea; +import javax.swing.border.TitledBorder; +import java.awt.GridBagConstraints; + +public class AppearancePanel extends JPanel { + + public AppearancePanel() { + initComponents(); + } + + private void initComponents() { + GridBagConstraints gridBagConstraints; + JLabel desc = new JLabel(); + desc.setText(LStrings.getString("PREFS_APPEARANCE_DESC")); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(desc, gridBagConstraints); + + condensedModeCB = new JCheckBox(); + condensedModeCB.setText(LStrings.getString("PREFS_APPEARANCE_CONDENSED_MODE")); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(condensedModeCB, gridBagConstraints); + + fontComboBox = new javax.swing.JComboBox<>(); + JLabel fontLabel = new JLabel(); + sizeSpinner = new javax.swing.JSpinner(); + JLabel sizeLabel = new JLabel(); + previewTextArea = new javax.swing.JTextArea(); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + setLayout(new java.awt.GridBagLayout()); + + fontComboBox.setMaximumRowCount(20); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(fontComboBox, gridBagConstraints); + + fontLabel.setText(LStrings.getString("PREFS_SELECT_FONT")); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(fontLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(sizeSpinner, gridBagConstraints); + sizeLabel.setText(LStrings.getString("PREFS_SELECT_FONTSIZE")); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); + add(sizeLabel, gridBagConstraints); + + previewTextArea.setEditable(false); + previewTextArea.setLineWrap(true); + previewTextArea.setText(LStrings.getString("PREFS_FONT_SAMPLE_TEXT")); // NOI18N + previewTextArea.setWrapStyleWord(true); + previewTextArea.setBorder(BorderFactory.createTitledBorder( + null, + LStrings.getString("PREFS_FONT_SAMPLE_TITLE"), + TitledBorder.DEFAULT_JUSTIFICATION, + TitledBorder.DEFAULT_POSITION, + fontLabel.getFont())); + previewTextArea.setOpaque(false); + previewTextArea.setPreferredSize(new java.awt.Dimension(116, 100)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + add(previewTextArea, gridBagConstraints); + + } + + JCheckBox condensedModeCB; + JComboBox fontComboBox; + JTextArea previewTextArea; + JSpinner sizeSpinner; +} diff --git a/src/main/java/io/github/eb4j/ebview/gui/preferences/PreferenceController.java b/src/main/java/io/github/eb4j/ebview/gui/preferences/PreferenceController.java index fbd4add..e9bc792 100644 --- a/src/main/java/io/github/eb4j/ebview/gui/preferences/PreferenceController.java +++ b/src/main/java/io/github/eb4j/ebview/gui/preferences/PreferenceController.java @@ -27,11 +27,13 @@ import javax.swing.border.LineBorder; import java.awt.Color; import java.awt.Window; +import java.util.HashSet; +import java.util.Set; public class PreferenceController { - private IPreferencesController secureStoreController; - private IPreferencesController oxfordApiController; + private final Set controllers = new HashSet<>(); + private JTabbedPane tabbedPane; public void show(final Window parent) { JDialog dialog = new JDialog(parent); @@ -41,17 +43,15 @@ public void show(final Window parent) { StaticUIUtils.setEscapeClosable(dialog); PreferencePanel preferencePanel = new PreferencePanel(); - JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane = new JTabbedPane(); tabbedPane.setBorder(new LineBorder(Color.DARK_GRAY)); - secureStoreController = new SecureStoreController(); - oxfordApiController = new OxfordApiController(); - tabbedPane.addTab("Oxford dictionaries", oxfordApiController.getGui()); - tabbedPane.addTab("Credentials", secureStoreController.getGui()); + addPanel("Appearance", new AppearanceController()); + addPanel("Oxford Dictionaries", new OxfordApiController()); + addPanel("Credentials", new SecureStoreController()); preferencePanel.prefsPanel.add(tabbedPane); preferencePanel.okButton.addActionListener(e -> { - secureStoreController.persist(); - oxfordApiController.persist(); + controllers.forEach(IPreferencesController::persist); Preferences.save(); StaticUIUtils.closeWindowByEvent(dialog); }); @@ -63,4 +63,9 @@ public void show(final Window parent) { dialog.setVisible(true); } + private void addPanel(final String title, final IPreferencesController controller) { + tabbedPane.addTab(title, controller.getGui()); + controllers.add(controller); + } + } diff --git a/src/main/java/io/github/eb4j/ebview/utils/Preferences.java b/src/main/java/io/github/eb4j/ebview/utils/Preferences.java index 444d406..f5d9920 100644 --- a/src/main/java/io/github/eb4j/ebview/utils/Preferences.java +++ b/src/main/java/io/github/eb4j/ebview/utils/Preferences.java @@ -36,6 +36,19 @@ public final class Preferences { public static final String FILE_PREFERENCES = "ebviewer.prefs"; + public static final String APPEARANCE_CONDENSED_VIEW = "appearance.condensed.view"; + public static final String APPEARANCE_FONT_NAME = "appearance.font.name"; + public static final String APPEARANCE_FONT_DEFAULT = "dialog"; + public static final String APPEARANCE_FONT_SIZE = "appearance.font.size"; + public static final int APPEARANCE_FONT_SIZE_DEFAULT = 12; + + /** + * Contains the location of the directory containing the configuration + * files. + */ + private static String configDir = null; + + /** Private constructor, because this file is singleton */ private Preferences() { } @@ -64,7 +77,7 @@ public > T getPreferenceEnumDefault(final String key, final T return preferences.getPreferenceEnumDefault(key, defaultValue); } - public int getPreferenceDefault(final String key, final int defaultValue) { + public static int getPreferenceDefault(final String key, final int defaultValue) { return preferences.getPreferenceDefault(key, defaultValue); } diff --git a/src/main/java/io/github/eb4j/ebview/utils/Stemmer.java b/src/main/java/io/github/eb4j/ebview/utils/Stemmer.java index fa694e5..4bc3d3d 100644 --- a/src/main/java/io/github/eb4j/ebview/utils/Stemmer.java +++ b/src/main/java/io/github/eb4j/ebview/utils/Stemmer.java @@ -53,9 +53,6 @@ public String[] doStem(final String str) { } private static String[] tokenizeTextToStringsNoCache(final String str) { - if (StringUtils.isBlank(str)) { - return EMPTY_STRINGS_LIST; - } // create a new token list List tokens = new ArrayList<>(64); // get a word breaker @@ -76,7 +73,7 @@ private static String[] tokenizeTextToStringsNoCache(final String str) { tokens.add(tokenStr); } } - return tokens.toArray(new String[tokens.size()]); + return tokens.toArray(new String[0]); } } diff --git a/src/main/resources/Bundle.properties b/src/main/resources/Bundle.properties index e0cf87d..9240e3a 100644 --- a/src/main/resources/Bundle.properties +++ b/src/main/resources/Bundle.properties @@ -26,6 +26,12 @@ BUTTON_OK=Ok BUTTON_CANCEL=Cancel PASSWORD_ENTER_MESSAGE=Enter password PASSWORD_TRY_AGAIN_MESSAGE=Try password again +PREFS_APPEARANCE_DESC=Appearance configuration +PREFS_APPEARANCE_CONDENSED_MODE=Condensed view mode +PREFS_SELECT_FONT=Select font +PREFS_SELECT_FONTSIZE=Select font size +PREFS_FONT_SAMPLE_TITLE=Sample text +PREFS_FONT_SAMPLE_TEXT=The quick brown fox jumps over the lazy dog. 1234567890 PREFS_OXFORD_DESC=Please set appId and appKey of Oxford dictionaries API. PREFS_OXFORD_APPID_LABEL=Application ID : PREFS_OXFORD_APPKEY_LABEL=Applicaiton Key: