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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
public class ExportToImageAction extends AbstractAction {
|
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() {
|
public static ExportToImageAction getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new ExportToImageAction();
|
instance = new ExportToImageAction();
|
||||||
|
@ -30,8 +31,6 @@ public class ExportToImageAction extends AbstractAction {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File lastSelectedFile;
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private MappingModel model;
|
private MappingModel model;
|
||||||
|
|
||||||
|
@ -52,12 +51,14 @@ public class ExportToImageAction extends AbstractAction {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setFileFilter(new FileNameExtensionFilter(
|
fileChooser.setFileFilter(new FileNameExtensionFilter(
|
||||||
"Image files", ImageIO.getReaderFileSuffixes()
|
"Image files", ImageIO.getReaderFileSuffixes()
|
||||||
));
|
));
|
||||||
if (this.lastSelectedFile != null) {
|
Preferences prefs = Preferences.userNodeForPackage(ExportToImageAction.class);
|
||||||
fileChooser.setSelectedFile(this.lastSelectedFile);
|
String path = prefs.get(LAST_EXPORT_LOCATION_KEY, null);
|
||||||
|
if (path != null) {
|
||||||
|
fileChooser.setSelectedFile(new File(path));
|
||||||
}
|
}
|
||||||
int choice = fileChooser.showSaveDialog((Component) e.getSource());
|
int choice = fileChooser.showSaveDialog((Component) e.getSource());
|
||||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||||
|
@ -74,7 +75,18 @@ public class ExportToImageAction extends AbstractAction {
|
||||||
chosenFile = new File(chosenFile.getParent(), chosenFile.getName() + '.' + extension);
|
chosenFile = new File(chosenFile.getParent(), chosenFile.getName() + '.' + extension);
|
||||||
}
|
}
|
||||||
try {
|
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) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
JOptionPane.showMessageDialog(fileChooser, "An error occurred and the file could not be saved:\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
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() {
|
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);
|
BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||||
Graphics2D g2d = bufferedImage.createGraphics();
|
Graphics2D g2d = bufferedImage.createGraphics();
|
||||||
DiagramPanel.prepareGraphics(g2d);
|
DiagramPanel.prepareGraphics(g2d);
|
||||||
final Rectangle bounds = this.model.getViewModel().getBounds(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);
|
BufferedImage outputImage = new BufferedImage(bounds.width, bounds.height + 20, BufferedImage.TYPE_INT_RGB);
|
||||||
g2d = outputImage.createGraphics();
|
g2d = outputImage.createGraphics();
|
||||||
g2d.setColor(Color.WHITE);
|
g2d.setColor(Color.WHITE);
|
||||||
g2d.fillRect(outputImage.getMinX(), outputImage.getMinY(), outputImage.getWidth(), outputImage.getHeight());
|
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();
|
AffineTransform originalTransform = g2d.getTransform();
|
||||||
g2d.setTransform(AffineTransform.getTranslateInstance(-bounds.x, -bounds.y));
|
g2d.setTransform(AffineTransform.getTranslateInstance(-bounds.x, -bounds.y));
|
||||||
DiagramPanel.prepareGraphics(g2d);
|
DiagramPanel.prepareGraphics(g2d);
|
||||||
|
|
||||||
|
// Render the model.
|
||||||
List<Relation> selectedRelations = this.model.getSelectedRelations();
|
List<Relation> selectedRelations = this.model.getSelectedRelations();
|
||||||
this.model.getSelectedRelations().forEach(r -> r.setSelected(false));
|
this.model.getSelectedRelations().forEach(r -> r.setSelected(false));
|
||||||
new MappingModelViewModel(this.model).draw(g2d);
|
new MappingModelViewModel(this.model).draw(g2d);
|
||||||
this.model.getRelations().forEach(r -> r.setSelected(selectedRelations.contains(r)));
|
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.setTransform(originalTransform);
|
||||||
g2d.setColor(Color.LIGHT_GRAY);
|
g2d.setColor(Color.LIGHT_GRAY);
|
||||||
g2d.setFont(g2d.getFont().deriveFont(10.0f));
|
g2d.setFont(g2d.getFont().deriveFont(10.0f));
|
||||||
|
|
|
@ -12,10 +12,16 @@ import java.net.URISyntaxException;
|
||||||
|
|
||||||
public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
||||||
private final String resourceFileName;
|
private final String resourceFileName;
|
||||||
|
private final Dialog.ModalityType modalityType;
|
||||||
|
|
||||||
public HtmlDocumentViewerAction(String name, String resourceFileName) {
|
public HtmlDocumentViewerAction(String name, String resourceFileName) {
|
||||||
|
this(name, resourceFileName, Dialog.ModalityType.APPLICATION_MODAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HtmlDocumentViewerAction(String name, String resourceFileName, Dialog.ModalityType modalityType) {
|
||||||
super(name);
|
super(name);
|
||||||
this.resourceFileName = resourceFileName;
|
this.resourceFileName = resourceFileName;
|
||||||
|
this.modalityType = modalityType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,7 +29,7 @@ public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
||||||
JDialog dialog = new JDialog(
|
JDialog dialog = new JDialog(
|
||||||
SwingUtilities.getWindowAncestor((Component) e.getSource()),
|
SwingUtilities.getWindowAncestor((Component) e.getSource()),
|
||||||
(String) this.getValue(NAME),
|
(String) this.getValue(NAME),
|
||||||
Dialog.ModalityType.APPLICATION_MODAL
|
this.modalityType
|
||||||
);
|
);
|
||||||
JTextPane textPane = new JTextPane();
|
JTextPane textPane = new JTextPane();
|
||||||
textPane.setEditable(false);
|
textPane.setEditable(false);
|
||||||
|
|
|
@ -14,10 +14,12 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
public class LoadAction extends AbstractAction {
|
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() {
|
public static LoadAction getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new LoadAction();
|
instance = new LoadAction();
|
||||||
|
@ -25,8 +27,6 @@ public class LoadAction extends AbstractAction {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File lastSelectedFile;
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private DiagramPanel diagramPanel;
|
private DiagramPanel diagramPanel;
|
||||||
|
|
||||||
|
@ -38,14 +38,16 @@ public class LoadAction extends AbstractAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||||
"ERME Serialized Files",
|
"ERME Serialized Files",
|
||||||
"erme"
|
"erme"
|
||||||
);
|
);
|
||||||
fileChooser.setFileFilter(filter);
|
fileChooser.setFileFilter(filter);
|
||||||
if (this.lastSelectedFile != null) {
|
Preferences prefs = Preferences.userNodeForPackage(LoadAction.class);
|
||||||
fileChooser.setSelectedFile(this.lastSelectedFile);
|
String path = prefs.get(LAST_LOAD_LOCATION_KEY, null);
|
||||||
|
if (path != null) {
|
||||||
|
fileChooser.setSelectedFile(new File(path));
|
||||||
}
|
}
|
||||||
int choice = fileChooser.showOpenDialog((Component) e.getSource());
|
int choice = fileChooser.showOpenDialog((Component) e.getSource());
|
||||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||||
|
@ -56,8 +58,8 @@ public class LoadAction extends AbstractAction {
|
||||||
}
|
}
|
||||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(chosenFile))) {
|
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(chosenFile))) {
|
||||||
MappingModel loadedModel = (MappingModel) ois.readObject();
|
MappingModel loadedModel = (MappingModel) ois.readObject();
|
||||||
this.lastSelectedFile = chosenFile;
|
|
||||||
this.diagramPanel.setModel(loadedModel);
|
this.diagramPanel.setModel(loadedModel);
|
||||||
|
prefs.put(LAST_LOAD_LOCATION_KEY, chosenFile.getAbsolutePath());
|
||||||
} catch (IOException | ClassNotFoundException | ClassCastException ex) {
|
} catch (IOException | ClassNotFoundException | ClassCastException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
JOptionPane.showMessageDialog(fileChooser, "An error occurred and the file could not be read:\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
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;
|
package nl.andrewlalis.erme.control.actions;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
|
public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
|
||||||
private static MappingAlgorithmHelpAction instance;
|
private static MappingAlgorithmHelpAction instance;
|
||||||
|
|
||||||
|
@ -11,7 +13,7 @@ public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappingAlgorithmHelpAction() {
|
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.");
|
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.ActionEvent;
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
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 {
|
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() {
|
public static SaveAction getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new SaveAction();
|
instance = new SaveAction();
|
||||||
|
@ -21,8 +26,6 @@ public class SaveAction extends AbstractAction {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private File lastSelectedFile;
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private MappingModel model;
|
private MappingModel model;
|
||||||
|
|
||||||
|
@ -34,14 +37,16 @@ public class SaveAction extends AbstractAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JFileChooser fileChooser = new JFileChooser(this.lastSelectedFile);
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||||
"ERME Serialized Files",
|
"ERME Serialized Files",
|
||||||
"erme"
|
"erme"
|
||||||
);
|
);
|
||||||
fileChooser.setFileFilter(filter);
|
fileChooser.setFileFilter(filter);
|
||||||
if (this.lastSelectedFile != null) {
|
Preferences prefs = Preferences.userNodeForPackage(SaveAction.class);
|
||||||
fileChooser.setSelectedFile(this.lastSelectedFile);
|
String path = prefs.get(LAST_SAVE_LOCATION_KEY, null);
|
||||||
|
if (path != null) {
|
||||||
|
fileChooser.setSelectedFile(new File(path));
|
||||||
}
|
}
|
||||||
int choice = fileChooser.showSaveDialog((Component) e.getSource());
|
int choice = fileChooser.showSaveDialog((Component) e.getSource());
|
||||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||||
|
@ -56,7 +61,7 @@ public class SaveAction extends AbstractAction {
|
||||||
// TODO: Check for confirm before overwriting.
|
// TODO: Check for confirm before overwriting.
|
||||||
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(chosenFile))) {
|
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(chosenFile))) {
|
||||||
oos.writeObject(this.model);
|
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);
|
JOptionPane.showMessageDialog(fileChooser, "File saved successfully.", "Success", JOptionPane.INFORMATION_MESSAGE);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
|
Loading…
Reference in New Issue