Added better load and save preferences, non-modal help.
This commit is contained in:
		
							parent
							
								
									7a49772540
								
							
						
					
					
						commit
						f37df5defc
					
				| 
						 | 
				
			
			@ -18,11 +18,12 @@ import java.awt.image.BufferedImage;
 | 
			
		|||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.prefs.Preferences;
 | 
			
		||||
 | 
			
		||||
public class ExportToImageAction extends AbstractAction {
 | 
			
		||||
	private static ExportToImageAction instance;
 | 
			
		||||
	private static final String LAST_EXPORT_LOCATION_KEY = "lastExportLocation";
 | 
			
		||||
 | 
			
		||||
	private static ExportToImageAction instance;
 | 
			
		||||
	public static ExportToImageAction getInstance() {
 | 
			
		||||
		if (instance == null) {
 | 
			
		||||
			instance = new ExportToImageAction();
 | 
			
		||||
| 
						 | 
				
			
			@ -30,8 +31,6 @@ public class ExportToImageAction extends AbstractAction {
 | 
			
		|||
		return instance;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private File lastSelectedFile;
 | 
			
		||||
 | 
			
		||||
	@Setter
 | 
			
		||||
	private MappingModel model;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,12 +51,14 @@ public class ExportToImageAction extends AbstractAction {
 | 
			
		|||
			);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser();
 | 
			
		||||
		fileChooser.setFileFilter(new FileNameExtensionFilter(
 | 
			
		||||
				"Image files", ImageIO.getReaderFileSuffixes()
 | 
			
		||||
		));
 | 
			
		||||
		if (this.lastSelectedFile != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(this.lastSelectedFile);
 | 
			
		||||
		Preferences prefs = Preferences.userNodeForPackage(ExportToImageAction.class);
 | 
			
		||||
		String path = prefs.get(LAST_EXPORT_LOCATION_KEY, null);
 | 
			
		||||
		if (path != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(new File(path));
 | 
			
		||||
		}
 | 
			
		||||
		int choice = fileChooser.showSaveDialog((Component) e.getSource());
 | 
			
		||||
		if (choice == JFileChooser.APPROVE_OPTION) {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +75,18 @@ public class ExportToImageAction extends AbstractAction {
 | 
			
		|||
				chosenFile = new File(chosenFile.getParent(), chosenFile.getName() + '.' + extension);
 | 
			
		||||
			}
 | 
			
		||||
			try {
 | 
			
		||||
				ImageIO.write(this.renderModel(), extension, chosenFile);
 | 
			
		||||
				long start = System.currentTimeMillis();
 | 
			
		||||
				BufferedImage render = this.renderModel();
 | 
			
		||||
				double durationSeconds = (System.currentTimeMillis() - start) / 1000.0;
 | 
			
		||||
				ImageIO.write(render, extension, chosenFile);
 | 
			
		||||
				prefs.put(LAST_EXPORT_LOCATION_KEY, chosenFile.getAbsolutePath());
 | 
			
		||||
				JOptionPane.showMessageDialog(
 | 
			
		||||
						fileChooser,
 | 
			
		||||
						"Image export completed in " + String.format("%.4f", durationSeconds) + " seconds.\n" +
 | 
			
		||||
								"Resolution: " + render.getWidth() + "x" + render.getHeight(),
 | 
			
		||||
						"Image Export Complete",
 | 
			
		||||
						JOptionPane.INFORMATION_MESSAGE
 | 
			
		||||
				);
 | 
			
		||||
			} catch (IOException ex) {
 | 
			
		||||
				ex.printStackTrace();
 | 
			
		||||
				JOptionPane.showMessageDialog(fileChooser, "An error occurred and the file could not be saved:\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,23 +95,30 @@ public class ExportToImageAction extends AbstractAction {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	private BufferedImage renderModel() {
 | 
			
		||||
		// Prepare a tiny sample image that we can use to determine the bounds of the model in a graphics context.
 | 
			
		||||
		BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
 | 
			
		||||
		Graphics2D g2d = bufferedImage.createGraphics();
 | 
			
		||||
		DiagramPanel.prepareGraphics(g2d);
 | 
			
		||||
		final Rectangle bounds = this.model.getViewModel().getBounds(g2d);
 | 
			
		||||
 | 
			
		||||
		// Prepare the output image.
 | 
			
		||||
		BufferedImage outputImage = new BufferedImage(bounds.width, bounds.height + 20, BufferedImage.TYPE_INT_RGB);
 | 
			
		||||
		g2d = outputImage.createGraphics();
 | 
			
		||||
		g2d.setColor(Color.WHITE);
 | 
			
		||||
		g2d.fillRect(outputImage.getMinX(), outputImage.getMinY(), outputImage.getWidth(), outputImage.getHeight());
 | 
			
		||||
 | 
			
		||||
		// Transform the graphics space to account for the model's offset from origin.
 | 
			
		||||
		AffineTransform originalTransform = g2d.getTransform();
 | 
			
		||||
		g2d.setTransform(AffineTransform.getTranslateInstance(-bounds.x, -bounds.y));
 | 
			
		||||
		DiagramPanel.prepareGraphics(g2d);
 | 
			
		||||
 | 
			
		||||
		// Render the model.
 | 
			
		||||
		List<Relation> selectedRelations = this.model.getSelectedRelations();
 | 
			
		||||
		this.model.getSelectedRelations().forEach(r -> r.setSelected(false));
 | 
			
		||||
		new MappingModelViewModel(this.model).draw(g2d);
 | 
			
		||||
		this.model.getRelations().forEach(r -> r.setSelected(selectedRelations.contains(r)));
 | 
			
		||||
 | 
			
		||||
		// Revert back to the normal image space, and render a watermark.
 | 
			
		||||
		g2d.setTransform(originalTransform);
 | 
			
		||||
		g2d.setColor(Color.LIGHT_GRAY);
 | 
			
		||||
		g2d.setFont(g2d.getFont().deriveFont(10.0f));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,16 @@ import java.net.URISyntaxException;
 | 
			
		|||
 | 
			
		||||
public abstract class HtmlDocumentViewerAction extends AbstractAction {
 | 
			
		||||
	private final String resourceFileName;
 | 
			
		||||
	private final Dialog.ModalityType modalityType;
 | 
			
		||||
 | 
			
		||||
	public HtmlDocumentViewerAction(String name, String resourceFileName) {
 | 
			
		||||
		this(name, resourceFileName, Dialog.ModalityType.APPLICATION_MODAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public HtmlDocumentViewerAction(String name, String resourceFileName, Dialog.ModalityType modalityType) {
 | 
			
		||||
		super(name);
 | 
			
		||||
		this.resourceFileName = resourceFileName;
 | 
			
		||||
		this.modalityType = modalityType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +29,7 @@ public abstract class HtmlDocumentViewerAction extends AbstractAction {
 | 
			
		|||
		JDialog dialog = new JDialog(
 | 
			
		||||
				SwingUtilities.getWindowAncestor((Component) e.getSource()),
 | 
			
		||||
				(String) this.getValue(NAME),
 | 
			
		||||
				Dialog.ModalityType.APPLICATION_MODAL
 | 
			
		||||
				this.modalityType
 | 
			
		||||
		);
 | 
			
		||||
		JTextPane textPane = new JTextPane();
 | 
			
		||||
		textPane.setEditable(false);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,10 +14,12 @@ import java.io.File;
 | 
			
		|||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.ObjectInputStream;
 | 
			
		||||
import java.util.prefs.Preferences;
 | 
			
		||||
 | 
			
		||||
public class LoadAction extends AbstractAction {
 | 
			
		||||
	private static LoadAction instance;
 | 
			
		||||
	private static final String LAST_LOAD_LOCATION_KEY = "lastLoadLocation";
 | 
			
		||||
 | 
			
		||||
	private static LoadAction instance;
 | 
			
		||||
	public static LoadAction getInstance() {
 | 
			
		||||
		if (instance == null) {
 | 
			
		||||
			instance = new LoadAction();
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +27,6 @@ public class LoadAction extends AbstractAction {
 | 
			
		|||
		return instance;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private File lastSelectedFile;
 | 
			
		||||
 | 
			
		||||
	@Setter
 | 
			
		||||
	private DiagramPanel diagramPanel;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,14 +38,16 @@ public class LoadAction extends AbstractAction {
 | 
			
		|||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void actionPerformed(ActionEvent e) {
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser();
 | 
			
		||||
		FileNameExtensionFilter filter = new FileNameExtensionFilter(
 | 
			
		||||
				"ERME Serialized Files",
 | 
			
		||||
				"erme"
 | 
			
		||||
		);
 | 
			
		||||
		fileChooser.setFileFilter(filter);
 | 
			
		||||
		if (this.lastSelectedFile != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(this.lastSelectedFile);
 | 
			
		||||
		Preferences prefs = Preferences.userNodeForPackage(LoadAction.class);
 | 
			
		||||
		String path = prefs.get(LAST_LOAD_LOCATION_KEY, null);
 | 
			
		||||
		if (path != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(new File(path));
 | 
			
		||||
		}
 | 
			
		||||
		int choice = fileChooser.showOpenDialog((Component) e.getSource());
 | 
			
		||||
		if (choice == JFileChooser.APPROVE_OPTION) {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +58,8 @@ public class LoadAction extends AbstractAction {
 | 
			
		|||
			}
 | 
			
		||||
			try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(chosenFile))) {
 | 
			
		||||
				MappingModel loadedModel = (MappingModel) ois.readObject();
 | 
			
		||||
				this.lastSelectedFile = chosenFile;
 | 
			
		||||
				this.diagramPanel.setModel(loadedModel);
 | 
			
		||||
				prefs.put(LAST_LOAD_LOCATION_KEY, chosenFile.getAbsolutePath());
 | 
			
		||||
			} catch (IOException | ClassNotFoundException | ClassCastException ex) {
 | 
			
		||||
				ex.printStackTrace();
 | 
			
		||||
				JOptionPane.showMessageDialog(fileChooser, "An error occurred and the file could not be read:\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
package nl.andrewlalis.erme.control.actions;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
 | 
			
		||||
public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
 | 
			
		||||
	private static MappingAlgorithmHelpAction instance;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +13,7 @@ public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	public MappingAlgorithmHelpAction() {
 | 
			
		||||
		super("Mapping Algorithm Help", "html/er_mapping_algorithm.html");
 | 
			
		||||
		super("Mapping Algorithm Help", "html/er_mapping_algorithm.html", Dialog.ModalityType.DOCUMENT_MODAL);
 | 
			
		||||
		this.putValue(SHORT_DESCRIPTION, "Shows a quick guide on how to map from an ER model to a schema.");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,11 +9,16 @@ import java.awt.*;
 | 
			
		|||
import java.awt.event.ActionEvent;
 | 
			
		||||
import java.awt.event.InputEvent;
 | 
			
		||||
import java.awt.event.KeyEvent;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.ObjectOutputStream;
 | 
			
		||||
import java.util.prefs.Preferences;
 | 
			
		||||
 | 
			
		||||
public class SaveAction extends AbstractAction {
 | 
			
		||||
	private static SaveAction instance;
 | 
			
		||||
	private static final String LAST_SAVE_LOCATION_KEY = "lastSaveLocation";
 | 
			
		||||
 | 
			
		||||
	private static SaveAction instance;
 | 
			
		||||
	public static SaveAction getInstance() {
 | 
			
		||||
		if (instance == null) {
 | 
			
		||||
			instance = new SaveAction();
 | 
			
		||||
| 
						 | 
				
			
			@ -21,8 +26,6 @@ public class SaveAction extends AbstractAction {
 | 
			
		|||
		return instance;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private File lastSelectedFile;
 | 
			
		||||
 | 
			
		||||
	@Setter
 | 
			
		||||
	private MappingModel model;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,14 +37,16 @@ public class SaveAction extends AbstractAction {
 | 
			
		|||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void actionPerformed(ActionEvent e) {
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
 | 
			
		||||
		JFileChooser fileChooser = new JFileChooser();
 | 
			
		||||
		FileNameExtensionFilter filter = new FileNameExtensionFilter(
 | 
			
		||||
				"ERME Serialized Files",
 | 
			
		||||
				"erme"
 | 
			
		||||
		);
 | 
			
		||||
		fileChooser.setFileFilter(filter);
 | 
			
		||||
		if (this.lastSelectedFile != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(this.lastSelectedFile);
 | 
			
		||||
		Preferences prefs = Preferences.userNodeForPackage(SaveAction.class);
 | 
			
		||||
		String path = prefs.get(LAST_SAVE_LOCATION_KEY, null);
 | 
			
		||||
		if (path != null) {
 | 
			
		||||
			fileChooser.setSelectedFile(new File(path));
 | 
			
		||||
		}
 | 
			
		||||
		int choice = fileChooser.showSaveDialog((Component) e.getSource());
 | 
			
		||||
		if (choice == JFileChooser.APPROVE_OPTION) {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +61,7 @@ public class SaveAction extends AbstractAction {
 | 
			
		|||
			// TODO: Check for confirm before overwriting.
 | 
			
		||||
			try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(chosenFile))) {
 | 
			
		||||
				oos.writeObject(this.model);
 | 
			
		||||
				this.lastSelectedFile = chosenFile;
 | 
			
		||||
				prefs.put(LAST_SAVE_LOCATION_KEY, chosenFile.getAbsolutePath());
 | 
			
		||||
				JOptionPane.showMessageDialog(fileChooser, "File saved successfully.", "Success", JOptionPane.INFORMATION_MESSAGE);
 | 
			
		||||
			} catch (IOException ex) {
 | 
			
		||||
				ex.printStackTrace();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue