Cleaned up singleton actions, updated instructions, etc.
This commit is contained in:
parent
0be31c84ac
commit
1019654e76
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>nl.andrewlalis</groupId>
|
||||
<artifactId>EntityRelationMappingEditor</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<version>1.6.2</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.EntityRelationMappingEditor;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class AboutAction extends AbstractAction {
|
||||
private static AboutAction instance;
|
||||
|
||||
public static AboutAction getInstance() {
|
||||
if (instance == null) instance = new AboutAction();
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public AboutAction() {
|
||||
super("About");
|
||||
this.putValue(SHORT_DESCRIPTION, "Show some information about this program.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
"Entity-Relation Mapping Editor\n" +
|
||||
"by Andrew Lalis\n" +
|
||||
"Version " + EntityRelationMappingEditor.VERSION + "\n" +
|
||||
"To report bugs or make suggestions, please visit the GitHub\n" +
|
||||
"repository for this application and create a new issue.\n\n" +
|
||||
"Thank you for using the ERME!",
|
||||
"About ERME",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
import nl.andrewlalis.erme.view.OrderableListPanel;
|
||||
|
@ -17,31 +15,20 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* A class that implements an AutoPositionAction. This automatically (vertically) positions all relations in the model
|
||||
* based either on alphabetic ordering (by name) or an order that's set by the user
|
||||
*/
|
||||
public class AutoPositionAction extends AbstractAction {
|
||||
public class AutoPositionAction extends DiagramPanelAction {
|
||||
private final static int MARGIN = 10;
|
||||
private final static int PADDING = 10;
|
||||
private static AutoPositionAction instance;
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
public AutoPositionAction() {
|
||||
super("Align Relations");
|
||||
this.putValue(SHORT_DESCRIPTION, "Automatically Align Relations");
|
||||
}
|
||||
|
||||
public static AutoPositionAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new AutoPositionAction();
|
||||
}
|
||||
return instance;
|
||||
public AutoPositionAction(DiagramPanel diagramPanel) {
|
||||
super("Align Relations", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Automatically Align Relations");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
if (model.getRelations().size() == 0) {
|
||||
if (getDiagramPanel().getModel().getRelations().size() == 0) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"Cannot position all relations when there are no relations present",
|
||||
"Relations Required",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
|
@ -50,7 +37,7 @@ public class AutoPositionAction extends AbstractAction {
|
|||
}
|
||||
String[] choices = new String[]{"Alphabeticaly", "Custom Order"};
|
||||
String choice = (String) JOptionPane.showInputDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"Select how to sort the relations",
|
||||
"Position Relations",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
@ -62,14 +49,14 @@ public class AutoPositionAction extends AbstractAction {
|
|||
positionRelations(getAlphabeticRelationList());
|
||||
} else if (choice.equals(choices[1])) {
|
||||
JOptionPane.showConfirmDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
OrderableListPanel.getInstance(),
|
||||
"teststring",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE);
|
||||
this.positionRelations(OrderableListPanel.getInstance().getOrderList());
|
||||
}
|
||||
diagramPanel.repaint();
|
||||
getDiagramPanel().repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,23 +67,20 @@ public class AutoPositionAction extends AbstractAction {
|
|||
if (orderList.isEmpty()) return;
|
||||
AtomicInteger vertSpace = new AtomicInteger(0);
|
||||
orderList.forEach(r -> {
|
||||
int height = (int) r.getViewModel().getBounds(diagramPanel.getGraphics2D()).getHeight();
|
||||
int height = (int) r.getViewModel().getBounds(getDiagramPanel().getGraphics2D()).getHeight();
|
||||
vertSpace.set(Math.max(vertSpace.get(), height));
|
||||
});
|
||||
vertSpace.addAndGet(PADDING);
|
||||
AtomicInteger vertPos = new AtomicInteger(MARGIN);
|
||||
orderList.forEach(r -> {
|
||||
r.setPosition(new Point(MARGIN, vertPos.getAndAdd(vertSpace.get())));
|
||||
});
|
||||
|
||||
diagramPanel.centerModel();
|
||||
orderList.forEach(r -> r.setPosition(new Point(MARGIN, vertPos.getAndAdd(vertSpace.get()))));
|
||||
getDiagramPanel().centerModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an orderList by grabbing all relations and sorting them
|
||||
*/
|
||||
private ArrayList<Relation> getAlphabeticRelationList() {
|
||||
ArrayList<Relation> relationList = new ArrayList<>(model.getRelations());
|
||||
ArrayList<Relation> relationList = new ArrayList<>(getDiagramPanel().getModel().getRelations());
|
||||
Collections.sort(relationList);
|
||||
return relationList;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public abstract class DiagramPanelAction extends AbstractAction {
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final DiagramPanel diagramPanel;
|
||||
|
||||
public DiagramPanelAction(String name, DiagramPanel diagramPanel) {
|
||||
super(name);
|
||||
this.diagramPanel = diagramPanel;
|
||||
}
|
||||
}
|
|
@ -1,29 +1,15 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class ExitAction extends AbstractAction {
|
||||
private static ExitAction instance;
|
||||
|
||||
public static ExitAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ExitAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public ExitAction() {
|
||||
super("Exit");
|
||||
public class ExitAction extends DiagramPanelAction {
|
||||
public ExitAction(DiagramPanel diagramPanel) {
|
||||
super("Exit", diagramPanel);
|
||||
this.putValue(Action.SHORT_DESCRIPTION, "Exit the program.");
|
||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
@ -31,7 +17,7 @@ public class ExitAction extends AbstractAction {
|
|||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int choice = JOptionPane.showConfirmDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"Are you sure you want to quit?\nAll unsaved data will be lost.",
|
||||
"Confirm Exit",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
@ -20,33 +19,21 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class ExportToImageAction extends AbstractAction {
|
||||
public class ExportToImageAction extends DiagramPanelAction {
|
||||
private static final String LAST_EXPORT_LOCATION_KEY = "lastExportLocation";
|
||||
|
||||
private static ExportToImageAction instance;
|
||||
public static ExportToImageAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ExportToImageAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public ExportToImageAction() {
|
||||
super("Export to Image");
|
||||
public ExportToImageAction(DiagramPanel diagramPanel) {
|
||||
super("Export to Image", diagramPanel);
|
||||
this.putValue(Action.SHORT_DESCRIPTION, "Export the current diagram to an image.");
|
||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (this.model.getRelations().isEmpty()) {
|
||||
DiagramPanel dp = getDiagramPanel();
|
||||
if (dp.getModel().getRelations().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
dp,
|
||||
"Model is empty. Add some relations before exporting to an image.",
|
||||
"Model Empty",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
|
@ -62,11 +49,11 @@ public class ExportToImageAction extends AbstractAction {
|
|||
if (path != null) {
|
||||
fileChooser.setSelectedFile(new File(path));
|
||||
}
|
||||
int choice = fileChooser.showSaveDialog(this.diagramPanel);
|
||||
int choice = fileChooser.showSaveDialog(dp);
|
||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||
File chosenFile = fileChooser.getSelectedFile();
|
||||
if (chosenFile == null || chosenFile.isDirectory()) {
|
||||
JOptionPane.showMessageDialog(fileChooser, "The selected file cannot be written to.", "Invalid File", JOptionPane.WARNING_MESSAGE);
|
||||
JOptionPane.showMessageDialog(dp, "The selected file cannot be written to.", "Invalid File", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
int i = chosenFile.getName().lastIndexOf('.');
|
||||
|
@ -76,13 +63,13 @@ public class ExportToImageAction extends AbstractAction {
|
|||
} else {
|
||||
chosenFile = new File(chosenFile.getParent(), chosenFile.getName() + '.' + extension);
|
||||
}
|
||||
String input = JOptionPane.showInputDialog(this.diagramPanel, "Choose a scale for the image.", "3.0");
|
||||
String input = JOptionPane.showInputDialog(dp, "Choose a scale for the image.", "3.0");
|
||||
float scale;
|
||||
try {
|
||||
scale = Float.parseFloat(input);
|
||||
if (scale <= 0.0f || scale > 64.0f) throw new IllegalArgumentException();
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(this.diagramPanel, "Invalid scale value. Should be a positive number less than 64.", "Invalid Scale", JOptionPane.WARNING_MESSAGE);
|
||||
JOptionPane.showMessageDialog(dp, "Invalid scale value. Should be a positive number less than 64.", "Invalid Scale", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -92,7 +79,7 @@ public class ExportToImageAction extends AbstractAction {
|
|||
ImageIO.write(render, extension, chosenFile);
|
||||
prefs.put(LAST_EXPORT_LOCATION_KEY, chosenFile.getAbsolutePath());
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
dp,
|
||||
"Image export completed in " + String.format("%.4f", durationSeconds) + " seconds.\n" +
|
||||
"Resolution: " + render.getWidth() + "x" + render.getHeight(),
|
||||
"Image Export Complete",
|
||||
|
@ -111,11 +98,12 @@ public class ExportToImageAction extends AbstractAction {
|
|||
* @return The image which was rendered.
|
||||
*/
|
||||
private BufferedImage renderModel(float scale) {
|
||||
MappingModel model = getDiagramPanel().getModel();
|
||||
// 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);
|
||||
final Rectangle bounds = model.getViewModel().getBounds(g2d);
|
||||
bounds.width *= scale;
|
||||
bounds.height *= scale;
|
||||
|
||||
|
@ -134,13 +122,13 @@ public class ExportToImageAction extends AbstractAction {
|
|||
DiagramPanel.prepareGraphics(g2d);
|
||||
|
||||
// Render the model.
|
||||
boolean lolcat = LolcatAction.getInstance().isLolcatEnabled(); // save previous lolcat mode
|
||||
LolcatAction.getInstance().setLolcatEnabled(false);
|
||||
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)));
|
||||
LolcatAction.getInstance().setLolcatEnabled(lolcat); // revert previous lolcat mode
|
||||
boolean lolcat = model.isLolcatEnabled(); // save previous lolcat mode
|
||||
model.setLolcatEnabled(false);
|
||||
List<Relation> selectedRelations = model.getSelectedRelations();
|
||||
model.getSelectedRelations().forEach(r -> r.setSelected(false));
|
||||
new MappingModelViewModel(model).draw(g2d);
|
||||
model.getRelations().forEach(r -> r.setSelected(selectedRelations.contains(r)));
|
||||
model.setLolcatEnabled(lolcat); // revert previous lolcat mode
|
||||
|
||||
// Revert to the normal image space, and render a watermark.
|
||||
g2d.setTransform(originalTransform);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -16,27 +15,24 @@ import java.net.URISyntaxException;
|
|||
/**
|
||||
* An action which, when performed, opens a view that displays an HTML document.
|
||||
*/
|
||||
public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
||||
public abstract class HtmlDocumentViewerAction extends DiagramPanelAction {
|
||||
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, DiagramPanel diagramPanel) {
|
||||
this(name, resourceFileName, Dialog.ModalityType.APPLICATION_MODAL, diagramPanel);
|
||||
}
|
||||
|
||||
public HtmlDocumentViewerAction(String name, String resourceFileName, Dialog.ModalityType modalityType) {
|
||||
super(name);
|
||||
public HtmlDocumentViewerAction(String name, String resourceFileName, Dialog.ModalityType modalityType, DiagramPanel diagramPanel) {
|
||||
super(name, diagramPanel);
|
||||
this.resourceFileName = resourceFileName;
|
||||
this.modalityType = modalityType;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JDialog dialog = new JDialog(
|
||||
SwingUtilities.getWindowAncestor(this.diagramPanel),
|
||||
SwingUtilities.getWindowAncestor(getDiagramPanel()),
|
||||
(String) this.getValue(NAME),
|
||||
this.modalityType
|
||||
);
|
||||
|
@ -63,7 +59,7 @@ public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
|||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"An error occured:\n" + ex.getMessage(),
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
|
@ -77,7 +73,7 @@ public abstract class HtmlDocumentViewerAction extends AbstractAction {
|
|||
dialog.setMaximumSize(new Dimension(600, 800));
|
||||
dialog.setPreferredSize(new Dimension(600, 800));
|
||||
dialog.pack();
|
||||
dialog.setLocationRelativeTo(this.diagramPanel);
|
||||
dialog.setLocationRelativeTo(getDiagramPanel());
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
public class InstructionsAction extends HtmlDocumentViewerAction {
|
||||
private static InstructionsAction instance;
|
||||
|
||||
public static InstructionsAction getInstance() {
|
||||
if (instance == null) instance = new InstructionsAction();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public InstructionsAction() {
|
||||
super("Instructions", "html/instructions.html");
|
||||
public InstructionsAction(DiagramPanel diagramPanel) {
|
||||
super("Instructions", "html/instructions.html", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Instructions for how to use this program.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.MapperFeature;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
|
@ -19,22 +18,11 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class LoadAction extends AbstractAction {
|
||||
public class LoadAction extends DiagramPanelAction {
|
||||
private static final String LAST_LOAD_LOCATION_KEY = "lastLoadLocation";
|
||||
|
||||
private static LoadAction instance;
|
||||
public static LoadAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new LoadAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public LoadAction() {
|
||||
super("Load");
|
||||
public LoadAction(DiagramPanel diagramPanel) {
|
||||
super("Load", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Load a saved diagram.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
@ -52,7 +40,7 @@ public class LoadAction extends AbstractAction {
|
|||
if (path != null) {
|
||||
fileChooser.setSelectedFile(new File(path));
|
||||
}
|
||||
int choice = fileChooser.showOpenDialog(this.diagramPanel);
|
||||
int choice = fileChooser.showOpenDialog(getDiagramPanel());
|
||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||
File chosenFile = fileChooser.getSelectedFile();
|
||||
if (chosenFile == null || chosenFile.isDirectory() || !chosenFile.exists() || !chosenFile.canRead()) {
|
||||
|
@ -65,7 +53,7 @@ public class LoadAction extends AbstractAction {
|
|||
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
|
||||
.build();
|
||||
JsonNode data = mapper.readValue(fis, JsonNode.class);
|
||||
this.diagramPanel.setModel(MappingModel.fromJson((ObjectNode) data));
|
||||
getDiagramPanel().setModel(MappingModel.fromJson((ObjectNode) data));
|
||||
prefs.put(LAST_LOAD_LOCATION_KEY, chosenFile.getAbsolutePath());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
|
|
@ -1,28 +1,14 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.*;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class LoadSampleModelAction extends AbstractAction {
|
||||
private static LoadSampleModelAction instance;
|
||||
|
||||
public static LoadSampleModelAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new LoadSampleModelAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public LoadSampleModelAction() {
|
||||
super("Load Sample Model");
|
||||
public class LoadSampleModelAction extends DiagramPanelAction {
|
||||
public LoadSampleModelAction(DiagramPanel diagramPanel) {
|
||||
super("Load Sample Model", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Loads a sample ER-mapping model.");
|
||||
}
|
||||
|
||||
|
@ -38,6 +24,6 @@ public class LoadSampleModelAction extends AbstractAction {
|
|||
r1.addAttribute(new Attribute(r1, AttributeType.PLAIN, "purchasedAt"));
|
||||
r1.addAttribute(new ForeignKeyAttribute(r1, AttributeType.PLAIN, "typeName", "AirplaneType", "name"));
|
||||
model.addRelation(r1);
|
||||
this.diagramPanel.setModel(model);
|
||||
getDiagramPanel().setModel(model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class LocalAction extends AbstractAction {
|
||||
@Setter
|
||||
@Getter
|
||||
private Point location;
|
||||
|
||||
public LocalAction(String name, Point location) {
|
||||
super(name);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public LocalAction(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public boolean hasLocation() {
|
||||
return this.location != null;
|
||||
}
|
||||
}
|
|
@ -1,37 +1,20 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class LolcatAction extends AbstractAction {
|
||||
private static LolcatAction instance;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean lolcatEnabled = false;
|
||||
|
||||
public static LolcatAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new LolcatAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public LolcatAction() {
|
||||
super("Toggle Lolcat Mode");
|
||||
public class LolcatAction extends DiagramPanelAction {
|
||||
public LolcatAction(DiagramPanel diagramPanel) {
|
||||
super("Toggle Lolcat Mode", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Does some wacky color stuff.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
lolcatEnabled = ((AbstractButton)actionEvent.getSource()).getModel().isSelected();
|
||||
diagramPanel.repaint();
|
||||
boolean lolcatEnabled = ((AbstractButton)actionEvent.getSource()).getModel().isSelected();
|
||||
getDiagramPanel().getModel().setLolcatEnabled(lolcatEnabled);
|
||||
getDiagramPanel().repaint();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class MappingAlgorithmHelpAction extends HtmlDocumentViewerAction {
|
||||
private static MappingAlgorithmHelpAction instance;
|
||||
|
||||
public static MappingAlgorithmHelpAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new MappingAlgorithmHelpAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MappingAlgorithmHelpAction() {
|
||||
super("Mapping Algorithm Help", "html/er_mapping_algorithm.html", Dialog.ModalityType.DOCUMENT_MODAL);
|
||||
public MappingAlgorithmHelpAction(DiagramPanel diagramPanel) {
|
||||
super("Mapping Algorithm Help", "html/er_mapping_algorithm.html", Dialog.ModalityType.DOCUMENT_MODAL, diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Shows a quick guide on how to map from an ER model to a schema.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
|
@ -9,27 +8,15 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class NewModelAction extends AbstractAction {
|
||||
private static NewModelAction instance;
|
||||
|
||||
public static NewModelAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new NewModelAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public NewModelAction() {
|
||||
super("New Model");
|
||||
public class NewModelAction extends DiagramPanelAction {
|
||||
public NewModelAction(DiagramPanel diagramPanel) {
|
||||
super("New Model", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Create a new model.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
this.diagramPanel.setModel(new MappingModel());
|
||||
getDiagramPanel().setModel(new MappingModel());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ import com.fasterxml.jackson.databind.MapperFeature;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -18,25 +16,11 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class SaveAction extends AbstractAction {
|
||||
public class SaveAction extends DiagramPanelAction {
|
||||
private static final String LAST_SAVE_LOCATION_KEY = "lastSaveLocation";
|
||||
|
||||
private static SaveAction instance;
|
||||
public static SaveAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new SaveAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public SaveAction() {
|
||||
super("Save");
|
||||
public SaveAction(DiagramPanel diagramPanel) {
|
||||
super("Save", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Save the current diagram to a file.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
@ -54,17 +38,18 @@ public class SaveAction extends AbstractAction {
|
|||
if (path != null) {
|
||||
fileChooser.setSelectedFile(new File(path));
|
||||
}
|
||||
int choice = fileChooser.showSaveDialog(this.diagramPanel);
|
||||
DiagramPanel dp = getDiagramPanel();
|
||||
int choice = fileChooser.showSaveDialog(dp);
|
||||
if (choice == JFileChooser.APPROVE_OPTION) {
|
||||
File chosenFile = fileChooser.getSelectedFile();
|
||||
if (chosenFile == null || chosenFile.isDirectory()) {
|
||||
JOptionPane.showMessageDialog(this.diagramPanel, "The selected file cannot be written to.", "Invalid File", JOptionPane.WARNING_MESSAGE);
|
||||
JOptionPane.showMessageDialog(dp, "The selected file cannot be written to.", "Invalid File", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (!chosenFile.exists() && !chosenFile.getName().endsWith(".json")) {
|
||||
chosenFile = new File(chosenFile.getParent(), chosenFile.getName() + ".json");
|
||||
} else if (chosenFile.exists()) {
|
||||
int result = JOptionPane.showConfirmDialog(this.diagramPanel, "Are you sure you want overwrite this file?", "Overwrite", JOptionPane.YES_NO_OPTION);
|
||||
int result = JOptionPane.showConfirmDialog(dp, "Are you sure you want overwrite this file?", "Overwrite", JOptionPane.YES_NO_OPTION);
|
||||
if (result == JOptionPane.NO_OPTION) {
|
||||
return;
|
||||
}
|
||||
|
@ -74,12 +59,12 @@ public class SaveAction extends AbstractAction {
|
|||
.configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
|
||||
.build();
|
||||
mapper.writeValue(fos, this.model.toJson(mapper));
|
||||
mapper.writeValue(fos, dp.getModel().toJson(mapper));
|
||||
prefs.put(LAST_SAVE_LOCATION_KEY, chosenFile.getAbsolutePath());
|
||||
JOptionPane.showMessageDialog(fileChooser, "File saved successfully.", "Success", JOptionPane.INFORMATION_MESSAGE);
|
||||
JOptionPane.showMessageDialog(dp, "File saved successfully.", "Success", 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);
|
||||
JOptionPane.showMessageDialog(dp, "An error occurred and the file could not be saved:\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,19 @@
|
|||
package nl.andrewlalis.erme.control.actions;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class VisualizeReferencesAction extends AbstractAction {
|
||||
private static VisualizeReferencesAction instance;
|
||||
|
||||
public static VisualizeReferencesAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new VisualizeReferencesAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean referenceVisualizationEnabled = false;
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public VisualizeReferencesAction() {
|
||||
super("Toggle Reference Visualization");
|
||||
public class VisualizeReferencesAction extends DiagramPanelAction {
|
||||
public VisualizeReferencesAction(DiagramPanel diagramPanel) {
|
||||
super("Toggle Reference Visualization", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Shows/hides visualization of the references between attributes.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
referenceVisualizationEnabled = ((AbstractButton)e.getSource()).getModel().isSelected();
|
||||
diagramPanel.repaint();
|
||||
getDiagramPanel().getModel().setReferenceVisualizationEnabled(((AbstractButton)e.getSource()).getModel().isSelected());
|
||||
getDiagramPanel().repaint();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package nl.andrewlalis.erme.control.actions.edits;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||
import nl.andrewlalis.erme.model.*;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
|
@ -10,36 +10,23 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class AddAttributeAction extends AbstractAction {
|
||||
private static AddAttributeAction instance;
|
||||
|
||||
public static AddAttributeAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new AddAttributeAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public AddAttributeAction() {
|
||||
super("Add Attribute");
|
||||
public class AddAttributeAction extends DiagramPanelAction {
|
||||
public AddAttributeAction(DiagramPanel diagramPanel) {
|
||||
super("Add Attribute", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Add an attribute to the selected relation.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<Relation> selectedRelations = this.model.getSelectedRelations();
|
||||
DiagramPanel dp = getDiagramPanel();
|
||||
MappingModel model = dp.getModel();
|
||||
List<Relation> selectedRelations = model.getSelectedRelations();
|
||||
if (selectedRelations.size() != 1) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
dp,
|
||||
"A single relation must be selected to add an attribute.",
|
||||
"Single Relation Required",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
|
@ -48,11 +35,10 @@ public class AddAttributeAction extends AbstractAction {
|
|||
}
|
||||
Relation r = selectedRelations.get(0);
|
||||
Attribute createdAttribute;
|
||||
Component source = this.diagramPanel;
|
||||
String name = JOptionPane.showInputDialog(source, "Enter the name of the attribute.", "Attribute Name", JOptionPane.PLAIN_MESSAGE);
|
||||
String name = JOptionPane.showInputDialog(dp, "Enter the name of the attribute.", "Attribute Name", JOptionPane.PLAIN_MESSAGE);
|
||||
if (name == null) return;
|
||||
Integer index = (Integer) JOptionPane.showInputDialog(
|
||||
source,
|
||||
dp,
|
||||
"Select the index to insert this attribute at.",
|
||||
"Attribute Index",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
@ -62,7 +48,7 @@ public class AddAttributeAction extends AbstractAction {
|
|||
);
|
||||
if (index == null) return;
|
||||
AttributeType type = (AttributeType) JOptionPane.showInputDialog(
|
||||
source,
|
||||
dp,
|
||||
"Select the type this attribute is.",
|
||||
"Attribute Type",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
@ -72,7 +58,7 @@ public class AddAttributeAction extends AbstractAction {
|
|||
);
|
||||
if (type == null) return;
|
||||
boolean shouldUseForeignKey = ((String) JOptionPane.showInputDialog(
|
||||
source,
|
||||
dp,
|
||||
"Is this attribute a foreign key?",
|
||||
"Foreign Key",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
@ -81,27 +67,27 @@ public class AddAttributeAction extends AbstractAction {
|
|||
"No"
|
||||
)).equalsIgnoreCase("yes");
|
||||
if (shouldUseForeignKey) {
|
||||
if (this.model.getRelations().size() < 2) {
|
||||
JOptionPane.showMessageDialog(source, "There should be at least 2 relations present in the model.", "Not Enough Relations", JOptionPane.WARNING_MESSAGE);
|
||||
if (model.getRelations().size() < 2) {
|
||||
JOptionPane.showMessageDialog(dp, "There should be at least 2 relations present in the model.", "Not Enough Relations", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
Relation fkRelation = (Relation) JOptionPane.showInputDialog(
|
||||
source,
|
||||
dp,
|
||||
"Select the relation that this foreign key references.",
|
||||
"Foreign Key Relation Reference",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
null,
|
||||
this.model.getRelations().toArray(new Relation[0]),
|
||||
this.model.getRelations().stream().findFirst().orElse(null)
|
||||
model.getRelations().toArray(new Relation[0]),
|
||||
model.getRelations().stream().findFirst().orElse(null)
|
||||
);
|
||||
if (fkRelation == null) return;
|
||||
List<Attribute> eligibleAttributes = fkRelation.getAttributes();
|
||||
if (eligibleAttributes.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(source, "There are no referencable attributes in the selected relation.", "No Referencable Attributes", JOptionPane.WARNING_MESSAGE);
|
||||
JOptionPane.showMessageDialog(dp, "There are no referencable attributes in the selected relation.", "No Referencable Attributes", JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
Attribute fkAttribute = (Attribute) JOptionPane.showInputDialog(
|
||||
source,
|
||||
dp,
|
||||
"Select the attribute that this foreign key references.",
|
||||
"Foreign Key Attribute Reference",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package nl.andrewlalis.erme.control.actions.edits;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.control.actions.LocalAction;
|
||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
@ -12,57 +11,45 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class AddRelationAction extends LocalAction {
|
||||
private static AddRelationAction instance;
|
||||
public static AddRelationAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new AddRelationAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public AddRelationAction() {
|
||||
super("Add Relation");
|
||||
public class AddRelationAction extends DiagramPanelAction {
|
||||
public AddRelationAction(DiagramPanel diagramPanel) {
|
||||
super("Add Relation", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Add a new relation to the diagram.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DiagramPanel dp = getDiagramPanel();
|
||||
MappingModel model = dp.getModel();
|
||||
String name = JOptionPane.showInputDialog(
|
||||
this.diagramPanel,
|
||||
dp,
|
||||
"Enter the name of the relation.",
|
||||
"Add Relation",
|
||||
JOptionPane.PLAIN_MESSAGE
|
||||
);
|
||||
if (name != null) {
|
||||
final boolean isFirstRelation = this.model.getRelations().isEmpty();
|
||||
final boolean isFirstRelation = model.getRelations().isEmpty();
|
||||
Point p;
|
||||
if (this.hasLocation()) {
|
||||
if (model.getLastInteractionPoint() != null) {
|
||||
p = new Point(
|
||||
this.getLocation().x - this.diagramPanel.getPanningTranslation().x,
|
||||
this.getLocation().y - this.diagramPanel.getPanningTranslation().y
|
||||
model.getLastInteractionPoint().x - dp.getPanningTranslation().x,
|
||||
model.getLastInteractionPoint().y - dp.getPanningTranslation().y
|
||||
);
|
||||
} else if (isFirstRelation) {
|
||||
p = new Point(100, 100);
|
||||
} else {
|
||||
Rectangle bounds = this.model.getRelationBounds();
|
||||
Rectangle bounds = model.getRelationBounds();
|
||||
p = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
|
||||
}
|
||||
Relation r = new Relation(this.model, p, name);
|
||||
this.model.getSelectedRelations().forEach(rl -> rl.setSelected(false));
|
||||
Relation r = new Relation(model, p, name);
|
||||
model.getSelectedRelations().forEach(rl -> rl.setSelected(false));
|
||||
r.setSelected(true);
|
||||
this.model.addRelation(r);
|
||||
model.addRelation(r);
|
||||
if (isFirstRelation) {
|
||||
this.model.normalizeRelationPositions();
|
||||
this.diagramPanel.centerModel();
|
||||
this.diagramPanel.repaint();
|
||||
model.normalizeRelationPositions();
|
||||
dp.centerModel();
|
||||
dp.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package nl.andrewlalis.erme.control.actions.edits;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||
import nl.andrewlalis.erme.model.Attribute;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
|
@ -12,33 +11,19 @@ import java.awt.event.InputEvent;
|
|||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoveAttributeAction extends AbstractAction {
|
||||
private static RemoveAttributeAction instance;
|
||||
|
||||
public static RemoveAttributeAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new RemoveAttributeAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public RemoveAttributeAction() {
|
||||
super("Remove Attribute");
|
||||
public class RemoveAttributeAction extends DiagramPanelAction {
|
||||
public RemoveAttributeAction(DiagramPanel diagramPanel) {
|
||||
super("Remove Attribute", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Remove an attribute from a relation.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<Relation> selectedRelations = this.model.getSelectedRelations();
|
||||
List<Relation> selectedRelations = getDiagramPanel().getModel().getSelectedRelations();
|
||||
if (selectedRelations.size() != 1 || selectedRelations.get(0).getAttributes().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"A single relation with at least one attribute must be selected to remove an attribute.",
|
||||
"Single Relation With Attribute Required",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
|
@ -47,7 +32,7 @@ public class RemoveAttributeAction extends AbstractAction {
|
|||
}
|
||||
Relation r = selectedRelations.get(0);
|
||||
Attribute attribute = (Attribute) JOptionPane.showInputDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"Select the attribute to remove.",
|
||||
"Select Attribute",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
|
|
|
@ -1,50 +1,36 @@
|
|||
package nl.andrewlalis.erme.control.actions.edits;
|
||||
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class RemoveRelationAction extends AbstractAction {
|
||||
private static RemoveRelationAction instance;
|
||||
|
||||
public static RemoveRelationAction getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new RemoveRelationAction();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Setter
|
||||
private MappingModel model;
|
||||
@Setter
|
||||
private DiagramPanel diagramPanel;
|
||||
|
||||
public RemoveRelationAction() {
|
||||
super("Remove Relation");
|
||||
public class RemoveRelationAction extends DiagramPanelAction {
|
||||
public RemoveRelationAction(DiagramPanel diagramPanel) {
|
||||
super("Remove Relation", diagramPanel);
|
||||
this.putValue(SHORT_DESCRIPTION, "Remove a relation from the diagram.");
|
||||
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (this.model.getSelectedRelations().isEmpty()) {
|
||||
MappingModel model = getDiagramPanel().getModel();
|
||||
if (model.getSelectedRelations().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
this.diagramPanel,
|
||||
getDiagramPanel(),
|
||||
"No relations selected. Select at least one relation to remove.",
|
||||
"No Relations Selected",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
);
|
||||
return;
|
||||
}
|
||||
for (Relation r : this.model.getSelectedRelations()) {
|
||||
this.model.removeRelation(r);
|
||||
for (Relation r : model.getSelectedRelations()) {
|
||||
model.removeRelation(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ import java.awt.event.MouseAdapter;
|
|||
import java.awt.event.MouseEvent;
|
||||
|
||||
public class DiagramMouseListener extends MouseAdapter {
|
||||
private final MappingModel model;
|
||||
private final DiagramPanel diagramPanel;
|
||||
private Point mouseDragStart;
|
||||
|
||||
public DiagramMouseListener(MappingModel model) {
|
||||
this.model = model;
|
||||
public DiagramMouseListener(DiagramPanel diagramPanel) {
|
||||
this.diagramPanel = diagramPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,13 +38,14 @@ public class DiagramMouseListener extends MouseAdapter {
|
|||
|
||||
final boolean isCtrlDown = (e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
|
||||
final boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
|
||||
MappingModel model = this.diagramPanel.getModel();
|
||||
|
||||
if (!isShiftDown && !isCtrlDown) {// A simple click anywhere should reset selection.
|
||||
this.model.getRelations().forEach(r -> r.setSelected(false));
|
||||
model.getRelations().forEach(r -> r.setSelected(false));
|
||||
}
|
||||
|
||||
if (!isShiftDown) {// If the user clicked or CTRL+clicked, try and select the relation they clicked on.
|
||||
for (Relation r : this.model.getRelations()) {
|
||||
for (Relation r : model.getRelations()) {
|
||||
if (r.getViewModel().getBounds(g).contains(modelX, modelY)) {
|
||||
r.setSelected(!r.isSelected());
|
||||
break;
|
||||
|
@ -54,11 +55,12 @@ public class DiagramMouseListener extends MouseAdapter {
|
|||
|
||||
// If the user right-clicked, show a popup menu.
|
||||
if (e.getButton() == MouseEvent.BUTTON3) {
|
||||
DiagramPopupMenu popupMenu = new DiagramPopupMenu(this.model, e);
|
||||
model.setLastInteractionPoint(e.getPoint());
|
||||
DiagramPopupMenu popupMenu = new DiagramPopupMenu(this.diagramPanel);
|
||||
popupMenu.show(panel, e.getX(), e.getY());
|
||||
}
|
||||
|
||||
this.model.fireChangedEvent();
|
||||
model.fireChangedEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,13 +74,14 @@ public class DiagramMouseListener extends MouseAdapter {
|
|||
final int dy = this.mouseDragStart.y - e.getY();
|
||||
final boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
|
||||
boolean changed = false;
|
||||
MappingModel model = this.diagramPanel.getModel();
|
||||
|
||||
if (isShiftDown) {
|
||||
final DiagramPanel panel = (DiagramPanel) e.getSource();
|
||||
panel.translate(-dx, -dy);
|
||||
panel.repaint();
|
||||
System.out.println(e);
|
||||
this.diagramPanel.translate(-dx, -dy);
|
||||
this.diagramPanel.repaint();
|
||||
} else {
|
||||
for (Relation r : this.model.getRelations()) {
|
||||
for (Relation r : model.getRelations()) {
|
||||
if (r.isSelected()) {
|
||||
r.setPosition(new Point(r.getPosition().x - dx, r.getPosition().y - dy));
|
||||
changed = true;
|
||||
|
@ -87,7 +90,7 @@ public class DiagramMouseListener extends MouseAdapter {
|
|||
}
|
||||
|
||||
if (changed) {
|
||||
this.model.fireChangedEvent();
|
||||
model.fireChangedEvent();
|
||||
}
|
||||
this.mouseDragStart = e.getPoint();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import nl.andrewlalis.erme.view.view_models.MappingModelViewModel;
|
||||
import nl.andrewlalis.erme.view.view_models.ViewModel;
|
||||
|
||||
|
@ -23,6 +24,16 @@ public class MappingModel implements Viewable {
|
|||
|
||||
private transient final Set<ModelChangeListener> changeListeners;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private transient Point lastInteractionPoint = null;
|
||||
@Getter
|
||||
@Setter
|
||||
private transient boolean lolcatEnabled = false;
|
||||
@Getter
|
||||
@Setter
|
||||
private transient boolean referenceVisualizationEnabled = false;
|
||||
|
||||
public MappingModel() {
|
||||
this.relations = new HashSet<>();
|
||||
this.changeListeners = new HashSet<>();
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
package nl.andrewlalis.erme.view;
|
||||
|
||||
import lombok.Getter;
|
||||
import nl.andrewlalis.erme.control.actions.*;
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddRelationAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveRelationAction;
|
||||
import nl.andrewlalis.erme.control.diagram.DiagramMouseListener;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.ModelChangeListener;
|
||||
|
@ -21,6 +16,10 @@ import java.awt.event.MouseMotionListener;
|
|||
* The main panel in which the ER Mapping diagram is displayed.
|
||||
*/
|
||||
public class DiagramPanel extends JPanel implements ModelChangeListener {
|
||||
/**
|
||||
* The model for the application. This is the main location from which to
|
||||
* obtain the model for use in actions.
|
||||
*/
|
||||
@Getter
|
||||
private MappingModel model;
|
||||
|
||||
|
@ -60,10 +59,10 @@ public class DiagramPanel extends JPanel implements ModelChangeListener {
|
|||
for (MouseMotionListener listener : this.getMouseMotionListeners()) {
|
||||
this.removeMouseMotionListener(listener);
|
||||
}
|
||||
DiagramMouseListener listener = new DiagramMouseListener(newModel);
|
||||
DiagramMouseListener listener = new DiagramMouseListener(this);
|
||||
this.addMouseListener(listener);
|
||||
this.addMouseMotionListener(listener);
|
||||
this.updateActionModels();
|
||||
this.updateActionModels(); // TODO: remove this once OrderableListPanel is cleaned up.
|
||||
newModel.addChangeListener(OrderableListPanel.getInstance());
|
||||
this.centerModel();
|
||||
this.repaint();
|
||||
|
@ -79,6 +78,9 @@ public class DiagramPanel extends JPanel implements ModelChangeListener {
|
|||
this.panningTranslation.y = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers the model in the panel, by adjusting the panning translation.
|
||||
*/
|
||||
public void centerModel() {
|
||||
if (this.getGraphics() == null) {
|
||||
return;
|
||||
|
@ -120,30 +122,7 @@ public class DiagramPanel extends JPanel implements ModelChangeListener {
|
|||
* TODO: Clean this up somehow!
|
||||
*/
|
||||
private void updateActionModels() {
|
||||
NewModelAction.getInstance().setDiagramPanel(this);
|
||||
SaveAction.getInstance().setModel(this.model);
|
||||
LoadAction.getInstance().setDiagramPanel(this);
|
||||
ExportToImageAction.getInstance().setModel(this.model);
|
||||
ExportToImageAction.getInstance().setDiagramPanel(this);
|
||||
AddRelationAction.getInstance().setModel(this.model);
|
||||
AddRelationAction.getInstance().setDiagramPanel(this);
|
||||
RemoveRelationAction.getInstance().setModel(this.model);
|
||||
RemoveRelationAction.getInstance().setDiagramPanel(this);
|
||||
AddAttributeAction.getInstance().setModel(this.model);
|
||||
AddAttributeAction.getInstance().setDiagramPanel(this);
|
||||
RemoveAttributeAction.getInstance().setModel(this.model);
|
||||
RemoveAttributeAction.getInstance().setDiagramPanel(this);
|
||||
LoadSampleModelAction.getInstance().setDiagramPanel(this);
|
||||
LolcatAction.getInstance().setDiagramPanel(this);
|
||||
VisualizeReferencesAction.getInstance().setDiagramPanel(this);
|
||||
AutoPositionAction.getInstance().setDiagramPanel(this);
|
||||
AutoPositionAction.getInstance().setModel(this.model);
|
||||
OrderableListPanel.getInstance().setModel(this.model);
|
||||
AboutAction.getInstance().setDiagramPanel(this);
|
||||
ExitAction.getInstance().setDiagramPanel(this);
|
||||
InstructionsAction.getInstance().setDiagramPanel(this);
|
||||
MappingAlgorithmHelpAction.getInstance().setDiagramPanel(this);
|
||||
SaveAction.getInstance().setDiagramPanel(this);
|
||||
}
|
||||
|
||||
public static void prepareGraphics(Graphics2D g) {
|
||||
|
|
|
@ -2,28 +2,27 @@ package nl.andrewlalis.erme.view;
|
|||
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddRelationAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveRelationAction;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
|
||||
public class DiagramPopupMenu extends JPopupMenu {
|
||||
public DiagramPopupMenu(MappingModel model, MouseEvent e) {
|
||||
List<Relation> selectedRelations = model.getSelectedRelations();
|
||||
AddRelationAction.getInstance().setLocation(e.getPoint());
|
||||
public DiagramPopupMenu(DiagramPanel diagramPanel) {
|
||||
List<Relation> selectedRelations = diagramPanel.getModel().getSelectedRelations();
|
||||
if (selectedRelations.size() == 0) {
|
||||
this.add(AddRelationAction.getInstance());
|
||||
this.add(new AddRelationAction(diagramPanel));
|
||||
}
|
||||
if (selectedRelations.size() > 0) {
|
||||
this.add(RemoveRelationAction.getInstance());
|
||||
this.add(new RemoveRelationAction(diagramPanel));
|
||||
}
|
||||
if (selectedRelations.size() == 1) {
|
||||
this.add(AddAttributeAction.getInstance());
|
||||
this.add(RemoveAttributeAction.getInstance());
|
||||
Relation relation = selectedRelations.get(0);
|
||||
this.add(new AddAttributeAction(diagramPanel));
|
||||
if (!relation.getAttributes().isEmpty()) {
|
||||
this.add(new RemoveRelationAction(diagramPanel));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ import java.io.InputStream;
|
|||
public class EditorFrame extends JFrame {
|
||||
public EditorFrame() {
|
||||
super("ER-Mapping Editor");
|
||||
this.setContentPane(new DiagramPanel(new MappingModel()));
|
||||
this.setJMenuBar(new EditorMenuBar());
|
||||
DiagramPanel diagramPanel = new DiagramPanel(new MappingModel());
|
||||
this.setContentPane(diagramPanel);
|
||||
this.setJMenuBar(new EditorMenuBar(diagramPanel));
|
||||
try {
|
||||
InputStream is = getClass().getClassLoader().getResourceAsStream("icon.png");
|
||||
if (is == null) {
|
||||
|
@ -26,7 +27,7 @@ public class EditorFrame extends JFrame {
|
|||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.setMinimumSize(new Dimension(400, 400));
|
||||
this.setMinimumSize(new Dimension(300, 300));
|
||||
this.setPreferredSize(new Dimension(800, 800));
|
||||
this.pack();
|
||||
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
|
|
@ -3,7 +3,6 @@ package nl.andrewlalis.erme.view;
|
|||
import nl.andrewlalis.erme.control.actions.*;
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.AddRelationAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveAttributeAction;
|
||||
import nl.andrewlalis.erme.control.actions.edits.RemoveRelationAction;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -12,51 +11,47 @@ import javax.swing.*;
|
|||
* The menu bar that's visible atop the application.
|
||||
*/
|
||||
public class EditorMenuBar extends JMenuBar {
|
||||
public EditorMenuBar() {
|
||||
this.add(this.buildFileMenu());
|
||||
this.add(this.buildEditMenu());
|
||||
this.add(this.buildViewMenu());
|
||||
this.add(this.buildHelpMenu());
|
||||
public EditorMenuBar(DiagramPanel diagramPanel) {
|
||||
this.add(this.buildFileMenu(diagramPanel));
|
||||
this.add(this.buildEditMenu(diagramPanel));
|
||||
this.add(this.buildViewMenu(diagramPanel));
|
||||
this.add(this.buildHelpMenu(diagramPanel));
|
||||
}
|
||||
|
||||
private JMenu buildFileMenu() {
|
||||
private JMenu buildFileMenu(DiagramPanel diagramPanel) {
|
||||
JMenu menu = new JMenu("File");
|
||||
menu.add(NewModelAction.getInstance());
|
||||
menu.add(SaveAction.getInstance());
|
||||
menu.add(LoadAction.getInstance());
|
||||
menu.add(new NewModelAction(diagramPanel));
|
||||
menu.add(new SaveAction(diagramPanel));
|
||||
menu.add(new LoadAction(diagramPanel));
|
||||
menu.addSeparator();
|
||||
menu.add(ExportToImageAction.getInstance());
|
||||
menu.add(new ExportToImageAction(diagramPanel));
|
||||
menu.addSeparator();
|
||||
menu.add(ExitAction.getInstance());
|
||||
menu.add(new ExitAction(diagramPanel));
|
||||
return menu;
|
||||
}
|
||||
|
||||
private JMenu buildEditMenu() {
|
||||
private JMenu buildEditMenu(DiagramPanel diagramPanel) {
|
||||
JMenu menu = new JMenu("Edit");
|
||||
menu.add(AddRelationAction.getInstance());
|
||||
menu.add(RemoveRelationAction.getInstance());
|
||||
menu.add(AddAttributeAction.getInstance());
|
||||
menu.add(RemoveAttributeAction.getInstance());
|
||||
menu.add(AutoPositionAction.getInstance());
|
||||
menu.addSeparator();
|
||||
menu.add(UndoAction.getInstance());
|
||||
menu.add(RedoAction.getInstance());
|
||||
menu.add(new AddRelationAction(diagramPanel));
|
||||
menu.add(new RemoveRelationAction(diagramPanel));
|
||||
menu.add(new AddAttributeAction(diagramPanel));
|
||||
menu.add(new RemoveRelationAction(diagramPanel));
|
||||
menu.add(new AutoPositionAction(diagramPanel));
|
||||
return menu;
|
||||
}
|
||||
|
||||
private JMenu buildViewMenu() {
|
||||
private JMenu buildViewMenu(DiagramPanel diagramPanel) {
|
||||
JMenu menu = new JMenu("View");
|
||||
menu.add(new JCheckBoxMenuItem(LolcatAction.getInstance()));
|
||||
menu.add(new JCheckBoxMenuItem(VisualizeReferencesAction.getInstance()));
|
||||
menu.add(new JCheckBoxMenuItem(new LolcatAction(diagramPanel)));
|
||||
menu.add(new JCheckBoxMenuItem(new VisualizeReferencesAction(diagramPanel)));
|
||||
return menu;
|
||||
}
|
||||
|
||||
private JMenu buildHelpMenu() {
|
||||
private JMenu buildHelpMenu(DiagramPanel diagramPanel) {
|
||||
JMenu menu = new JMenu("Help");
|
||||
menu.add(InstructionsAction.getInstance());
|
||||
menu.add(MappingAlgorithmHelpAction.getInstance());
|
||||
menu.add(LoadSampleModelAction.getInstance());
|
||||
menu.add(AboutAction.getInstance());
|
||||
menu.add(new InstructionsAction(diagramPanel));
|
||||
menu.add(new MappingAlgorithmHelpAction(diagramPanel));
|
||||
menu.add(new LoadSampleModelAction(diagramPanel));
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Set;
|
|||
/**
|
||||
* A panel to be used in a popup that has a OrderableListModel implemented. Implements ModelChangeListener to be able
|
||||
* to update the list of relations when new ones are added or ones are removed.
|
||||
* TODO: Refactor this to not use static singleton instance.
|
||||
*/
|
||||
public class OrderableListPanel extends JPanel implements ModelChangeListener {
|
||||
private static OrderableListPanel instance;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package nl.andrewlalis.erme.view.view_models;
|
||||
|
||||
import nl.andrewlalis.erme.control.actions.LolcatAction;
|
||||
import nl.andrewlalis.erme.model.Attribute;
|
||||
import nl.andrewlalis.erme.model.AttributeType;
|
||||
import nl.andrewlalis.erme.model.ForeignKeyAttribute;
|
||||
|
@ -46,7 +45,7 @@ public class AttributeViewModel implements ViewModel {
|
|||
}
|
||||
|
||||
private Color getBackgroundColor(int x, int y, Graphics2D g) {
|
||||
if (!LolcatAction.getInstance().isLolcatEnabled()) return BACKGROUND_COLOR;
|
||||
if (!attribute.getRelation().getModel().isLolcatEnabled()) return BACKGROUND_COLOR;
|
||||
Point offset = g.getClipBounds().getLocation();
|
||||
g.translate(offset.x, offset.y);
|
||||
Dimension viewportSize = g.getClipBounds().getSize();
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package nl.andrewlalis.erme.view.view_models;
|
||||
|
||||
import nl.andrewlalis.erme.control.actions.VisualizeReferencesAction;
|
||||
import nl.andrewlalis.erme.model.Attribute;
|
||||
import nl.andrewlalis.erme.model.ForeignKeyAttribute;
|
||||
import nl.andrewlalis.erme.model.MappingModel;
|
||||
import nl.andrewlalis.erme.model.Relation;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
|
@ -22,9 +20,7 @@ public class MappingModelViewModel implements ViewModel {
|
|||
|
||||
@Override
|
||||
public void draw(Graphics2D g) {
|
||||
if (VisualizeReferencesAction.getInstance().isReferenceVisualizationEnabled()) {
|
||||
visualizeReferences(g);
|
||||
}
|
||||
if (model.isReferenceVisualizationEnabled()) visualizeReferences(g);
|
||||
for (Relation r : this.model.getRelations()) {
|
||||
r.getViewModel().draw(g);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
<body>
|
||||
|
||||
<h1>Entity-Relation Mapping Editor</h1>
|
||||
<p>Created by <a href="https://github.com/andrewlalis">@andrewlalis</a></p>
|
||||
|
||||
<p><em>A simple UI for editing entity-relation mapping diagrams.</em></p>
|
||||
<p>Created by <a href="https://github.com/andrewlalis">Andrew Lalis</a></p>
|
||||
<p>And with generous contributions by</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/bjornpijnacker">Bjorn Pijnacker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Have you noticed any unexpected behavior? Is there something you think would make a good addition to this application?
|
||||
|
@ -27,6 +31,9 @@
|
|||
<li>
|
||||
The <em>Edit</em> menu contains options for making changes to the current model, such as adding or removing relations and attributes, or undoing/redoing actions.
|
||||
</li>
|
||||
<li>
|
||||
The <em>View</em> menu contains options for changing how the model is viewed.
|
||||
</li>
|
||||
<li>
|
||||
The <em>Help</em> menu contains some items with additional information about the application, like this help page and a simple <em>About</em> popup with version information. There's also a <em>Load Sample Model</em> option, which will load a very basic sample model into the application that you are free to mess around with.
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue