From fa87c325911e66a695254c41ec297968c652df07 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 27 Oct 2021 17:31:18 +0200 Subject: [PATCH] Added visualization of relations, transparent selection and attribute backgrounds --- README.md | 11 +++--- .../actions/VisualizeReferencesAction.java | 37 +++++++++++++++++++ .../andrewlalis/erme/view/DiagramPanel.java | 1 + .../andrewlalis/erme/view/EditorMenuBar.java | 9 ++++- .../view/view_models/AttributeViewModel.java | 2 +- .../view_models/MappingModelViewModel.java | 26 +++++++++++++ .../view/view_models/RelationViewModel.java | 2 +- 7 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 src/main/java/nl/andrewlalis/erme/control/actions/VisualizeReferencesAction.java diff --git a/README.md b/README.md index f055f68..f9c9583 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ This program is distributed as an executable **jar** file. You can find the late Simply double-click on the jar file, or execute `java -jar ` from the command line (where `` is replaced with the path to your actual jar file). ![window screenshot](https://raw.githubusercontent.com/andrewlalis/EntityRelationMappingEditor/main/design/main_interface.PNG) +> The above image shows the application's user-interface. -## How to Use +## Instructions The interface and menus should be pretty self-explanatory, but here are some tips to get you started: * Click on a relation to select it. * You can CTRL + click to select multiple relations. @@ -16,7 +17,7 @@ The interface and menus should be pretty self-explanatory, but here are some tip * Right-click on different areas to access context menus with some helpful actions. * When exporting the model to an image, be sure to add the desired image file extension (`.png`, `.jpg`, `.bmp`, etc.), or the application will default to `.png`. -## Sample Exported Image -Here's a sample of an exported diagram. - -![sample diagram export](https://raw.githubusercontent.com/andrewlalis/EntityRelationMappingEditor/main/design/sample_export.png) +## Contributing +This is an open-source project, and gladly accepts contributions in terms of new features, bug fixes, suggestions, bug reports, and more. +* [Create a new issue](https://github.com/andrewlalis/EntityRelationMappingEditor/issues) if you'd like to make a suggestion, or report a bug. +* Fork the repository, make your changes, and submit them as a pull request. diff --git a/src/main/java/nl/andrewlalis/erme/control/actions/VisualizeReferencesAction.java b/src/main/java/nl/andrewlalis/erme/control/actions/VisualizeReferencesAction.java new file mode 100644 index 0000000..9473d17 --- /dev/null +++ b/src/main/java/nl/andrewlalis/erme/control/actions/VisualizeReferencesAction.java @@ -0,0 +1,37 @@ +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"); + 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(); + } +} diff --git a/src/main/java/nl/andrewlalis/erme/view/DiagramPanel.java b/src/main/java/nl/andrewlalis/erme/view/DiagramPanel.java index 7e3735a..c28cb17 100644 --- a/src/main/java/nl/andrewlalis/erme/view/DiagramPanel.java +++ b/src/main/java/nl/andrewlalis/erme/view/DiagramPanel.java @@ -135,6 +135,7 @@ public class DiagramPanel extends JPanel implements ModelChangeListener { 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); diff --git a/src/main/java/nl/andrewlalis/erme/view/EditorMenuBar.java b/src/main/java/nl/andrewlalis/erme/view/EditorMenuBar.java index 90114c0..96a7604 100644 --- a/src/main/java/nl/andrewlalis/erme/view/EditorMenuBar.java +++ b/src/main/java/nl/andrewlalis/erme/view/EditorMenuBar.java @@ -15,6 +15,7 @@ public class EditorMenuBar extends JMenuBar { public EditorMenuBar() { this.add(this.buildFileMenu()); this.add(this.buildEditMenu()); + this.add(this.buildViewMenu()); this.add(this.buildHelpMenu()); } @@ -36,7 +37,6 @@ public class EditorMenuBar extends JMenuBar { menu.add(RemoveRelationAction.getInstance()); menu.add(AddAttributeAction.getInstance()); menu.add(RemoveAttributeAction.getInstance()); - menu.add(new JCheckBoxMenuItem(LolcatAction.getInstance())); menu.add(AutoPositionAction.getInstance()); menu.addSeparator(); menu.add(UndoAction.getInstance()); @@ -44,6 +44,13 @@ public class EditorMenuBar extends JMenuBar { return menu; } + private JMenu buildViewMenu() { + JMenu menu = new JMenu("View"); + menu.add(new JCheckBoxMenuItem(LolcatAction.getInstance())); + menu.add(new JCheckBoxMenuItem(VisualizeReferencesAction.getInstance())); + return menu; + } + private JMenu buildHelpMenu() { JMenu menu = new JMenu("Help"); menu.add(InstructionsAction.getInstance()); diff --git a/src/main/java/nl/andrewlalis/erme/view/view_models/AttributeViewModel.java b/src/main/java/nl/andrewlalis/erme/view/view_models/AttributeViewModel.java index 754bd3e..ab104fa 100644 --- a/src/main/java/nl/andrewlalis/erme/view/view_models/AttributeViewModel.java +++ b/src/main/java/nl/andrewlalis/erme/view/view_models/AttributeViewModel.java @@ -16,7 +16,7 @@ import java.text.AttributedString; public class AttributeViewModel implements ViewModel { public static final int PADDING_X = 5; public static final int PADDING_Y = 5; - public static final Color BACKGROUND_COLOR = Color.LIGHT_GRAY; + public static final Color BACKGROUND_COLOR = new Color(192, 192, 192, 127); public static final Color FONT_COLOR = Color.BLACK; public static final float FK_FONT_SIZE = 11.0f; private static final float LOLCAT_SAT = 0.75f; diff --git a/src/main/java/nl/andrewlalis/erme/view/view_models/MappingModelViewModel.java b/src/main/java/nl/andrewlalis/erme/view/view_models/MappingModelViewModel.java index 686f468..cbad44c 100644 --- a/src/main/java/nl/andrewlalis/erme/view/view_models/MappingModelViewModel.java +++ b/src/main/java/nl/andrewlalis/erme/view/view_models/MappingModelViewModel.java @@ -1,5 +1,8 @@ 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; @@ -17,11 +20,34 @@ public class MappingModelViewModel implements ViewModel { @Override public void draw(Graphics2D g) { + if (VisualizeReferencesAction.getInstance().isReferenceVisualizationEnabled()) { + visualizeReferences(g); + } for (Relation r : this.model.getRelations()) { r.getViewModel().draw(g); } } + private void visualizeReferences(Graphics2D g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setColor(Color.BLUE); + Stroke dashedStroke = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0, new float[]{5}, 0); + g2.setStroke(dashedStroke); + for (Relation r : this.model.getRelations()) { + for (Attribute a : r.getAttributes()) { + if (a instanceof ForeignKeyAttribute) { + ForeignKeyAttribute fk = (ForeignKeyAttribute) a; + Rectangle sourceBounds = fk.getViewModel().getBounds(g); + Rectangle targetBounds = fk.getReference().getViewModel().getBounds(g); + Point sourcePoint = new Point(sourceBounds.x + sourceBounds.width / 2, sourceBounds.y); + Point targetPoint = new Point(targetBounds.x + targetBounds.width / 2, targetBounds.y + targetBounds.height); + g2.drawLine(sourcePoint.x, sourcePoint.y, targetPoint.x, targetPoint.y); + } + } + } + g2.dispose(); + } + @Override public Rectangle getBounds(Graphics2D g) { int minX = Integer.MAX_VALUE; diff --git a/src/main/java/nl/andrewlalis/erme/view/view_models/RelationViewModel.java b/src/main/java/nl/andrewlalis/erme/view/view_models/RelationViewModel.java index 34fcdb9..4f02326 100644 --- a/src/main/java/nl/andrewlalis/erme/view/view_models/RelationViewModel.java +++ b/src/main/java/nl/andrewlalis/erme/view/view_models/RelationViewModel.java @@ -27,7 +27,7 @@ public class RelationViewModel implements ViewModel { */ public static final int ATTRIBUTE_SEPARATION = 10; - public static final Color SELECTED_COLOR = new Color(204, 224, 255); + public static final Color SELECTED_COLOR = new Color(204, 224, 255, 127); public static final Color NAME_COLOR = Color.BLACK; private final Relation relation;