Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions jhotdraw-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,24 @@
<artifactId>jhotdraw-gui</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Testing dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@

package org.jhotdraw.app.internal;

import org.jhotdraw.api.app.Application;
import org.jhotdraw.api.app.ApplicationModel;
import org.jhotdraw.api.app.View;
import org.jhotdraw.api.gui.URIChooser;
public class ChooserManager {

private URIChooser openChooser;
private URIChooser saveChooser;
private URIChooser importChooser;
private URIChooser exportChooser;

private final Application application;
private final ApplicationModel model;

public ChooserManager(Application application, ApplicationModel model) {
this.application = application;
this.model = model;
}

/**
* Gets an open chooser for the specified view or for the application.
* Implements Lazy Initialization pattern.
*/
public URIChooser getOpenChooser(View v) {
if (v == null) {
return getApplicationOpenChooser();
} else {
return getViewOpenChooser(v);
}
}

/**
* Gets a save chooser for the specified view or for the application.
*/
public URIChooser getSaveChooser(View v) {
if (v == null) {
return getApplicationSaveChooser();
} else {
return getViewSaveChooser(v);
}
}

/**
* Gets an import chooser for the specified view or for the application.
*/
public URIChooser getImportChooser(View v) {
if (v == null) {
return getApplicationImportChooser();
} else {
return getViewImportChooser(v);
}
}

/**
* Gets an export chooser for the specified view or for the application.
*/
public URIChooser getExportChooser(View v) {
if (v == null) {
return getApplicationExportChooser();
} else {
return getViewExportChooser(v);
}
}

// Application-level choosers (singletons)

private URIChooser getApplicationOpenChooser() {
if (openChooser == null) {
openChooser = createAndConfigureChooser(() -> model.createOpenChooser(application, null));
}
return openChooser;
}

private URIChooser getApplicationSaveChooser() {
if (saveChooser == null) {
saveChooser = createAndConfigureChooser(() -> model.createSaveChooser(application, null));
}
return saveChooser;
}

private URIChooser getApplicationImportChooser() {
if (importChooser == null) {
importChooser = createAndConfigureChooser(() -> model.createImportChooser(application, null));
}
return importChooser;
}

private URIChooser getApplicationExportChooser() {
if (exportChooser == null) {
exportChooser = createAndConfigureChooser(() -> model.createExportChooser(application, null));
}
return exportChooser;
}

// View-specific choosers

private URIChooser getViewOpenChooser(View v) {
return getOrCreateViewChooser(v, "openChooser", () -> model.createOpenChooser(application, v));
}

private URIChooser getViewSaveChooser(View v) {
return getOrCreateViewChooser(v, "saveChooser", () -> model.createSaveChooser(application, v));
}

private URIChooser getViewImportChooser(View v) {
return getOrCreateViewChooser(v, "importChooser", () -> model.createImportChooser(application, v));
}

private URIChooser getViewExportChooser(View v) {
return getOrCreateViewChooser(v, "exportChooser", () -> model.createExportChooser(application, v));
}

// Helper methods using Strategy pattern for chooser creation

/**
* Gets or creates a view-specific chooser using the provided factory.
* Implements Template Method pattern for view chooser management.
*/
private URIChooser getOrCreateViewChooser(View v, String clientPropertyKey, ChooserFactory factory) {
URIChooser chooser = (URIChooser) v.getComponent().getClientProperty(clientPropertyKey);
if (chooser == null) {
chooser = factory.createChooser();
v.getComponent().putClientProperty(clientPropertyKey, chooser);
setupViewChooserProperties(chooser, v);
}
return chooser;
}

/**
* Creates and configures an application-level chooser.
*/
private URIChooser createAndConfigureChooser(ChooserFactory factory) {
URIChooser chooser = factory.createChooser();
chooser.getComponent().putClientProperty("application", application);
return chooser;
}

/**
* Sets up client properties for view-specific choosers.
*/
private void setupViewChooserProperties(URIChooser chooser, View view) {
chooser.getComponent().putClientProperty("view", view);
chooser.getComponent().putClientProperty("application", application);
}

/**
* Functional interface for chooser creation strategy.
*/
@FunctionalInterface
private interface ChooserFactory {
URIChooser createChooser();
}

/**
* Clears all cached choosers - useful for testing or configuration changes.
*/
public void clearCachedChoosers() {
openChooser = null;
saveChooser = null;
importChooser = null;
exportChooser = null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* @(#)RecentFilesManager.java
*
* Copyright (c) 1996-2010 The authors and contributors of JHotDraw.
* You may not use, copy or modify this file, except in compliance with the
* accompanying license terms.
*/
package org.jhotdraw.app.internal;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.List;
import java.util.prefs.Preferences;

public class RecentFilesManager {

private static final int MAX_RECENT_FILES_COUNT = 10;
private final LinkedList<URI> recentURIs = new LinkedList<>();
private final Preferences preferences;
private static final int RECENT_FILE_COUNT = 0;
private static final String RECENT_FILES_KEY = "recentFile.";
public RecentFilesManager(Preferences preferences) throws URISyntaxException {
this.preferences = preferences;
loadRecentFiles();
}

/**
* Loads recent files from preferences using Template Method pattern.
*/
private void loadRecentFiles() throws URISyntaxException {
int count = preferences.getInt(String.valueOf(RECENT_FILE_COUNT), 0);
for (int i = 0; i < count; i++) {
String path = preferences.get(RECENT_FILES_KEY + i, null);
if (path != null) {
addRecentURIInternal(new URI(path));
}
}
}

/**
* Saves recent files to preferences.
*/
public void saveRecentFiles() {
preferences.putInt(String.valueOf(RECENT_FILE_COUNT), recentURIs.size());
for (int i = 0; i < recentURIs.size(); i++) {
preferences.put(RECENT_FILES_KEY + i, recentURIs.get(i).toString());
}
}

/**
* Adds a URI to the recent files list.
* Implements the strategy of keeping most recent at the front.
*/
public void addRecentURI(URI uri) {
if (uri == null) {
return;
}

// Remove if already exists to avoid duplicates
recentURIs.remove(uri);

// Add to front
recentURIs.addFirst(uri);

// Limit size
while (recentURIs.size() > MAX_RECENT_FILES_COUNT) {
recentURIs.removeLast();
}

saveRecentFiles();
}

/**
* Internal method for adding without saving (used during loading).
*/
private void addRecentURIInternal(URI uri) {
if (uri != null && !recentURIs.contains(uri)) {
recentURIs.add(uri);
}
}

/**
* Gets the list of recent URIs.
* Returns a copy to prevent external modification.
*/
public List<URI> getRecentURIs() {
return new LinkedList<>(recentURIs);
}

/**
* Clears all recent files.
*/
public void clearRecentFiles() {
recentURIs.clear();
preferences.putInt(String.valueOf(RECENT_FILE_COUNT), 0);
// Remove all stored recent file entries
for (int i = 0; i < MAX_RECENT_FILES_COUNT; i++) {
preferences.remove(RECENT_FILES_KEY + i);
}
}

/**
* Removes a specific URI from the recent files list.
*/
public boolean removeRecentURI(URI uri) {
boolean removed = recentURIs.remove(uri);
if (removed) {
saveRecentFiles();
}
return removed;
}

/**
* Gets the most recent URI, or null if none exists.
*/
public URI getMostRecentURI() {
return recentURIs.isEmpty() ? null : recentURIs.getFirst();
}

/**
* Checks if the recent files list is empty.
*/
public boolean isEmpty() {
return recentURIs.isEmpty();
}

/**
* Gets the maximum number of recent files that can be stored.
*/
public int getMaxRecentFilesCount() {
return MAX_RECENT_FILES_COUNT;
}

/**
* Gets the current number of recent files.
*/
public int getRecentFilesCount() {
return recentURIs.size();
}
}
Loading