diff --git a/src/main/java/com/itextpdf/rups/Rups.java b/src/main/java/com/itextpdf/rups/Rups.java index ba1bc3c7..0e22c4af 100644 --- a/src/main/java/com/itextpdf/rups/Rups.java +++ b/src/main/java/com/itextpdf/rups/Rups.java @@ -46,10 +46,7 @@ This file is part of the iText (R) project. import com.itextpdf.rups.controller.IRupsController; import com.itextpdf.rups.controller.RupsController; import com.itextpdf.rups.model.LoggerHelper; -import com.itextpdf.rups.view.Language; -import com.itextpdf.rups.view.RupsDropTarget; -import com.itextpdf.rups.view.RupsMenuBar; -import com.itextpdf.rups.view.RupsTabbedPane; +import com.itextpdf.rups.view.*; import com.itextpdf.rups.view.icons.FrameIconUtil; import java.awt.BorderLayout; @@ -87,7 +84,7 @@ static void setLookandFeel() { UIManager.setLookAndFeel(RupsConfiguration.INSTANCE.getLookAndFeel()); } catch ( ClassNotFoundException | InstantiationException | - IllegalAccessException | UnsupportedLookAndFeelException e) { + IllegalAccessException | UnsupportedLookAndFeelException e) { LoggerHelper.error(Language.ERROR_LOOK_AND_FEEL.getString(), e, Rups.class); } } @@ -100,21 +97,27 @@ static IRupsController initApplication(JFrame frame) { // title bar frame.setTitle( - String.format(Language.TITLE.getString(), ITextCoreProductData.getInstance().getVersion())); + String.format(Language.TITLE.getString(), ITextCoreProductData.getInstance().getVersion()) + ); frame.setIconImages(FrameIconUtil.loadFrameIcons()); frame.setDefaultCloseOperation(RupsConfiguration.INSTANCE.getCloseOperation()); final RupsTabbedPane rupsTabbedPane = new RupsTabbedPane(); final RupsController rupsController = new RupsController(screen, rupsTabbedPane); - final RupsMenuBar rupsMenuBar = new RupsMenuBar(rupsController); - rupsController.addObserver(rupsMenuBar); + configureMenuBar(rupsController, frame); frame.setDropTarget(new RupsDropTarget(rupsController)); - frame.setJMenuBar(rupsMenuBar); frame.getContentPane().add(rupsController.getMasterComponent(), BorderLayout.CENTER); frame.setVisible(true); return rupsController; } + + private static void configureMenuBar(final RupsController rupsController, JFrame frame) { + final RupsMenuBar rupsMenuBar = new RupsMenuBar(rupsController); + final RupsMenuBarChangeListener rupsMenuBarChangeListener = new RupsMenuBarChangeListener(rupsMenuBar); + rupsController.addPropertyChangeListener(rupsMenuBarChangeListener); + frame.setJMenuBar(rupsMenuBar); + } } diff --git a/src/main/java/com/itextpdf/rups/controller/RupsController.java b/src/main/java/com/itextpdf/rups/controller/RupsController.java index 6eddea41..9b881208 100644 --- a/src/main/java/com/itextpdf/rups/controller/RupsController.java +++ b/src/main/java/com/itextpdf/rups/controller/RupsController.java @@ -51,8 +51,11 @@ This file is part of the iText (R) project. import com.itextpdf.rups.view.Language; import com.itextpdf.rups.view.RupsTabbedPane; +import javax.swing.event.SwingPropertyChangeSupport; import java.awt.Component; import java.awt.Dimension; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.io.File; import java.util.Observable; import java.util.Observer; @@ -62,12 +65,14 @@ This file is part of the iText (R) project. * the RUPS application: the menu bar, the panels,... */ public class RupsController extends Observable - implements Observer, IRupsController { + implements IRupsController { private final RupsTabbedPane rupsTabbedPane; private final Dimension dimension; + private final PropertyChangeSupport propertyChangeSupport; + /** * Constructs the GUI components of the RUPS application. * @@ -78,6 +83,8 @@ public RupsController(Dimension dimension, RupsTabbedPane rupsTabbedPane) { this.rupsTabbedPane = rupsTabbedPane; this.dimension = dimension; + + this.propertyChangeSupport = new SwingPropertyChangeSupport(this); } /** @@ -90,43 +97,24 @@ public Component getMasterComponent() { return rupsTabbedPane.getJTabbedPane(); } - @Override - public final void update(Observable o, Object arg) { - //Events that have come from non observable classes: ObjectLoader and FileChooserAction - if (o == null && arg instanceof RupsEvent) { - RupsEvent event = (RupsEvent) arg; - switch (event.getType()) { - case RupsEvent.CLOSE_DOCUMENT_EVENT: - this.closeCurrentFile(); - break; - case RupsEvent.OPEN_FILE_EVENT: - this.openNewFile((File) event.getContent()); - break; - case RupsEvent.COMPARE_WITH_FILE_EVENT: - break; - case RupsEvent.SAVE_TO_FILE_EVENT: - this.rupsTabbedPane.saveCurrentFile((File) event.getContent()); - break; - case RupsEvent.OPEN_DOCUMENT_POST_EVENT: - default: - setChanged(); - super.notifyObservers(event); - break; - } - } else { - setChanged(); - super.notifyObservers(arg); - } + public final void update(Object arg) { + setChanged(); + super.notifyObservers(arg); } @Override public final void closeCurrentFile() { + PdfFile lastFile = this.rupsTabbedPane.getCurrentFile(); final boolean lastOne = this.rupsTabbedPane.closeCurrentFile(); if (lastOne) { - this.update(this, new AllFilesClosedEvent()); + this.propertyChangeSupport.firePropertyChange("ALL_FILES_CLOSED", lastFile, null); } } + public final void saveCurrentFile(File saveLocation) { + this.rupsTabbedPane.saveCurrentFile(saveLocation); + } + @Override public final PdfFile getCurrentFile() { return this.rupsTabbedPane.getCurrentFile(); @@ -141,7 +129,16 @@ public final void openNewFile(File file) { } this.rupsTabbedPane.openNewFile(file, this.dimension, false); - this.update(this, new OpenFileEvent(file)); + this.propertyChangeSupport.firePropertyChange("FILE_OPEN", null, file); + this.propertyChangeSupport.firePropertyChange("FILE_LOADED", null, file); } } + + public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) { + this.propertyChangeSupport.addPropertyChangeListener(propertyChangeListener); + } + + public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) { + this.propertyChangeSupport.removePropertyChangeListener(propertyChangeListener); + } } diff --git a/src/main/java/com/itextpdf/rups/controller/RupsInstanceController.java b/src/main/java/com/itextpdf/rups/controller/RupsInstanceController.java index 410f9f27..ceb2bc43 100644 --- a/src/main/java/com/itextpdf/rups/controller/RupsInstanceController.java +++ b/src/main/java/com/itextpdf/rups/controller/RupsInstanceController.java @@ -345,7 +345,7 @@ public void run() { } }); loader = new ObjectLoader(this, pdfFile, pdfFile.getFilename(), dialog); - loader.start(); + loader.execute(); } // tree selection diff --git a/src/main/java/com/itextpdf/rups/io/FileChooserAction.java b/src/main/java/com/itextpdf/rups/io/FileChooserAction.java index 7c5ef6af..f297d151 100644 --- a/src/main/java/com/itextpdf/rups/io/FileChooserAction.java +++ b/src/main/java/com/itextpdf/rups/io/FileChooserAction.java @@ -59,10 +59,6 @@ This file is part of the iText (R) project. */ public abstract class FileChooserAction extends AbstractAction { - /** - * An object that is expecting the result of the file chooser action. - */ - protected Observer observer; /** * A file filter to apply when browsing for a file. */ @@ -83,14 +79,12 @@ public abstract class FileChooserAction extends AbstractAction { /** * Creates a new file chooser action. * - * @param observer the object waiting for you to select file * @param caption a description for the action * @param filter a filter to apply when browsing * @param parent a parent Component for chooser dialog */ - public FileChooserAction(Observer observer, String caption, FileFilter filter, Component parent) { + public FileChooserAction(String caption, FileFilter filter, Component parent) { super(caption); - this.observer = observer; this.filter = filter; this.parent = parent; } @@ -119,11 +113,12 @@ public void actionPerformed(ActionEvent evt) { if (okCancel == JFileChooser.APPROVE_OPTION) { file = fileChooser.getSelectedFile(); lastSelectedFolder = fileChooser.getCurrentDirectory(); - observer.update(null, getEvent()); +// observer.update(null, getEvent()); + firePropertyChange(getEvent(), null, getFile()); } } protected abstract int showDialog(); - protected abstract RupsEvent getEvent(); + protected abstract String getEvent(); } diff --git a/src/main/java/com/itextpdf/rups/io/FileCloseAction.java b/src/main/java/com/itextpdf/rups/io/FileCloseAction.java index 1ed86390..f0fd8afb 100644 --- a/src/main/java/com/itextpdf/rups/io/FileCloseAction.java +++ b/src/main/java/com/itextpdf/rups/io/FileCloseAction.java @@ -44,6 +44,7 @@ This file is part of the iText (R) project. import com.itextpdf.rups.event.CloseDocumentEvent; +import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Observer; @@ -52,27 +53,11 @@ This file is part of the iText (R) project. * Action that tells an observer to close a file and/or releases * resources relevant for the file that is being closed. */ -public class FileCloseAction implements ActionListener { +public class FileCloseAction extends AbstractAction { - /** - * An object that allows you to close a file. - */ - protected Observer observer; - - /** - * Creates the close action. - * - * @param observer the object that expects you to close a file. - */ - public FileCloseAction(Observer observer) { - this.observer = observer; - } - - /** - * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) - */ + @Override public void actionPerformed(ActionEvent evt) { - observer.update(null, new CloseDocumentEvent()); + firePropertyChange("FILE_CLOSE", null, null); } } diff --git a/src/main/java/com/itextpdf/rups/io/FileCompareAction.java b/src/main/java/com/itextpdf/rups/io/FileCompareAction.java index 3a14469a..a0734deb 100644 --- a/src/main/java/com/itextpdf/rups/io/FileCompareAction.java +++ b/src/main/java/com/itextpdf/rups/io/FileCompareAction.java @@ -56,12 +56,11 @@ public class FileCompareAction extends FileChooserAction { /** * Creates a new file chooser action. * - * @param observer the object waiting for you to select file * @param filter a filter to apply when browsing * @param parent a parent Component for chooser dialog */ - public FileCompareAction(Observer observer, FileFilter filter, Component parent) { - super(observer, Language.COMPARE_WITH.getString(), filter, parent); + public FileCompareAction(FileFilter filter, Component parent) { + super(Language.COMPARE_WITH.getString(), filter, parent); } @Override @@ -70,7 +69,7 @@ protected int showDialog() { } @Override - protected RupsEvent getEvent() { - return new CompareWithFileEvent(getFile()); + protected String getEvent() { + return "FILE_COMPARE"; } } diff --git a/src/main/java/com/itextpdf/rups/io/FileOpenAction.java b/src/main/java/com/itextpdf/rups/io/FileOpenAction.java index 2c7da005..c885b81b 100644 --- a/src/main/java/com/itextpdf/rups/io/FileOpenAction.java +++ b/src/main/java/com/itextpdf/rups/io/FileOpenAction.java @@ -54,12 +54,11 @@ public class FileOpenAction extends FileChooserAction { /** * Creates a new file chooser action. * - * @param observer the object waiting for you to select file * @param filter a filter to apply when browsing * @param parent a parent Component for chooser dialog */ - public FileOpenAction(Observer observer, FileFilter filter, Component parent) { - super(observer, Language.OPEN.getString(), filter, parent); + public FileOpenAction(FileFilter filter, Component parent) { + super(Language.OPEN.getString(), filter, parent); } @Override @@ -68,7 +67,7 @@ protected int showDialog() { } @Override - protected RupsEvent getEvent() { - return new OpenFileEvent(getFile()); + protected String getEvent() { + return "FILE_OPEN"; } } diff --git a/src/main/java/com/itextpdf/rups/io/FileSaveAction.java b/src/main/java/com/itextpdf/rups/io/FileSaveAction.java index 18d1c598..862456f3 100644 --- a/src/main/java/com/itextpdf/rups/io/FileSaveAction.java +++ b/src/main/java/com/itextpdf/rups/io/FileSaveAction.java @@ -55,12 +55,11 @@ public class FileSaveAction extends FileChooserAction { /** * Creates a new file chooser action. * - * @param observer the object waiting for you to select file * @param filter a filter to apply when browsing * @param parent a parent Component for chooser dialog */ - public FileSaveAction(Observer observer, FileFilter filter, Component parent) { - super(observer, Language.MENU_BAR_SAVE_AS.getString(), filter, parent); + public FileSaveAction(FileFilter filter, Component parent) { + super(Language.MENU_BAR_SAVE_AS.getString(), filter, parent); } @Override @@ -69,7 +68,7 @@ protected int showDialog() { } @Override - protected RupsEvent getEvent() { - return new SaveToFileEvent(getFile()); + protected String getEvent() { + return "FILE_SAVED"; } } diff --git a/src/main/java/com/itextpdf/rups/model/BackgroundTask.java b/src/main/java/com/itextpdf/rups/model/BackgroundTask.java deleted file mode 100644 index 06f2c7b1..00000000 --- a/src/main/java/com/itextpdf/rups/model/BackgroundTask.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - This file is part of the iText (R) project. - Copyright (c) 1998-2023 Apryse Group NV - Authors: Apryse Software. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation with the addition of the - following permission added to Section 15 as permitted in Section 7(a): - FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY - APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT - OF THIRD PARTY RIGHTS - - 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 Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License - along with this program; if not, see http://www.gnu.org/licenses or write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA, 02110-1301 USA, or download the license from the following URL: - http://itextpdf.com/terms-of-use/ - - The interactive user interfaces in modified source and object code versions - of this program must display Appropriate Legal Notices, as required under - Section 5 of the GNU Affero General Public License. - - In accordance with Section 7(b) of the GNU Affero General Public License, - a covered work must retain the producer line in every PDF that is created - or manipulated using iText. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the iText software without - disclosing the source code of your own applications. - These activities include: offering paid services to customers as an ASP, - serving PDFs on the fly in a web application, shipping iText with a closed - source product. - - For more information, please contact iText Software Corp. at this - address: sales@itextpdf.com - */ -package com.itextpdf.rups.model; - -import javax.swing.SwingUtilities; - -/** - * Allows you to perform long-lasting tasks in background. - * If we ever move to Java 6, we should use the SwingWorker class - * (included in the JDK) instead of this custom Event Dispatching - * code. - */ -public abstract class BackgroundTask { - - /** - * A wrapper for the tread that executes a time-consuming task. - */ - private final ThreadWrapper thread; - - /** - * Starts a thread. - * Executes the time-consuming task in the construct method; - * finally calls the finish(). - */ - public BackgroundTask() { - final Runnable doFinished = this::finished; - - final Runnable doConstruct = () -> { - doTask(); - SwingUtilities.invokeLater(doFinished); - }; - - final Thread t = new Thread(doConstruct); - thread = new ThreadWrapper(t); - } - - /** - * Implement this class; the time-consuming task will go here. - */ - public abstract void doTask(); - - /** - * Starts the thread. - */ - public void start() { - final Thread t = thread.get(); - if (t != null) { - t.start(); - } - } - - /** - * Wait for thread to finish what it's doing - * - * @throws InterruptedException an exception - */ - public void join() throws InterruptedException { - Thread t = thread.get(); - if (t != null) { - t.join(); - } - } - - /** - * Called on the event dispatching thread once the - * construct method has finished its task. - */ - public abstract void finished(); - - /** - * Inner class that holds the reference to the thread. - */ - private static class ThreadWrapper { - private final Thread thread; - - ThreadWrapper(Thread t) { - thread = t; - } - - Thread get() { - synchronized (this) { - return thread; - } - } - } -} diff --git a/src/main/java/com/itextpdf/rups/model/ObjectLoader.java b/src/main/java/com/itextpdf/rups/model/ObjectLoader.java index 5c29ccbc..b5bad18f 100644 --- a/src/main/java/com/itextpdf/rups/model/ObjectLoader.java +++ b/src/main/java/com/itextpdf/rups/model/ObjectLoader.java @@ -45,13 +45,15 @@ This file is part of the iText (R) project. import com.itextpdf.rups.event.PostOpenDocumentEvent; import com.itextpdf.rups.view.Language; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.util.Observer; -import javax.swing.SwingUtilities; +import javax.swing.*; /** * Loads the necessary iText PDF objects in Background. */ -public class ObjectLoader extends BackgroundTask { +public class ObjectLoader extends SwingWorker { /** * This is the object that wait for task to complete. */ @@ -127,11 +129,8 @@ public String getLoaderName() { return loaderName; } - /** - * @see BackgroundTask#doTask() - */ @Override - public void doTask() { + public Void doInBackground() { objects = new IndirectObjectFactory(file.getPdfDocument()); final int n = objects.getXRefMaximum(); SwingUtilities.invokeLater(() -> { @@ -144,12 +143,15 @@ public void doTask() { SwingUtilities.invokeLater(() -> progress.setTotal(0)); nodes = new TreeNodeFactory(objects); SwingUtilities.invokeLater(() -> progress.setMessage(Language.GUI_UPDATING.getString())); + + return null; } @Override - public void finished() { + public void done() { try { observer.update(null, new PostOpenDocumentEvent(this)); + this.firePropertyChange("FILE_OPEN_POST", null, null); } catch (Exception ex) { progress.showErrorDialog(ex); LoggerHelper.error(ex.getLocalizedMessage(), ex, getClass()); diff --git a/src/main/java/com/itextpdf/rups/view/FileCloseChangeListener.java b/src/main/java/com/itextpdf/rups/view/FileCloseChangeListener.java new file mode 100644 index 00000000..2b00ca89 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/FileCloseChangeListener.java @@ -0,0 +1,23 @@ +package com.itextpdf.rups.view; + +import com.itextpdf.rups.controller.RupsController; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; + +public class FileCloseChangeListener implements PropertyChangeListener { + + private RupsController controller; + + public FileCloseChangeListener(RupsController controller) { + this.controller = controller; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("FILE_CLOSE".equals(evt.getPropertyName())) { + this.controller.closeCurrentFile(); + } + } +} diff --git a/src/main/java/com/itextpdf/rups/view/FileCompareChangeListener.java b/src/main/java/com/itextpdf/rups/view/FileCompareChangeListener.java new file mode 100644 index 00000000..15c76129 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/FileCompareChangeListener.java @@ -0,0 +1,11 @@ +package com.itextpdf.rups.view; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class FileCompareChangeListener implements PropertyChangeListener { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + } +} diff --git a/src/main/java/com/itextpdf/rups/view/FileOpenChangeListener.java b/src/main/java/com/itextpdf/rups/view/FileOpenChangeListener.java new file mode 100644 index 00000000..c25b5ec3 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/FileOpenChangeListener.java @@ -0,0 +1,26 @@ +package com.itextpdf.rups.view; + +import com.itextpdf.rups.controller.RupsController; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; + +public class FileOpenChangeListener implements PropertyChangeListener { + + private RupsController controller; + + public FileOpenChangeListener(RupsController controller) { + this.controller = controller; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("FILE_OPEN".equals(evt.getPropertyName()) + && evt.getNewValue() != null + && evt.getNewValue() instanceof File + ) { + this.controller.openNewFile((File)evt.getNewValue()); + } + } +} diff --git a/src/main/java/com/itextpdf/rups/view/FileOpenPostChangeListener.java b/src/main/java/com/itextpdf/rups/view/FileOpenPostChangeListener.java new file mode 100644 index 00000000..ed58c886 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/FileOpenPostChangeListener.java @@ -0,0 +1,20 @@ +package com.itextpdf.rups.view; + +import com.itextpdf.rups.controller.RupsController; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class FileOpenPostChangeListener implements PropertyChangeListener { + + private RupsController controller; + + public FileOpenPostChangeListener(RupsController controller) { + this.controller = controller; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + this.controller.update(evt); + } +} diff --git a/src/main/java/com/itextpdf/rups/view/FileSaveChangeListener.java b/src/main/java/com/itextpdf/rups/view/FileSaveChangeListener.java new file mode 100644 index 00000000..efb75356 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/FileSaveChangeListener.java @@ -0,0 +1,25 @@ +package com.itextpdf.rups.view; + +import com.itextpdf.rups.controller.RupsController; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; + +public class FileSaveChangeListener implements PropertyChangeListener { + + private RupsController controller; + + public FileSaveChangeListener(RupsController controller) { + this.controller = controller; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( "FILE_SAVED".equals(evt.getPropertyName()) + && evt.getNewValue() != null + && evt.getNewValue() instanceof File ) { + this.controller.saveCurrentFile((File) evt.getNewValue()); + } + } +} diff --git a/src/main/java/com/itextpdf/rups/view/NewIndirectPdfObjectDialog.java b/src/main/java/com/itextpdf/rups/view/NewIndirectPdfObjectDialog.java index 39231da8..90b85862 100644 --- a/src/main/java/com/itextpdf/rups/view/NewIndirectPdfObjectDialog.java +++ b/src/main/java/com/itextpdf/rups/view/NewIndirectPdfObjectDialog.java @@ -202,7 +202,7 @@ public AddNewIndirectAction(RupsController controller, String name, Icon icon) { @Override public void actionPerformed(ActionEvent e) { - controller.update(null, new NewIndirectObjectEvent()); + controller.update(new NewIndirectObjectEvent()); } } } diff --git a/src/main/java/com/itextpdf/rups/view/RupsMenuBar.java b/src/main/java/com/itextpdf/rups/view/RupsMenuBar.java index 2b76f0fd..006da829 100644 --- a/src/main/java/com/itextpdf/rups/view/RupsMenuBar.java +++ b/src/main/java/com/itextpdf/rups/view/RupsMenuBar.java @@ -63,7 +63,7 @@ This file is part of the iText (R) project. import javax.swing.JMenuItem; import javax.swing.KeyStroke; -public class RupsMenuBar extends JMenuBar implements Observer { +public class RupsMenuBar extends JMenuBar { /** * The action needed to open a file. */ @@ -101,17 +101,27 @@ public RupsMenuBar(RupsController controller) { preferencesWindow = new PreferencesWindow(); - fileOpenAction = new FileOpenAction(controller, PdfFilter.INSTANCE, controller.getMasterComponent()); - fileCloseAction = new FileCloseAction(controller); + fileOpenAction = new FileOpenAction(PdfFilter.INSTANCE, controller.getMasterComponent()); + fileOpenAction.addPropertyChangeListener(new FileOpenChangeListener(controller)); + + fileCloseAction = new FileCloseAction(); + fileCloseAction.addPropertyChangeListener(new FileCloseChangeListener(controller)); + + fileSaverAction = new FileSaveAction(PdfFilter.INSTANCE, controller.getMasterComponent()); + fileSaverAction.addPropertyChangeListener(new FileSaveChangeListener(controller)); + openInViewerAction = new OpenInViewerAction(controller); - fileSaverAction = new FileSaveAction(controller, PdfFilter.INSTANCE, controller.getMasterComponent()); + fileCompareAction = - new FileCompareAction(controller, PdfFilter.INSTANCE, controller.getMasterComponent()); + new FileCompareAction(PdfFilter.INSTANCE, controller.getMasterComponent()); + fileCompareAction.addPropertyChangeListener(new FileCompareChangeListener()); final JMenu file = new JMenu(Language.MENU_BAR_FILE.getString()); addItem(file, Language.MENU_BAR_OPEN.getString(), fileOpenAction, KeyStroke.getKeyStroke('O', InputEvent.CTRL_DOWN_MASK)); - addItem(file, Language.MENU_BAR_CLOSE.getString(), new FileCloseAction(controller), + FileCloseAction action = new FileCloseAction(); + action.addPropertyChangeListener(new FileCloseChangeListener(controller)); + addItem(file, Language.MENU_BAR_CLOSE.getString(), action, KeyStroke.getKeyStroke('W', InputEvent.CTRL_DOWN_MASK)); addItem(file, Language.MENU_BAR_SAVE_AS.getString(), fileSaverAction, KeyStroke.getKeyStroke('S', InputEvent.CTRL_DOWN_MASK)); @@ -141,26 +151,6 @@ public RupsMenuBar(RupsController controller) { enableItems(false); } - /** - * @see java.util.Observer#update(java.util.Observable, java.lang.Object) - */ - public void update(Observable observable, Object obj) { - if (observable instanceof RupsController && obj instanceof RupsEvent) { - RupsEvent event = (RupsEvent) obj; - switch (event.getType()) { - case RupsEvent.ALL_FILES_CLOSED: - enableItems(false); - break; - case RupsEvent.OPEN_DOCUMENT_POST_EVENT: - case RupsEvent.OPEN_FILE_EVENT: - enableItems(true); - break; - case RupsEvent.ROOT_NODE_CLICKED_EVENT: - fileOpenAction.actionPerformed(null); - } - } - } - /** * Create an item with a certain caption and a certain action, * then add the item to a menu. diff --git a/src/main/java/com/itextpdf/rups/view/RupsMenuBarChangeListener.java b/src/main/java/com/itextpdf/rups/view/RupsMenuBarChangeListener.java new file mode 100644 index 00000000..5d0b6601 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/view/RupsMenuBarChangeListener.java @@ -0,0 +1,28 @@ +package com.itextpdf.rups.view; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * Class responsible for manipulating a {@link com.itextpdf.rups.view.RupsMenuBar RupsMenuBar} instance. + * It listens to fired events, such as "FILE_LOADED", etc. + */ +public class RupsMenuBarChangeListener implements PropertyChangeListener { + + private final String FILE_LOADED_EVENT = "FILE_LOADED"; + + private RupsMenuBar menuBar; + + public RupsMenuBarChangeListener(RupsMenuBar menuBar) { + this.menuBar = menuBar; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( this.FILE_LOADED_EVENT.equals(evt.getPropertyName())) { + this.menuBar.enableItems(true); + } else { + this.menuBar.enableItems(false); + } + } +} diff --git a/src/test/java/com/itextpdf/rups/controller/RupsControllerTest.java b/src/test/java/com/itextpdf/rups/controller/RupsControllerTest.java index 14668272..004e135e 100644 --- a/src/test/java/com/itextpdf/rups/controller/RupsControllerTest.java +++ b/src/test/java/com/itextpdf/rups/controller/RupsControllerTest.java @@ -45,11 +45,16 @@ This file is part of the iText (R) project. import com.itextpdf.rups.event.CloseDocumentEvent; import com.itextpdf.rups.event.OpenFileEvent; import com.itextpdf.rups.event.SaveToFileEvent; +import com.itextpdf.rups.model.PdfFile; +import com.itextpdf.rups.view.FileCloseChangeListener; +import com.itextpdf.rups.view.FileOpenChangeListener; +import com.itextpdf.rups.view.FileSaveChangeListener; import com.itextpdf.rups.view.RupsTabbedPane; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.awt.Dimension; +import java.beans.PropertyChangeEvent; import java.io.File; public class RupsControllerTest { @@ -59,7 +64,9 @@ public void closeTest() { MockRupsTabbedPane rupsTabbedPane = new MockRupsTabbedPane(); RupsController rupsController = new RupsController(null, rupsTabbedPane); - rupsController.update(null, new CloseDocumentEvent()); + FileCloseChangeListener closeChangeListener = new FileCloseChangeListener(rupsController); + closeChangeListener.propertyChange(new PropertyChangeEvent(rupsController, "FILE_CLOSE", null, null)); + Assertions.assertTrue(rupsTabbedPane.closed); Assertions.assertFalse(rupsTabbedPane.opened); Assertions.assertFalse(rupsTabbedPane.saved); @@ -69,8 +76,9 @@ public void closeTest() { public void saveTest() { MockRupsTabbedPane rupsTabbedPane = new MockRupsTabbedPane(); RupsController rupsController = new RupsController(null, rupsTabbedPane); + FileSaveChangeListener saveChangeListener = new FileSaveChangeListener(rupsController); + saveChangeListener.propertyChange(new PropertyChangeEvent(rupsController, "FILE_SAVED", null, new File(""))); - rupsController.update(null, new SaveToFileEvent(new File(""))); Assertions.assertTrue(rupsTabbedPane.saved); Assertions.assertFalse(rupsTabbedPane.opened); Assertions.assertFalse(rupsTabbedPane.closed); @@ -81,7 +89,9 @@ public void openTest() { MockRupsTabbedPane rupsTabbedPane = new MockRupsTabbedPane(); RupsController rupsController = new RupsController(null, rupsTabbedPane); - rupsController.update(null, new OpenFileEvent(new File("test.pdf"))); + FileOpenChangeListener openChangeListener = new FileOpenChangeListener(rupsController); + openChangeListener.propertyChange(new PropertyChangeEvent(rupsController, "FILE_OPEN", null, new File(""))); + Assertions.assertTrue(rupsTabbedPane.opened); Assertions.assertFalse(rupsTabbedPane.saved); Assertions.assertFalse(rupsTabbedPane.closed); @@ -101,6 +111,12 @@ public boolean closeCurrentFile() { } @Override + public PdfFile getCurrentFile() { + return null; + } + + + @Override public void saveCurrentFile(File file) { saved = true; } diff --git a/src/test/java/com/itextpdf/rups/mock/MockedBackgroundTask.java b/src/test/java/com/itextpdf/rups/mock/MockedBackgroundTask.java deleted file mode 100644 index 8e390182..00000000 --- a/src/test/java/com/itextpdf/rups/mock/MockedBackgroundTask.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of the iText (R) project. - Copyright (c) 1998-2023 Apryse Group NV - Authors: Apryse Software. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation with the addition of the - following permission added to Section 15 as permitted in Section 7(a): - FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY - APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT - OF THIRD PARTY RIGHTS - - 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 Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License - along with this program; if not, see http://www.gnu.org/licenses or write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA, 02110-1301 USA, or download the license from the following URL: - http://itextpdf.com/terms-of-use/ - - The interactive user interfaces in modified source and object code versions - of this program must display Appropriate Legal Notices, as required under - Section 5 of the GNU Affero General Public License. - - In accordance with Section 7(b) of the GNU Affero General Public License, - a covered work must retain the producer line in every PDF that is created - or manipulated using iText. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the iText software without - disclosing the source code of your own applications. - These activities include: offering paid services to customers as an ASP, - serving PDFs on the fly in a web application, shipping iText with a closed - source product. - - For more information, please contact iText Software Corp. at this - address: sales@itextpdf.com - */ -package com.itextpdf.rups.mock; - -import com.itextpdf.rups.model.BackgroundTask; - -public class MockedBackgroundTask extends BackgroundTask { - - private boolean taskExecuted; - - public MockedBackgroundTask() { - this.taskExecuted = false; - } - - @Override public void doTask() { - taskExecuted = true; - } - - @Override public void finished() { - } - - public boolean hasTaskExecuted() { - return taskExecuted; - } -} diff --git a/src/test/java/com/itextpdf/rups/model/BackgroundTaskTest.java b/src/test/java/com/itextpdf/rups/model/BackgroundTaskTest.java deleted file mode 100644 index ce6930f5..00000000 --- a/src/test/java/com/itextpdf/rups/model/BackgroundTaskTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - This file is part of the iText (R) project. - Copyright (c) 1998-2023 Apryse Group NV - Authors: Apryse Software. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation with the addition of the - following permission added to Section 15 as permitted in Section 7(a): - FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY - APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT - OF THIRD PARTY RIGHTS - - 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 Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License - along with this program; if not, see http://www.gnu.org/licenses or write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA, 02110-1301 USA, or download the license from the following URL: - http://itextpdf.com/terms-of-use/ - - The interactive user interfaces in modified source and object code versions - of this program must display Appropriate Legal Notices, as required under - Section 5 of the GNU Affero General Public License. - - In accordance with Section 7(b) of the GNU Affero General Public License, - a covered work must retain the producer line in every PDF that is created - or manipulated using iText. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the iText software without - disclosing the source code of your own applications. - These activities include: offering paid services to customers as an ASP, - serving PDFs on the fly in a web application, shipping iText with a closed - source product. - - For more information, please contact iText Software Corp. at this - address: sales@itextpdf.com - */ -package com.itextpdf.rups.model; - -import com.itextpdf.rups.mock.MockedBackgroundTask; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag("UnitTest") -public class BackgroundTaskTest { - - @Test - public void normalScenario() throws InterruptedException { - MockedBackgroundTask backgroundTask = new MockedBackgroundTask(); - backgroundTask.start(); - backgroundTask.join(); - Assertions.assertTrue(backgroundTask.hasTaskExecuted()); - } -} diff --git a/src/test/java/com/itextpdf/rups/view/itext/StructureTreeTest.java b/src/test/java/com/itextpdf/rups/view/itext/StructureTreeTest.java index ffe6ad14..9adbe812 100644 --- a/src/test/java/com/itextpdf/rups/view/itext/StructureTreeTest.java +++ b/src/test/java/com/itextpdf/rups/view/itext/StructureTreeTest.java @@ -92,8 +92,8 @@ private static StructureTreeNode getStructureTreeRootNode(PdfFile pdfFile) { PdfReaderController controller = new PdfReaderController(null, null); ObjectLoader loader = new ObjectLoader(controller, pdfFile, pdfFile.getFilename(), new DummyProgressDialog()); // preload everything - loader.doTask(); - + loader.execute(); + while (!loader.isDone()) {} // initialise the main PDF object tree view controller.update(controller, new PostOpenDocumentEvent(loader));