Added a selection model, and attribute selection, and cleaned up foreign key referencing.
This commit is contained in:
parent
1019654e76
commit
cea15d872b
|
@ -124,10 +124,10 @@ public class ExportToImageAction extends DiagramPanelAction {
|
||||||
// Render the model.
|
// Render the model.
|
||||||
boolean lolcat = model.isLolcatEnabled(); // save previous lolcat mode
|
boolean lolcat = model.isLolcatEnabled(); // save previous lolcat mode
|
||||||
model.setLolcatEnabled(false);
|
model.setLolcatEnabled(false);
|
||||||
List<Relation> selectedRelations = model.getSelectedRelations();
|
List<Relation> selectedRelations = model.getSelectionModel().getSelectedRelations();
|
||||||
model.getSelectedRelations().forEach(r -> r.setSelected(false));
|
model.getSelectionModel().clearSelection();
|
||||||
new MappingModelViewModel(model).draw(g2d);
|
new MappingModelViewModel(model).draw(g2d);
|
||||||
model.getRelations().forEach(r -> r.setSelected(selectedRelations.contains(r)));
|
model.getSelectionModel().selectAll(selectedRelations);
|
||||||
model.setLolcatEnabled(lolcat); // revert previous lolcat mode
|
model.setLolcatEnabled(lolcat); // revert previous lolcat mode
|
||||||
|
|
||||||
// Revert to the normal image space, and render a watermark.
|
// Revert to the normal image space, and render a watermark.
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package nl.andrewlalis.erme.control.actions;
|
package nl.andrewlalis.erme.control.actions;
|
||||||
|
|
||||||
import nl.andrewlalis.erme.model.*;
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
|
import nl.andrewlalis.erme.model.AttributeType;
|
||||||
|
import nl.andrewlalis.erme.model.MappingModel;
|
||||||
|
import nl.andrewlalis.erme.model.Relation;
|
||||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -22,7 +25,9 @@ public class LoadSampleModelAction extends DiagramPanelAction {
|
||||||
Relation r1 = new Relation(model, new Point(50, 100), "Airplane");
|
Relation r1 = new Relation(model, new Point(50, 100), "Airplane");
|
||||||
r1.addAttribute(new Attribute(r1, AttributeType.ID_KEY, "id"));
|
r1.addAttribute(new Attribute(r1, AttributeType.ID_KEY, "id"));
|
||||||
r1.addAttribute(new Attribute(r1, AttributeType.PLAIN, "purchasedAt"));
|
r1.addAttribute(new Attribute(r1, AttributeType.PLAIN, "purchasedAt"));
|
||||||
r1.addAttribute(new ForeignKeyAttribute(r1, AttributeType.PLAIN, "typeName", "AirplaneType", "name"));
|
Attribute fk = new Attribute(r1, AttributeType.PLAIN, "typeName");
|
||||||
|
fk.setReference(model.findAttribute("AirplaneType", "name"));
|
||||||
|
r1.addAttribute(fk);
|
||||||
model.addRelation(r1);
|
model.addRelation(r1);
|
||||||
getDiagramPanel().setModel(model);
|
getDiagramPanel().setModel(model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package nl.andrewlalis.erme.control.actions.edits;
|
||||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||||
import nl.andrewlalis.erme.model.*;
|
import nl.andrewlalis.erme.model.*;
|
||||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||||
|
import nl.andrewlalis.erme.view.EditAttributePopupDialog;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -23,7 +24,7 @@ public class AddAttributeAction extends DiagramPanelAction {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
DiagramPanel dp = getDiagramPanel();
|
DiagramPanel dp = getDiagramPanel();
|
||||||
MappingModel model = dp.getModel();
|
MappingModel model = dp.getModel();
|
||||||
List<Relation> selectedRelations = model.getSelectedRelations();
|
List<Relation> selectedRelations = model.getSelectionModel().getSelectedRelations();
|
||||||
if (selectedRelations.size() != 1) {
|
if (selectedRelations.size() != 1) {
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
dp,
|
dp,
|
||||||
|
@ -34,72 +35,74 @@ public class AddAttributeAction extends DiagramPanelAction {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Relation r = selectedRelations.get(0);
|
Relation r = selectedRelations.get(0);
|
||||||
Attribute createdAttribute;
|
EditAttributePopupDialog popup = new EditAttributePopupDialog((JFrame) SwingUtilities.getWindowAncestor(dp), r, null);
|
||||||
String name = JOptionPane.showInputDialog(dp, "Enter the name of the attribute.", "Attribute Name", JOptionPane.PLAIN_MESSAGE);
|
popup.setVisible(true);
|
||||||
if (name == null) return;
|
// Attribute createdAttribute;
|
||||||
Integer index = (Integer) JOptionPane.showInputDialog(
|
// String name = JOptionPane.showInputDialog(dp, "Enter the name of the attribute.", "Attribute Name", JOptionPane.PLAIN_MESSAGE);
|
||||||
dp,
|
// if (name == null) return;
|
||||||
"Select the index to insert this attribute at.",
|
// Integer index = (Integer) JOptionPane.showInputDialog(
|
||||||
"Attribute Index",
|
// dp,
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
// "Select the index to insert this attribute at.",
|
||||||
null,
|
// "Attribute Index",
|
||||||
Stream.iterate(0, n -> n + 1).limit(r.getAttributes().size() + 1).toArray(),
|
// JOptionPane.PLAIN_MESSAGE,
|
||||||
r.getAttributes().size()
|
// null,
|
||||||
);
|
// Stream.iterate(0, n -> n + 1).limit(r.getAttributes().size() + 1).toArray(),
|
||||||
if (index == null) return;
|
// r.getAttributes().size()
|
||||||
AttributeType type = (AttributeType) JOptionPane.showInputDialog(
|
// );
|
||||||
dp,
|
// if (index == null) return;
|
||||||
"Select the type this attribute is.",
|
// AttributeType type = (AttributeType) JOptionPane.showInputDialog(
|
||||||
"Attribute Type",
|
// dp,
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
// "Select the type this attribute is.",
|
||||||
null,
|
// "Attribute Type",
|
||||||
AttributeType.values(),
|
// JOptionPane.PLAIN_MESSAGE,
|
||||||
AttributeType.PLAIN
|
// null,
|
||||||
);
|
// AttributeType.values(),
|
||||||
if (type == null) return;
|
// AttributeType.PLAIN
|
||||||
boolean shouldUseForeignKey = ((String) JOptionPane.showInputDialog(
|
// );
|
||||||
dp,
|
// if (type == null) return;
|
||||||
"Is this attribute a foreign key?",
|
// boolean shouldUseForeignKey = ((String) JOptionPane.showInputDialog(
|
||||||
"Foreign Key",
|
// dp,
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
// "Is this attribute a foreign key?",
|
||||||
null,
|
// "Foreign Key",
|
||||||
new String[]{"Yes", "No"},
|
// JOptionPane.PLAIN_MESSAGE,
|
||||||
"No"
|
// null,
|
||||||
)).equalsIgnoreCase("yes");
|
// new String[]{"Yes", "No"},
|
||||||
if (shouldUseForeignKey) {
|
// "No"
|
||||||
if (model.getRelations().size() < 2) {
|
// )).equalsIgnoreCase("yes");
|
||||||
JOptionPane.showMessageDialog(dp, "There should be at least 2 relations present in the model.", "Not Enough Relations", JOptionPane.WARNING_MESSAGE);
|
// if (shouldUseForeignKey) {
|
||||||
return;
|
// 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);
|
||||||
Relation fkRelation = (Relation) JOptionPane.showInputDialog(
|
// return;
|
||||||
dp,
|
// }
|
||||||
"Select the relation that this foreign key references.",
|
// Relation fkRelation = (Relation) JOptionPane.showInputDialog(
|
||||||
"Foreign Key Relation Reference",
|
// dp,
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
// "Select the relation that this foreign key references.",
|
||||||
null,
|
// "Foreign Key Relation Reference",
|
||||||
model.getRelations().toArray(new Relation[0]),
|
// JOptionPane.PLAIN_MESSAGE,
|
||||||
model.getRelations().stream().findFirst().orElse(null)
|
// null,
|
||||||
);
|
// model.getRelations().toArray(new Relation[0]),
|
||||||
if (fkRelation == null) return;
|
// model.getRelations().stream().findFirst().orElse(null)
|
||||||
List<Attribute> eligibleAttributes = fkRelation.getAttributes();
|
// );
|
||||||
if (eligibleAttributes.isEmpty()) {
|
// if (fkRelation == null) return;
|
||||||
JOptionPane.showMessageDialog(dp, "There are no referencable attributes in the selected relation.", "No Referencable Attributes", JOptionPane.WARNING_MESSAGE);
|
// List<Attribute> eligibleAttributes = fkRelation.getAttributes();
|
||||||
return;
|
// if (eligibleAttributes.isEmpty()) {
|
||||||
}
|
// JOptionPane.showMessageDialog(dp, "There are no referencable attributes in the selected relation.", "No Referencable Attributes", JOptionPane.WARNING_MESSAGE);
|
||||||
Attribute fkAttribute = (Attribute) JOptionPane.showInputDialog(
|
// return;
|
||||||
dp,
|
// }
|
||||||
"Select the attribute that this foreign key references.",
|
// Attribute fkAttribute = (Attribute) JOptionPane.showInputDialog(
|
||||||
"Foreign Key Attribute Reference",
|
// dp,
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
// "Select the attribute that this foreign key references.",
|
||||||
null,
|
// "Foreign Key Attribute Reference",
|
||||||
eligibleAttributes.toArray(new Attribute[0]),
|
// JOptionPane.PLAIN_MESSAGE,
|
||||||
eligibleAttributes.get(0)
|
// null,
|
||||||
);
|
// eligibleAttributes.toArray(new Attribute[0]),
|
||||||
if (fkAttribute == null) return;
|
// eligibleAttributes.get(0)
|
||||||
createdAttribute = new ForeignKeyAttribute(r, type, name, fkAttribute);
|
// );
|
||||||
} else {
|
// if (fkAttribute == null) return;
|
||||||
createdAttribute = new Attribute(r, type, name);
|
// createdAttribute = new ForeignKeyAttribute(r, type, name, fkAttribute);
|
||||||
}
|
// } else {
|
||||||
r.addAttribute(createdAttribute, index);
|
// createdAttribute = new Attribute(r, type, name);
|
||||||
|
// }
|
||||||
|
// r.addAttribute(createdAttribute, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,9 @@ public class AddRelationAction extends DiagramPanelAction {
|
||||||
p = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
|
p = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
|
||||||
}
|
}
|
||||||
Relation r = new Relation(model, p, name);
|
Relation r = new Relation(model, p, name);
|
||||||
model.getSelectedRelations().forEach(rl -> rl.setSelected(false));
|
|
||||||
r.setSelected(true);
|
|
||||||
model.addRelation(r);
|
model.addRelation(r);
|
||||||
|
model.getSelectionModel().clearSelection();
|
||||||
|
model.getSelectionModel().select(r);
|
||||||
if (isFirstRelation) {
|
if (isFirstRelation) {
|
||||||
model.normalizeRelationPositions();
|
model.normalizeRelationPositions();
|
||||||
dp.centerModel();
|
dp.centerModel();
|
||||||
|
|
|
@ -2,7 +2,6 @@ package nl.andrewlalis.erme.control.actions.edits;
|
||||||
|
|
||||||
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
import nl.andrewlalis.erme.control.actions.DiagramPanelAction;
|
||||||
import nl.andrewlalis.erme.model.Attribute;
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
import nl.andrewlalis.erme.model.Relation;
|
|
||||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -20,28 +19,22 @@ public class RemoveAttributeAction extends DiagramPanelAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
List<Relation> selectedRelations = getDiagramPanel().getModel().getSelectedRelations();
|
List<Attribute> selectedAttributes = getDiagramPanel().getModel().getSelectionModel().getSelectedAttributes();
|
||||||
if (selectedRelations.size() != 1 || selectedRelations.get(0).getAttributes().isEmpty()) {
|
if (selectedAttributes.isEmpty()) {
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
getDiagramPanel(),
|
getDiagramPanel(),
|
||||||
"A single relation with at least one attribute must be selected to remove an attribute.",
|
"At least one attribute must be selected to remove.",
|
||||||
"Single Relation With Attribute Required",
|
"Select Attributes to Remove Them",
|
||||||
JOptionPane.WARNING_MESSAGE
|
JOptionPane.WARNING_MESSAGE
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Relation r = selectedRelations.get(0);
|
int choice = JOptionPane.showConfirmDialog(getDiagramPanel(), "Are you sure you want to remove these attributes?", "Confirm", JOptionPane.OK_CANCEL_OPTION);
|
||||||
Attribute attribute = (Attribute) JOptionPane.showInputDialog(
|
if (choice == JOptionPane.YES_OPTION) {
|
||||||
getDiagramPanel(),
|
for (Attribute a : selectedAttributes) {
|
||||||
"Select the attribute to remove.",
|
a.getRelation().removeAttribute(a);
|
||||||
"Select Attribute",
|
}
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
getDiagramPanel().getModel().getSelectionModel().clearAttributes();
|
||||||
null,
|
|
||||||
r.getAttributes().toArray(new Attribute[0]),
|
|
||||||
r.getAttributes().get(0)
|
|
||||||
);
|
|
||||||
if (attribute != null) {
|
|
||||||
r.removeAttribute(attribute);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import javax.swing.*;
|
||||||
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.util.List;
|
||||||
|
|
||||||
public class RemoveRelationAction extends DiagramPanelAction {
|
public class RemoveRelationAction extends DiagramPanelAction {
|
||||||
public RemoveRelationAction(DiagramPanel diagramPanel) {
|
public RemoveRelationAction(DiagramPanel diagramPanel) {
|
||||||
|
@ -20,7 +21,8 @@ public class RemoveRelationAction extends DiagramPanelAction {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
MappingModel model = getDiagramPanel().getModel();
|
MappingModel model = getDiagramPanel().getModel();
|
||||||
if (model.getSelectedRelations().isEmpty()) {
|
List<Relation> selectedRelations = model.getSelectionModel().getSelectedRelations();
|
||||||
|
if (selectedRelations.isEmpty()) {
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
getDiagramPanel(),
|
getDiagramPanel(),
|
||||||
"No relations selected. Select at least one relation to remove.",
|
"No relations selected. Select at least one relation to remove.",
|
||||||
|
@ -29,8 +31,12 @@ public class RemoveRelationAction extends DiagramPanelAction {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Relation r : model.getSelectedRelations()) {
|
int choice = JOptionPane.showConfirmDialog(getDiagramPanel(), "Are you sure you want to remove these relations?", "Confirm", JOptionPane.YES_NO_OPTION);
|
||||||
model.removeRelation(r);
|
if (choice == JOptionPane.YES_OPTION) {
|
||||||
|
for (Relation r : selectedRelations) {
|
||||||
|
model.removeRelation(r);
|
||||||
|
}
|
||||||
|
model.getSelectionModel().clearRelations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.erme.control.diagram;
|
package nl.andrewlalis.erme.control.diagram;
|
||||||
|
|
||||||
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
import nl.andrewlalis.erme.model.MappingModel;
|
import nl.andrewlalis.erme.model.MappingModel;
|
||||||
import nl.andrewlalis.erme.model.Relation;
|
import nl.andrewlalis.erme.model.Relation;
|
||||||
import nl.andrewlalis.erme.view.DiagramPanel;
|
import nl.andrewlalis.erme.view.DiagramPanel;
|
||||||
|
@ -25,7 +26,7 @@ public class DiagramMouseListener extends MouseAdapter {
|
||||||
* - If the click occurs within at least one relation, select the first one,
|
* - If the click occurs within at least one relation, select the first one,
|
||||||
* and deselect all others if CTRL is not held down.
|
* and deselect all others if CTRL is not held down.
|
||||||
* - If the user did a right-click, try to open a popup menu with some
|
* - If the user did a right-click, try to open a popup menu with some
|
||||||
* possible actions.
|
* possible actions, based on what entity we're over.
|
||||||
* @param e The mouse event.
|
* @param e The mouse event.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,15 +41,24 @@ public class DiagramMouseListener extends MouseAdapter {
|
||||||
final boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
|
final boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;
|
||||||
MappingModel model = this.diagramPanel.getModel();
|
MappingModel model = this.diagramPanel.getModel();
|
||||||
|
|
||||||
if (!isShiftDown && !isCtrlDown) {// A simple click anywhere should reset selection.
|
if (!isShiftDown && !isCtrlDown) {// A simple left-click anywhere should reset selection.
|
||||||
model.getRelations().forEach(r -> r.setSelected(false));
|
model.getSelectionModel().clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isShiftDown) {// If the user clicked or CTRL+clicked, try and select the relation they clicked on.
|
if (!isShiftDown) {// If the user clicked or CTRL+clicked, try and select the relation they clicked on.
|
||||||
for (Relation r : model.getRelations()) {
|
for (Relation r : model.getRelations()) {
|
||||||
if (r.getViewModel().getBounds(g).contains(modelX, modelY)) {
|
if (r.getViewModel().getBounds(g).contains(modelX, modelY)) {
|
||||||
r.setSelected(!r.isSelected());
|
boolean anyAttributeSelected = false;
|
||||||
break;
|
for (Attribute a : r.getAttributes()) {
|
||||||
|
if (a.getViewModel().getBounds(g).contains(modelX, modelY)) {
|
||||||
|
model.getSelectionModel().toggle(a);
|
||||||
|
}
|
||||||
|
anyAttributeSelected = anyAttributeSelected || a.isSelected();
|
||||||
|
}
|
||||||
|
if (!anyAttributeSelected) {
|
||||||
|
model.getSelectionModel().toggle(r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,12 +87,11 @@ public class DiagramMouseListener extends MouseAdapter {
|
||||||
MappingModel model = this.diagramPanel.getModel();
|
MappingModel model = this.diagramPanel.getModel();
|
||||||
|
|
||||||
if (isShiftDown) {
|
if (isShiftDown) {
|
||||||
System.out.println(e);
|
|
||||||
this.diagramPanel.translate(-dx, -dy);
|
this.diagramPanel.translate(-dx, -dy);
|
||||||
this.diagramPanel.repaint();
|
this.diagramPanel.repaint();
|
||||||
} else {
|
} else {
|
||||||
for (Relation r : model.getRelations()) {
|
for (Relation r : model.getRelations()) {
|
||||||
if (r.isSelected()) {
|
if (model.getSelectionModel().isSelected(r)) {
|
||||||
r.setPosition(new Point(r.getPosition().x - dx, r.getPosition().y - dy));
|
r.setPosition(new Point(r.getPosition().x - dx, r.getPosition().y - dy));
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ public class Attribute {
|
||||||
private final Relation relation;
|
private final Relation relation;
|
||||||
private AttributeType type;
|
private AttributeType type;
|
||||||
private String name;
|
private String name;
|
||||||
|
private Attribute reference;
|
||||||
|
|
||||||
private transient AttributeViewModel viewModel;
|
private transient AttributeViewModel viewModel;
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ public class Attribute {
|
||||||
this.relation = relation;
|
this.relation = relation;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.reference = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(AttributeType type) {
|
public void setType(AttributeType type) {
|
||||||
|
@ -32,6 +34,14 @@ public class Attribute {
|
||||||
this.relation.getModel().fireChangedEvent();
|
this.relation.getModel().fireChangedEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasReference() {
|
||||||
|
return this.reference != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReference(Attribute attribute) {
|
||||||
|
this.reference = attribute;
|
||||||
|
}
|
||||||
|
|
||||||
public AttributeViewModel getViewModel() {
|
public AttributeViewModel getViewModel() {
|
||||||
if (this.viewModel == null) {
|
if (this.viewModel == null) {
|
||||||
this.viewModel = new AttributeViewModel(this);
|
this.viewModel = new AttributeViewModel(this);
|
||||||
|
@ -39,6 +49,10 @@ public class Attribute {
|
||||||
return this.viewModel;
|
return this.viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSelected() {
|
||||||
|
return this.relation.getModel().getSelectionModel().isSelected(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package nl.andrewlalis.erme.model;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class ForeignKeyAttribute extends Attribute {
|
|
||||||
private Attribute reference;
|
|
||||||
|
|
||||||
public ForeignKeyAttribute(Relation relation, AttributeType type, String name, Attribute reference) {
|
|
||||||
super(relation, type, name);
|
|
||||||
this.reference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ForeignKeyAttribute(Relation relation, AttributeType type, String name, String referencedRelationName, String referencedAttributeName) {
|
|
||||||
this(relation, type, name, relation.getModel().findAttribute(referencedRelationName, referencedAttributeName));
|
|
||||||
if (this.getReference() == null) {
|
|
||||||
throw new IllegalArgumentException("Unknown attribute name.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReference(Attribute reference) {
|
|
||||||
this.reference = reference;
|
|
||||||
this.getRelation().getModel().fireChangedEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFullReferenceName() {
|
|
||||||
return this.getReference().getRelation().getName() + "." + this.getReference().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + "->" + this.getFullReferenceName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForeignKeyAttribute copy(Relation newRelation) {
|
|
||||||
return new ForeignKeyAttribute(newRelation, this.getType(), this.getName(), this.getReference());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,9 +10,7 @@ import nl.andrewlalis.erme.view.view_models.MappingModelViewModel;
|
||||||
import nl.andrewlalis.erme.view.view_models.ViewModel;
|
import nl.andrewlalis.erme.view.view_models.ViewModel;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This model contains all the information about a single mapping diagram,
|
* This model contains all the information about a single mapping diagram,
|
||||||
|
@ -33,10 +31,13 @@ public class MappingModel implements Viewable {
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private transient boolean referenceVisualizationEnabled = false;
|
private transient boolean referenceVisualizationEnabled = false;
|
||||||
|
@Getter
|
||||||
|
private transient final SelectionModel selectionModel;
|
||||||
|
|
||||||
public MappingModel() {
|
public MappingModel() {
|
||||||
this.relations = new HashSet<>();
|
this.relations = new HashSet<>();
|
||||||
this.changeListeners = new HashSet<>();
|
this.changeListeners = new HashSet<>();
|
||||||
|
this.selectionModel = new SelectionModel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRelation(Relation r) {
|
public void addRelation(Relation r) {
|
||||||
|
@ -51,14 +52,6 @@ public class MappingModel implements Viewable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the list of relations which are currently selected.
|
|
||||||
* @return The list of relations which are selected.
|
|
||||||
*/
|
|
||||||
public List<Relation> getSelectedRelations() {
|
|
||||||
return this.relations.stream().filter(Relation::isSelected).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds an attribute in this model, or returns null otherwise.
|
* Finds an attribute in this model, or returns null otherwise.
|
||||||
* @param relationName The name of the relation the attribute is in.
|
* @param relationName The name of the relation the attribute is in.
|
||||||
|
@ -86,11 +79,8 @@ public class MappingModel implements Viewable {
|
||||||
for (Relation r : this.getRelations()) {
|
for (Relation r : this.getRelations()) {
|
||||||
Set<Attribute> removalSet = new HashSet<>();
|
Set<Attribute> removalSet = new HashSet<>();
|
||||||
for (Attribute a : r.getAttributes()) {
|
for (Attribute a : r.getAttributes()) {
|
||||||
if (a instanceof ForeignKeyAttribute) {
|
if (a.hasReference() && a.getReference().equals(referenced)) {
|
||||||
ForeignKeyAttribute fkA = (ForeignKeyAttribute) a;
|
removalSet.add(a);
|
||||||
if (fkA.getReference().equals(referenced)) {
|
|
||||||
removalSet.add(fkA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removalSet.forEach(r::removeAttribute);
|
removalSet.forEach(r::removeAttribute);
|
||||||
|
@ -196,12 +186,11 @@ public class MappingModel implements Viewable {
|
||||||
ObjectNode attributeNode = mapper.createObjectNode()
|
ObjectNode attributeNode = mapper.createObjectNode()
|
||||||
.put("name", a.getName())
|
.put("name", a.getName())
|
||||||
.put("type", a.getType().name());
|
.put("type", a.getType().name());
|
||||||
if (a instanceof ForeignKeyAttribute) {
|
if (a.hasReference()) {
|
||||||
ForeignKeyAttribute fk = (ForeignKeyAttribute) a;
|
|
||||||
ObjectNode referenceNode = mapper.createObjectNode()
|
ObjectNode referenceNode = mapper.createObjectNode()
|
||||||
.put("relation", fk.getReference().getRelation().getName())
|
.put("relation", a.getReference().getRelation().getName())
|
||||||
.put("attribute", fk.getReference().getName());
|
.put("attribute", a.getReference().getName());
|
||||||
attributeNode.set("references", referenceNode);
|
attributeNode.set("reference", referenceNode);
|
||||||
}
|
}
|
||||||
attributesArray.add(attributeNode);
|
attributesArray.add(attributeNode);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +234,8 @@ public class MappingModel implements Viewable {
|
||||||
Attribute referencedAttribute = model.findAttribute(referencedRelation, referencedName);
|
Attribute referencedAttribute = model.findAttribute(referencedRelation, referencedName);
|
||||||
if (referencedAttribute == null) throw new IllegalArgumentException("Foreign key referenced unknown attribute.");
|
if (referencedAttribute == null) throw new IllegalArgumentException("Foreign key referenced unknown attribute.");
|
||||||
if (!references.containsKey(referencedAttribute)) {
|
if (!references.containsKey(referencedAttribute)) {
|
||||||
ForeignKeyAttribute fk = new ForeignKeyAttribute(attribute.getRelation(), attribute.getType(), attribute.getName(), referencedAttribute);
|
Attribute fk = new Attribute(attribute.getRelation(), attribute.getType(), attribute.getName());
|
||||||
|
fk.setReference(referencedAttribute);
|
||||||
attribute.getRelation().removeAttribute(attribute);
|
attribute.getRelation().removeAttribute(attribute);
|
||||||
attribute.getRelation().addAttribute(fk);
|
attribute.getRelation().addAttribute(fk);
|
||||||
references.remove(attribute);
|
references.remove(attribute);
|
||||||
|
@ -270,8 +260,8 @@ public class MappingModel implements Viewable {
|
||||||
Map<Attribute, ObjectNode> references = new HashMap<>();
|
Map<Attribute, ObjectNode> references = new HashMap<>();
|
||||||
for (JsonNode r : node.withArray("relations")) {
|
for (JsonNode r : node.withArray("relations")) {
|
||||||
for (JsonNode a : r.withArray("attributes")) {
|
for (JsonNode a : r.withArray("attributes")) {
|
||||||
if (a.has("references") && a.get("references").isObject()) {
|
if (a.has("reference") && a.get("reference").isObject()) {
|
||||||
ObjectNode referenceNode = (ObjectNode) a.get("references");
|
ObjectNode referenceNode = (ObjectNode) a.get("reference");
|
||||||
String attributeName = a.get("name").asText();
|
String attributeName = a.get("name").asText();
|
||||||
String relationName = r.get("name").asText();
|
String relationName = r.get("name").asText();
|
||||||
Attribute attribute = model.findAttribute(relationName, attributeName);
|
Attribute attribute = model.findAttribute(relationName, attributeName);
|
||||||
|
|
|
@ -20,7 +20,6 @@ public class Relation implements Viewable, Comparable<Relation> {
|
||||||
private String name;
|
private String name;
|
||||||
private final List<Attribute> attributes;
|
private final List<Attribute> attributes;
|
||||||
|
|
||||||
private transient boolean selected;
|
|
||||||
private transient RelationViewModel viewModel;
|
private transient RelationViewModel viewModel;
|
||||||
|
|
||||||
public Relation(MappingModel model, Point position, String name, List<Attribute> attributes) {
|
public Relation(MappingModel model, Point position, String name, List<Attribute> attributes) {
|
||||||
|
@ -42,10 +41,6 @@ public class Relation implements Viewable, Comparable<Relation> {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelected(boolean selected) {
|
|
||||||
this.selected = selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAttribute(Attribute attribute) {
|
public void addAttribute(Attribute attribute) {
|
||||||
this.attributes.add(attribute);
|
this.attributes.add(attribute);
|
||||||
this.model.fireChangedEvent();
|
this.model.fireChangedEvent();
|
||||||
|
@ -63,6 +58,10 @@ public class Relation implements Viewable, Comparable<Relation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSelected() {
|
||||||
|
return this.model.getSelectionModel().isSelected(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewModel getViewModel() {
|
public ViewModel getViewModel() {
|
||||||
if (this.viewModel == null) {
|
if (this.viewModel == null) {
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package nl.andrewlalis.erme.model;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A model that keeps track of the application's set of selected elements.
|
||||||
|
*/
|
||||||
|
public class SelectionModel {
|
||||||
|
private final MappingModel model;
|
||||||
|
private final Set<Relation> selectedRelations;
|
||||||
|
private final Set<Attribute> selectedAttributes;
|
||||||
|
|
||||||
|
public SelectionModel(MappingModel model) {
|
||||||
|
this.model = model;
|
||||||
|
this.selectedRelations = new HashSet<>();
|
||||||
|
this.selectedAttributes = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelected(Relation relation) {
|
||||||
|
return this.selectedRelations.contains(relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelected(Attribute attribute) {
|
||||||
|
return this.selectedAttributes.contains(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Relation> getSelectedRelations() {
|
||||||
|
return new ArrayList<>(this.selectedRelations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Attribute> getSelectedAttributes() {
|
||||||
|
return new ArrayList<>(this.selectedAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void select(Relation relation) {
|
||||||
|
this.selectedRelations.add(relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectAll(Collection<Relation> relations) {
|
||||||
|
this.selectedRelations.addAll(relations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void select(Attribute attribute) {
|
||||||
|
this.selectedAttributes.add(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggle(Relation relation) {
|
||||||
|
if (selectedRelations.contains(relation)) {
|
||||||
|
selectedRelations.remove(relation);
|
||||||
|
} else {
|
||||||
|
selectedRelations.add(relation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggle(Attribute attribute) {
|
||||||
|
if (selectedAttributes.contains(attribute)) {
|
||||||
|
selectedAttributes.remove(attribute);
|
||||||
|
} else {
|
||||||
|
selectedAttributes.add(attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearSelection() {
|
||||||
|
this.selectedRelations.clear();
|
||||||
|
this.selectedAttributes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearRelations() {
|
||||||
|
this.selectedRelations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAttributes() {
|
||||||
|
this.selectedAttributes.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,9 @@ package nl.andrewlalis.erme.view;
|
||||||
|
|
||||||
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
||||||
import nl.andrewlalis.erme.control.actions.edits.AddRelationAction;
|
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.actions.edits.RemoveRelationAction;
|
||||||
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
import nl.andrewlalis.erme.model.Relation;
|
import nl.andrewlalis.erme.model.Relation;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -10,19 +12,19 @@ import java.util.List;
|
||||||
|
|
||||||
public class DiagramPopupMenu extends JPopupMenu {
|
public class DiagramPopupMenu extends JPopupMenu {
|
||||||
public DiagramPopupMenu(DiagramPanel diagramPanel) {
|
public DiagramPopupMenu(DiagramPanel diagramPanel) {
|
||||||
List<Relation> selectedRelations = diagramPanel.getModel().getSelectedRelations();
|
List<Relation> selectedRelations = diagramPanel.getModel().getSelectionModel().getSelectedRelations();
|
||||||
if (selectedRelations.size() == 0) {
|
List<Attribute> selectedAttributes = diagramPanel.getModel().getSelectionModel().getSelectedAttributes();
|
||||||
|
if (selectedRelations.isEmpty() && selectedAttributes.isEmpty()) {
|
||||||
this.add(new AddRelationAction(diagramPanel));
|
this.add(new AddRelationAction(diagramPanel));
|
||||||
}
|
}
|
||||||
if (selectedRelations.size() > 0) {
|
if (selectedRelations.size() > 0 && selectedAttributes.isEmpty()) {
|
||||||
this.add(new RemoveRelationAction(diagramPanel));
|
this.add(new RemoveRelationAction(diagramPanel));
|
||||||
}
|
}
|
||||||
if (selectedRelations.size() == 1) {
|
if (selectedRelations.size() == 1 && selectedAttributes.isEmpty()) {
|
||||||
Relation relation = selectedRelations.get(0);
|
|
||||||
this.add(new AddAttributeAction(diagramPanel));
|
this.add(new AddAttributeAction(diagramPanel));
|
||||||
if (!relation.getAttributes().isEmpty()) {
|
}
|
||||||
this.add(new RemoveRelationAction(diagramPanel));
|
if (!selectedAttributes.isEmpty() && selectedRelations.isEmpty()) {
|
||||||
}
|
this.add(new RemoveAttributeAction(diagramPanel));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package nl.andrewlalis.erme.view;
|
||||||
|
|
||||||
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
|
import nl.andrewlalis.erme.model.AttributeType;
|
||||||
|
import nl.andrewlalis.erme.model.Relation;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A popup that's shown when creating or editing an attribute of a relation.
|
||||||
|
*/
|
||||||
|
public class EditAttributePopupDialog extends JDialog {
|
||||||
|
private final Relation relation;
|
||||||
|
private final Attribute attribute;
|
||||||
|
|
||||||
|
private final JTextField nameField;
|
||||||
|
private final JComboBox<AttributeType> attributeTypeComboBox;
|
||||||
|
private final JSpinner orderSpinner;
|
||||||
|
|
||||||
|
public EditAttributePopupDialog(Frame owner, Relation relation, Attribute attribute) {
|
||||||
|
super(owner, "Edit Attribute", true);
|
||||||
|
this.relation = relation;
|
||||||
|
this.attribute = attribute;
|
||||||
|
JPanel mainPanel = new JPanel(new GridBagLayout());
|
||||||
|
GridBagConstraints gc = new GridBagConstraints();
|
||||||
|
gc.ipadx = 2;
|
||||||
|
gc.ipady = 2;
|
||||||
|
gc.gridx = 0;
|
||||||
|
gc.gridy = 0;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_START;
|
||||||
|
mainPanel.add(new JLabel("Name"), gc);
|
||||||
|
gc.gridx = 1;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_END;
|
||||||
|
this.nameField = new JTextField(20);
|
||||||
|
mainPanel.add(nameField, gc);
|
||||||
|
gc.gridx = 0;
|
||||||
|
gc.gridy++;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_START;
|
||||||
|
mainPanel.add(new JLabel("Type"), gc);
|
||||||
|
gc.gridx = 1;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_END;
|
||||||
|
this.attributeTypeComboBox = new JComboBox<>(AttributeType.values());
|
||||||
|
mainPanel.add(attributeTypeComboBox, gc);
|
||||||
|
gc.gridx = 0;
|
||||||
|
gc.gridy++;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_START;
|
||||||
|
mainPanel.add(new JLabel("Order"), gc);
|
||||||
|
gc.gridx = 1;
|
||||||
|
gc.anchor = GridBagConstraints.LINE_END;
|
||||||
|
this.orderSpinner = new JSpinner(new SpinnerNumberModel(1, 1, relation.getAttributes().size() + 1, 1));
|
||||||
|
mainPanel.add(orderSpinner, gc);
|
||||||
|
|
||||||
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||||
|
JButton okayButton = new JButton("Okay");
|
||||||
|
okayButton.addActionListener(e -> this.submit());
|
||||||
|
JButton cancelButton = new JButton("Cancel");
|
||||||
|
cancelButton.addActionListener(e -> this.dispose());
|
||||||
|
buttonPanel.add(okayButton);
|
||||||
|
buttonPanel.add(cancelButton);
|
||||||
|
gc.gridx = 0;
|
||||||
|
gc.gridy++;
|
||||||
|
gc.gridwidth = 2;
|
||||||
|
mainPanel.add(buttonPanel, gc);
|
||||||
|
|
||||||
|
if (this.attribute != null) {
|
||||||
|
this.nameField.setText(this.attribute.getName());
|
||||||
|
this.attributeTypeComboBox.setSelectedItem(this.attribute.getType());
|
||||||
|
this.orderSpinner.setValue(this.relation.getAttributes().indexOf(this.attribute));
|
||||||
|
} else {
|
||||||
|
this.orderSpinner.setValue(this.relation.getAttributes().size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setContentPane(mainPanel);
|
||||||
|
this.pack();
|
||||||
|
this.setLocationRelativeTo(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submit() {
|
||||||
|
String name = this.nameField.getText().trim();
|
||||||
|
AttributeType type = (AttributeType) this.attributeTypeComboBox.getSelectedItem();
|
||||||
|
int order = (int) this.orderSpinner.getValue();
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
JOptionPane.showMessageDialog(this, "The attribute must have a name.", "Missing Name", JOptionPane.WARNING_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.attribute != null) {
|
||||||
|
this.attribute.setName(name);
|
||||||
|
this.attribute.setType(type);
|
||||||
|
} else {
|
||||||
|
Attribute a = new Attribute(this.relation, type, name);
|
||||||
|
this.relation.addAttribute(a, order - 1);
|
||||||
|
}
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package nl.andrewlalis.erme.view;
|
||||||
import nl.andrewlalis.erme.control.actions.*;
|
import nl.andrewlalis.erme.control.actions.*;
|
||||||
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
import nl.andrewlalis.erme.control.actions.edits.AddAttributeAction;
|
||||||
import nl.andrewlalis.erme.control.actions.edits.AddRelationAction;
|
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.actions.edits.RemoveRelationAction;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -35,7 +36,7 @@ public class EditorMenuBar extends JMenuBar {
|
||||||
menu.add(new AddRelationAction(diagramPanel));
|
menu.add(new AddRelationAction(diagramPanel));
|
||||||
menu.add(new RemoveRelationAction(diagramPanel));
|
menu.add(new RemoveRelationAction(diagramPanel));
|
||||||
menu.add(new AddAttributeAction(diagramPanel));
|
menu.add(new AddAttributeAction(diagramPanel));
|
||||||
menu.add(new RemoveRelationAction(diagramPanel));
|
menu.add(new RemoveAttributeAction(diagramPanel));
|
||||||
menu.add(new AutoPositionAction(diagramPanel));
|
menu.add(new AutoPositionAction(diagramPanel));
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package nl.andrewlalis.erme.view.view_models;
|
||||||
|
|
||||||
import nl.andrewlalis.erme.model.Attribute;
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
import nl.andrewlalis.erme.model.AttributeType;
|
import nl.andrewlalis.erme.model.AttributeType;
|
||||||
import nl.andrewlalis.erme.model.ForeignKeyAttribute;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.font.TextAttribute;
|
import java.awt.font.TextAttribute;
|
||||||
|
@ -16,6 +15,7 @@ public class AttributeViewModel implements ViewModel {
|
||||||
public static final int PADDING_X = 5;
|
public static final int PADDING_X = 5;
|
||||||
public static final int PADDING_Y = 5;
|
public static final int PADDING_Y = 5;
|
||||||
public static final Color BACKGROUND_COLOR = new Color(192, 192, 192, 127);
|
public static final Color BACKGROUND_COLOR = new Color(192, 192, 192, 127);
|
||||||
|
public static final Color SELECTED_COLOR = new Color(148, 255, 176, 127);
|
||||||
public static final Color FONT_COLOR = Color.BLACK;
|
public static final Color FONT_COLOR = Color.BLACK;
|
||||||
public static final float FK_FONT_SIZE = 11.0f;
|
public static final float FK_FONT_SIZE = 11.0f;
|
||||||
private static final float LOLCAT_SAT = 0.75f;
|
private static final float LOLCAT_SAT = 0.75f;
|
||||||
|
@ -35,16 +35,16 @@ public class AttributeViewModel implements ViewModel {
|
||||||
g.setColor(FONT_COLOR);
|
g.setColor(FONT_COLOR);
|
||||||
g.drawRect(r.x, r.y, r.width, r.height);
|
g.drawRect(r.x, r.y, r.width, r.height);
|
||||||
g.drawString(as.getIterator(), r.x + PADDING_X, r.y + (r.height - PADDING_Y));
|
g.drawString(as.getIterator(), r.x + PADDING_X, r.y + (r.height - PADDING_Y));
|
||||||
if (this.attribute instanceof ForeignKeyAttribute) {
|
if (this.attribute.hasReference() && !this.attribute.getRelation().getModel().isReferenceVisualizationEnabled()) {
|
||||||
ForeignKeyAttribute fkAttribute = (ForeignKeyAttribute) this.attribute;
|
|
||||||
Font originalFont = g.getFont();
|
Font originalFont = g.getFont();
|
||||||
g.setFont(g.getFont().deriveFont(Font.ITALIC, FK_FONT_SIZE));
|
g.setFont(g.getFont().deriveFont(Font.ITALIC, FK_FONT_SIZE));
|
||||||
g.drawString(fkAttribute.getFullReferenceName(), r.x + PADDING_X, r.y - PADDING_Y);
|
g.drawString(getFullReferenceName(), r.x + PADDING_X, r.y - PADDING_Y);
|
||||||
g.setFont(originalFont);
|
g.setFont(originalFont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color getBackgroundColor(int x, int y, Graphics2D g) {
|
private Color getBackgroundColor(int x, int y, Graphics2D g) {
|
||||||
|
if (attribute.isSelected()) return SELECTED_COLOR;
|
||||||
if (!attribute.getRelation().getModel().isLolcatEnabled()) return BACKGROUND_COLOR;
|
if (!attribute.getRelation().getModel().isLolcatEnabled()) return BACKGROUND_COLOR;
|
||||||
Point offset = g.getClipBounds().getLocation();
|
Point offset = g.getClipBounds().getLocation();
|
||||||
g.translate(offset.x, offset.y);
|
g.translate(offset.x, offset.y);
|
||||||
|
@ -82,11 +82,10 @@ public class AttributeViewModel implements ViewModel {
|
||||||
Rectangle2D nameRect = g.getFontMetrics().getStringBounds(as.getIterator(), 0, this.attribute.getName().length(), g);
|
Rectangle2D nameRect = g.getFontMetrics().getStringBounds(as.getIterator(), 0, this.attribute.getName().length(), g);
|
||||||
int width = (int) nameRect.getWidth() + (2 * PADDING_X);
|
int width = (int) nameRect.getWidth() + (2 * PADDING_X);
|
||||||
int height = (int) nameRect.getHeight() + (2 * PADDING_Y);
|
int height = (int) nameRect.getHeight() + (2 * PADDING_Y);
|
||||||
if (this.attribute instanceof ForeignKeyAttribute) {
|
if (this.attribute.hasReference()) {
|
||||||
ForeignKeyAttribute fkAttribute = (ForeignKeyAttribute) this.attribute;
|
|
||||||
Font originalFont = g.getFont();
|
Font originalFont = g.getFont();
|
||||||
g.setFont(g.getFont().deriveFont(Font.ITALIC, FK_FONT_SIZE));
|
g.setFont(g.getFont().deriveFont(Font.ITALIC, FK_FONT_SIZE));
|
||||||
Rectangle referenceNameBounds = g.getFontMetrics().getStringBounds(fkAttribute.getFullReferenceName(), g).getBounds();
|
Rectangle referenceNameBounds = g.getFontMetrics().getStringBounds(getFullReferenceName(), g).getBounds();
|
||||||
g.setFont(originalFont);
|
g.setFont(originalFont);
|
||||||
width = Math.max(width, referenceNameBounds.width + (2 * PADDING_X));
|
width = Math.max(width, referenceNameBounds.width + (2 * PADDING_X));
|
||||||
}
|
}
|
||||||
|
@ -103,4 +102,9 @@ public class AttributeViewModel implements ViewModel {
|
||||||
}
|
}
|
||||||
return as;
|
return as;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getFullReferenceName() {
|
||||||
|
if (!this.attribute.hasReference()) return "";
|
||||||
|
return this.attribute.getReference().getRelation().getName() + "." + this.attribute.getReference().getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package nl.andrewlalis.erme.view.view_models;
|
package nl.andrewlalis.erme.view.view_models;
|
||||||
|
|
||||||
import nl.andrewlalis.erme.model.Attribute;
|
import nl.andrewlalis.erme.model.Attribute;
|
||||||
import nl.andrewlalis.erme.model.ForeignKeyAttribute;
|
|
||||||
import nl.andrewlalis.erme.model.MappingModel;
|
import nl.andrewlalis.erme.model.MappingModel;
|
||||||
import nl.andrewlalis.erme.model.Relation;
|
import nl.andrewlalis.erme.model.Relation;
|
||||||
|
|
||||||
|
@ -32,13 +31,12 @@ public class MappingModelViewModel implements ViewModel {
|
||||||
g2.setStroke(dashedStroke);
|
g2.setStroke(dashedStroke);
|
||||||
for (Relation r : this.model.getRelations()) {
|
for (Relation r : this.model.getRelations()) {
|
||||||
for (Attribute a : r.getAttributes()) {
|
for (Attribute a : r.getAttributes()) {
|
||||||
if (a instanceof ForeignKeyAttribute) {
|
if (a.hasReference()) {
|
||||||
ForeignKeyAttribute fk = (ForeignKeyAttribute) a;
|
|
||||||
// Generate a random HSB color for the line, seeded using the referenced attribute's hash code.
|
// Generate a random HSB color for the line, seeded using the referenced attribute's hash code.
|
||||||
Random random = new Random(fk.getReference().hashCode());
|
Random random = new Random(a.getReference().hashCode());
|
||||||
g2.setColor(Color.getHSBColor(random.nextFloat(), 1.0f, 0.8f));
|
g2.setColor(Color.getHSBColor(random.nextFloat(), 1.0f, 0.8f));
|
||||||
Rectangle sourceBounds = fk.getViewModel().getBounds(g);
|
Rectangle sourceBounds = a.getViewModel().getBounds(g);
|
||||||
Rectangle targetBounds = fk.getReference().getViewModel().getBounds(g);
|
Rectangle targetBounds = a.getReference().getViewModel().getBounds(g);
|
||||||
Point sourcePoint = new Point(sourceBounds.x + sourceBounds.width / 2, sourceBounds.y + 3 * targetBounds.height / 4);
|
Point sourcePoint = new Point(sourceBounds.x + sourceBounds.width / 2, sourceBounds.y + 3 * targetBounds.height / 4);
|
||||||
Point targetPoint = new Point(targetBounds.x + targetBounds.width / 2, targetBounds.y + 3 * targetBounds.height / 4);
|
Point targetPoint = new Point(targetBounds.x + targetBounds.width / 2, targetBounds.y + 3 * targetBounds.height / 4);
|
||||||
g2.drawLine(sourcePoint.x, sourcePoint.y, targetPoint.x, targetPoint.y);
|
g2.drawLine(sourcePoint.x, sourcePoint.y, targetPoint.x, targetPoint.y);
|
||||||
|
|
Loading…
Reference in New Issue