From 151f1cd8992360b4bbafbdbffbda0e703e4ac701 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 27 Aug 2013 22:29:35 +0200 Subject: [PATCH] added some commentaries. --- .../conexpng/gui/lattice/LatticeGraph.java | 382 +++++----- .../gui/lattice/LatticeGraphElement.java | 10 +- .../LatticeGraphNodeMouseMotionListener.java | 33 +- .../gui/lattice/LatticeGraphView.java | 667 +++++++++--------- .../conexpng/gui/lattice/LatticeSettings.java | 462 ++++++------ .../conexpng/gui/lattice/LatticeView.java | 522 +++++++------- .../fcatools/conexpng/gui/lattice/Node.java | 572 +++++++-------- .../gui/lattice/NodeMouseClickListener.java | 9 +- .../model/ILatticeGraphAlgorithm.java | 23 +- .../conexpng/model/LatticeConcept.java | 18 +- .../conexpng/model/LatticeGraphComputer.java | 417 +++++------ 11 files changed, 1616 insertions(+), 1499 deletions(-) diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraph.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraph.java index 137bb4f..8e99348 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraph.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraph.java @@ -10,195 +10,213 @@ import fcatools.conexpng.model.LatticeGraphComputer; /** - * This class implemented the graph model for the lattice. - * @author Jan - * + * This class implemented the graph model for the lattice. It contains a list of + * nodes and edges. + * */ public class LatticeGraph { - private List nodes; - private List edges; + private List nodes; + private List edges; - /** + /** * */ - public LatticeGraph() { - this.nodes = new ArrayList<>(); - this.edges = new ArrayList<>(); - } - - /** - * - * @param nodes - * @param edges - */ - public LatticeGraph(List nodes, List edges) { - this.nodes = nodes; - this.edges = edges; - } - - /** - * - * @param i - * @return - */ - public Node getNode(int i) { - return nodes.get(i); - } - - /** - * - * @return - */ - public List getNodes() { - return nodes; - } - - /** - * - * @param nodes - */ - public void setNodes(List nodes) { - this.nodes = nodes; - } - - /** - * - * @param i - * @return - */ - public Edge getEdge(int i) { - return edges.get(i); - } - - /** - * - * @return - */ - public List getEdges() { - return edges; - } - - /** - * - * @param edges - */ - public void setEdges(List edges) { - this.edges = edges; - } - - public boolean missingEdges() { - return edges.isEmpty() && nodes.size() > 1; - } - - public void translate(int d, int e) { - for (Node n : nodes) { - n.setX(n.getX() + d); - n.setY(n.getY() + e); - n.getObjectsLabel().update(d, e, false); - n.getAttributesLabel().update(d, e, false); - } - } - - public void addEdges(Set>> concepts) { - LatticeGraph temp = new LatticeGraphComputer().computeLatticeGraph(concepts, new Rectangle()); - for (Edge e : temp.edges) { - Node u = getNodeWithIntent(e.getU().getAttributes()); - Node v = getNodeWithIntent(e.getV().getAttributes()); - if (u != null && v != null && !u.equals(v)) { - u.getObjects().addAll(e.getU().getObjects()); - v.getObjects().addAll(e.getV().getObjects()); - u.setVisibleAttributes(e.getU().getVisibleAttributes()); - v.setVisibleAttributes(e.getV().getVisibleAttributes()); - u.setVisibleObjects(e.getU().getVisibleObjects()); - v.setVisibleObjects(e.getV().getVisibleObjects()); - u.setLevel(e.getU().getLevel()); - v.setLevel(e.getV().getLevel()); - u.addBelowNode(v); - if(u.getAttributesLabel().getX()==0 && u.getAttributesLabel().getY()==0) - u.getAttributesLabel().setXY(e.getU().getAttributesLabel().getX(), e.getU().getAttributesLabel().getY()); - if(v.getAttributesLabel().getX()==0 && v.getAttributesLabel().getY()==0) - v.getAttributesLabel().setXY(e.getV().getAttributesLabel().getX(), e.getV().getAttributesLabel().getY()); - if(u.getObjectsLabel().getX()==0 && u.getObjectsLabel().getY()==0) - u.getObjectsLabel().setXY(e.getU().getObjectsLabel().getX(), e.getU().getObjectsLabel().getY()); - if(v.getObjectsLabel().getX()==0 && v.getObjectsLabel().getY()==0) - v.getObjectsLabel().setXY(e.getV().getObjectsLabel().getX(), e.getV().getObjectsLabel().getY()); - edges.add(new Edge(u, v)); - } - } - computeAllIdeals(); - } - - public void removeAllDuplicates() { - ArrayList duplicates = new ArrayList<>(); - for (Node n : getNodes()) { - if (n.getObjects().isEmpty() && n.getAttributes().isEmpty()) { - duplicates.add(n); - } - } - getNodes().removeAll(duplicates); - duplicates.clear(); - for (int i = 0; i < getNodes().size() - 1; i++) { - Node u = getNodes().get(i); - for (int j = i + 1; j < getNodes().size(); j++) { - Node v = getNodes().get(j); - if (u.getObjects().equals(v.getObjects()) && u.getAttributes().equals(v.getAttributes())) { - duplicates.add(v); - } - } - - } - getNodes().removeAll(duplicates); - for (Node n : getNodes()) { - n.getBelow().removeAll(duplicates); - } - } - - /** + public LatticeGraph() { + this.nodes = new ArrayList<>(); + this.edges = new ArrayList<>(); + } + + /** + * + * @param nodes + * @param edges + */ + public LatticeGraph(List nodes, List edges) { + this.nodes = nodes; + this.edges = edges; + } + + /** + * + * @param i + * @return + */ + public Node getNode(int i) { + return nodes.get(i); + } + + /** + * + * @return + */ + public List getNodes() { + return nodes; + } + + /** + * + * @param nodes + */ + public void setNodes(List nodes) { + this.nodes = nodes; + } + + /** + * + * @param i + * @return + */ + public Edge getEdge(int i) { + return edges.get(i); + } + + /** + * + * @return + */ + public List getEdges() { + return edges; + } + + /** + * + * @param edges + */ + public void setEdges(List edges) { + this.edges = edges; + } + + public boolean missingEdges() { + return edges.isEmpty() && nodes.size() > 1; + } + + public void translate(int d, int e) { + for (Node n : nodes) { + n.setX(n.getX() + d); + n.setY(n.getY() + e); + n.getObjectsLabel().update(d, e, false); + n.getAttributesLabel().update(d, e, false); + } + } + + public void addEdges( + Set>> concepts) { + LatticeGraph temp = new LatticeGraphComputer().computeLatticeGraph( + concepts, new Rectangle()); + for (Edge e : temp.edges) { + Node u = getNodeWithIntent(e.getU().getAttributes()); + Node v = getNodeWithIntent(e.getV().getAttributes()); + if (u != null && v != null && !u.equals(v)) { + u.getObjects().addAll(e.getU().getObjects()); + v.getObjects().addAll(e.getV().getObjects()); + u.setVisibleAttributes(e.getU().getVisibleAttributes()); + v.setVisibleAttributes(e.getV().getVisibleAttributes()); + u.setVisibleObjects(e.getU().getVisibleObjects()); + v.setVisibleObjects(e.getV().getVisibleObjects()); + u.setLevel(e.getU().getLevel()); + v.setLevel(e.getV().getLevel()); + u.addBelowNode(v); + if (u.getAttributesLabel().getX() == 0 + && u.getAttributesLabel().getY() == 0) + u.getAttributesLabel().setXY( + e.getU().getAttributesLabel().getX(), + e.getU().getAttributesLabel().getY()); + if (v.getAttributesLabel().getX() == 0 + && v.getAttributesLabel().getY() == 0) + v.getAttributesLabel().setXY( + e.getV().getAttributesLabel().getX(), + e.getV().getAttributesLabel().getY()); + if (u.getObjectsLabel().getX() == 0 + && u.getObjectsLabel().getY() == 0) + u.getObjectsLabel().setXY( + e.getU().getObjectsLabel().getX(), + e.getU().getObjectsLabel().getY()); + if (v.getObjectsLabel().getX() == 0 + && v.getObjectsLabel().getY() == 0) + v.getObjectsLabel().setXY( + e.getV().getObjectsLabel().getX(), + e.getV().getObjectsLabel().getY()); + edges.add(new Edge(u, v)); + } + } + computeAllIdeals(); + } + + public void removeAllDuplicates() { + ArrayList duplicates = new ArrayList<>(); + for (Node n : getNodes()) { + if (n.getObjects().isEmpty() && n.getAttributes().isEmpty()) { + duplicates.add(n); + } + } + getNodes().removeAll(duplicates); + duplicates.clear(); + for (int i = 0; i < getNodes().size() - 1; i++) { + Node u = getNodes().get(i); + for (int j = i + 1; j < getNodes().size(); j++) { + Node v = getNodes().get(j); + if (u.getObjects().equals(v.getObjects()) + && u.getAttributes().equals(v.getAttributes())) { + duplicates.add(v); + } + } + + } + getNodes().removeAll(duplicates); + for (Node n : getNodes()) { + n.getBelow().removeAll(duplicates); + } + } + + /** * */ - public void computeAllIdeals() { - // sort the list of nodes from bottom too top - - ArrayList q = new ArrayList<>(); - for (Node n : getNodes()) { - if (q.size() == 0) { - q.add(n); - } else { - for (int i = 0; i < q.size(); i++) { - if (q.get(i).getObjects().containsAll(n.getObjects()) - || q.get(i).getObjects().size() > n.getObjects().size()) { - q.add(i, n); - break; - } - if (i + 1 == q.size()) { - q.add(i + 1, n); - break; - } - } - } - } - for (int i = 1; i < q.size(); i++) { - Node u = q.get(i); - for (int j = i - 1; j >= 0; j--) { - Node v = q.get(j); - if (u.getObjects().containsAll(v.getObjects()) && v.getAttributes().containsAll(u.getAttributes())) { - u.getIdeal().add(v); - } - } - } - } - - private Node getNodeWithIntent(Set attributes) { - for (Node n : nodes) { - if (n.getAttributes().containsAll(attributes) && attributes.containsAll(n.getAttributes())) - return n; - } - return null; - } - - public boolean isEmpty() { - return nodes.isEmpty(); - } + public void computeAllIdeals() { + // sort the list of nodes from bottom too top + + ArrayList q = new ArrayList<>(); + for (Node n : getNodes()) { + if (q.size() == 0) { + q.add(n); + } else { + for (int i = 0; i < q.size(); i++) { + if (q.get(i).getObjects().containsAll(n.getObjects()) + || q.get(i).getObjects().size() > n.getObjects() + .size()) { + q.add(i, n); + break; + } + if (i + 1 == q.size()) { + q.add(i + 1, n); + break; + } + } + } + } + for (int i = 1; i < q.size(); i++) { + Node u = q.get(i); + for (int j = i - 1; j >= 0; j--) { + Node v = q.get(j); + if (u.getObjects().containsAll(v.getObjects()) + && v.getAttributes().containsAll(u.getAttributes())) { + u.getIdeal().add(v); + } + } + } + } + + private Node getNodeWithIntent(Set attributes) { + for (Node n : nodes) { + if (n.getAttributes().containsAll(attributes) + && attributes.containsAll(n.getAttributes())) + return n; + } + return null; + } + + public boolean isEmpty() { + return nodes.isEmpty(); + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphElement.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphElement.java index 9c0cc06..5bb2493 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphElement.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphElement.java @@ -2,11 +2,19 @@ import java.awt.Rectangle; +/** + * This interface has to be implemented by all elements which are in relation to + * the LatticeGraph.class. + * + */ public interface LatticeGraphElement { - + public abstract void update(int x, int y, boolean first); + public abstract int getX(); + public abstract int getY(); + public abstract Rectangle getBounds(); } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphNodeMouseMotionListener.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphNodeMouseMotionListener.java index 5c93182..5c429d1 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphNodeMouseMotionListener.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphNodeMouseMotionListener.java @@ -3,26 +3,29 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; +/** + * This class implemented the mouseMotionListener. + * + */ public class LatticeGraphNodeMouseMotionListener implements MouseMotionListener { - private LatticeGraphElement n; + private LatticeGraphElement n; - public LatticeGraphNodeMouseMotionListener(LatticeGraphElement n) { - this.n = n; - } + public LatticeGraphNodeMouseMotionListener(LatticeGraphElement n) { + this.n = n; + } - @Override - public void mouseDragged(MouseEvent e) { - int newX = e.getX(); - int newY = e.getY(); - n.update(newX, newY, true); - } + @Override + public void mouseDragged(MouseEvent e) { + int newX = e.getX(); + int newY = e.getY(); + n.update(newX, newY, true); + } - @Override - public void mouseMoved(MouseEvent arg0) { - // TODO Auto-generated method stub - - } + @Override + public void mouseMoved(MouseEvent arg0) { + // TODO Auto-generated method stub + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphView.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphView.java index 79e6ae0..bde4a45 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphView.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeGraphView.java @@ -36,339 +36,344 @@ import fcatools.conexpng.Conf; -/*The JSVGCanvas provides a set of build-in interactors that - * let the users manipulate the displayed document, including ones for zooming, - * panning and rotating. Interactors catch user input to the JSVGCanvas component - * and translate them into behaviour. +/** + * This class represented the graphical visualisation of the graph. It draws the + * lattice graph. + * + * The JSVGCanvas provides a set of build-in interactors that let the users + * manipulate the displayed document, including ones for zooming, panning and + * rotating. Interactors catch user input to the JSVGCanvas component and + * translate them into behaviour. */ public class LatticeGraphView extends JSVGCanvas { - private static final long serialVersionUID = -8623872314193862285L; - private Conf state; - private ArrayList lastIdeal; - private boolean idealHighlighting; - private boolean move; - private static Font font = new Font("Monospaced", Font.PLAIN, 12); - private Stroke drawingStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, - BasicStroke.JOIN_BEVEL, 0, new float[] { 9 }, 0); - - public LatticeGraphView(Conf state) { - this.state = state; - this.lastIdeal = new ArrayList(); - } - - private void init() { - this.removeAll(); - for (Node n : state.lattice.getNodes()) { - this.add(n); - n.addMouseMotionListener(new LatticeGraphNodeMouseMotionListener(n)); - n.addMouseListener(new NodeMouseClickListener(n)); - - this.add(n.getAttributesLabel()); - n.getAttributesLabel().addMouseMotionListener( - new LatticeGraphNodeMouseMotionListener(n - .getAttributesLabel())); - - this.add(n.getObjectsLabel()); - n.getObjectsLabel() - .addMouseMotionListener( - new LatticeGraphNodeMouseMotionListener(n - .getObjectsLabel())); - } - - } - - @Override - public void paint(Graphics g0) { - super.paint(g0); - - Graphics2D g = (Graphics2D) g0; - - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - - g.setColor(Color.BLACK); - int radius = LatticeView.radius; - - for (Node n : state.lattice.getNodes()) { - if (n.isPartOfAnIdeal() && !lastIdeal.contains(n)) { - lastIdeal.clear(); - } - } - - if (!state.lattice.getEdges().isEmpty() && state.guiConf.showEdges) { - for (Edge e : state.lattice.getEdges()) { - g.setColor(Color.BLACK); - if (e.getU().isPartOfAnIdeal() && e.getV().isPartOfAnIdeal() - && idealHighlighting) { - g.setColor(Color.BLUE); - } else if (!(e.getU().isPartOfAnIdeal() && e.getV() - .isPartOfAnIdeal()) && idealHighlighting) { - g.setColor(Color.LIGHT_GRAY); - } - g.drawLine(e.getU().getX() + radius, e.getU().getY() + radius, - e.getV().getX() + radius, e.getV().getY() + radius); - } - } - for (Node n : state.lattice.getNodes()) { - int x = n.getX(); - int y = n.getY(); - - // draw a normal node - g.setColor(Color.WHITE); - g.fillOval(x, y, radius * 2, radius * 2); - g.setColor(Color.BLACK); - g.drawOval(x, y, radius * 2, radius * 2); - - // label drawing - if ((!n.getVisibleObjects().isEmpty()) && state.guiConf.showObjectLabel) { - g.setColor(Color.BLACK); - - // dashed line - g.setStroke(drawingStroke); - g.drawLine(n.getObjectsLabel().getX() - + n.getObjectsLabel().getBounds().width / 2, n - .getObjectsLabel().getY(), x + radius, y + radius); - g.setStroke(new BasicStroke()); - - // draw the label - String content = n.getObjectsLabel().elementsToString(); - g.setFont(font); - FontMetrics fm = g.getFontMetrics(); - Rectangle r = fm.getStringBounds(content, g).getBounds(); - - g.setColor(Color.WHITE); - g.fillRect(r.x + n.getObjectsLabel().getX(), r.y - + n.getObjectsLabel().getY(), r.width, r.height); - - g.setColor(Color.BLACK); - - g.drawString(content, n.getObjectsLabel().getX(), n - .getObjectsLabel().getY()); - - g.drawRect(r.x + n.getObjectsLabel().getX(), r.y - + n.getObjectsLabel().getY(), r.width, r.height); - - n.getObjectsLabel().setBounds(r.x + n.getObjectsLabel().getX(), - r.y + n.getObjectsLabel().getY(), r.width, r.height); - - } - - // analog like objects - if ((!n.getVisibleAttributes().isEmpty()) - && state.guiConf.showAttributLabel) { - g.setColor(Color.BLACK); - g.setStroke(drawingStroke); - g.drawLine(n.getAttributesLabel().getX() - + n.getAttributesLabel().getBounds().width / 2, n - .getAttributesLabel().getY(), x + radius, y + radius); - g.setStroke(new BasicStroke()); - - String content = n.getAttributesLabel().elementsToString(); - g.setFont(font); - FontMetrics fm = g.getFontMetrics(); - Rectangle r = fm.getStringBounds(content, g).getBounds(); - - g.setColor(Color.WHITE); - g.fillRect(r.x + n.getAttributesLabel().getX(), r.y - + n.getAttributesLabel().getY(), r.width, r.height); - - g.setColor(Color.BLUE); - - g.drawString(content, n.getAttributesLabel().getX(), n - .getAttributesLabel().getY()); - - g.setColor(Color.BLACK); - g.drawRect(r.x + n.getAttributesLabel().getX(), r.y - + n.getAttributesLabel().getY(), r.width, r.height); - - n.getAttributesLabel().setBounds( - r.x + n.getAttributesLabel().getX(), - r.y + n.getAttributesLabel().getY(), r.width, r.height); - - // draw filled node - - } - if (!n.getVisibleAttributes().isEmpty() - && !n.getVisibleObjects().isEmpty()) { - g.setColor(Color.BLACK); - g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - g.setColor(Color.BLUE); - g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, - 0, 180); - g.setColor(Color.BLACK); - g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - - } else if (!n.getVisibleAttributes().isEmpty()) { - g.setColor(Color.BLUE); - g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - g.setColor(Color.WHITE); - g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, - 180, 180); - g.setColor(Color.BLACK); - g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - } else if (!n.getVisibleObjects().isEmpty()) { - g.setColor(Color.BLACK); - g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - g.setColor(Color.WHITE); - g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, - 0, 180); - g.setColor(Color.BLACK); - g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); - } - - // highlight an ideal if it selected - - if (n.isPartOfAnIdeal() && idealHighlighting) { - lastIdeal.add(n); - g.setColor(Color.BLUE); - g.drawOval(x, y, radius * 2, radius * 2); - } else if ((!n.isPartOfAnIdeal()) && idealHighlighting) { - g.setColor(Color.LIGHT_GRAY); - g.drawOval(x, y, radius * 2, radius * 2); - } - } - } - - /** - * This method creates an output file of the lattice. - * - * @param path - */ - public void exportLattice(String path) { - DOMImplementation domImpl = GenericDOMImplementation - .getDOMImplementation(); - - String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; - Document document = domImpl.createDocument(svgNS, "svg", null); - - SVGGraphics2D svgGenerator = new SVGGraphics2D(document); - this.paint(svgGenerator); - - Writer out; - String svg_URI_input; - try { - - // calculating the output file size - int maxWidth = 0; - int maxHeight = 0; - for (Node n : state.lattice.getNodes()) { - if (maxWidth < n.getX()) { - maxWidth = n.getX(); - } - if (maxHeight < n.getY()) { - maxHeight = n.getY(); - } - if (state.guiConf.showAttributLabel) { - if (maxWidth < n.getAttributesLabel().getX()) { - maxWidth = n.getAttributesLabel().getX(); - } - if (maxHeight < n.getAttributesLabel().getY()) { - maxHeight = n.getAttributesLabel().getY(); - } - } - if (state.guiConf.showObjectLabel) { - if (maxWidth < n.getObjectsLabel().getX()) { - maxWidth = n.getObjectsLabel().getX(); - } - if (maxHeight < n.getObjectsLabel().getY()) { - maxHeight = n.getObjectsLabel().getY(); - } - } - - } - // default case: create a svg file. - if (!(path.contains(".pdf") || path.contains(".jpg") - || path.contains(".jpeg") || path.contains(".png"))) { - File svg = new File(path + ".svg"); - out = new FileWriter(svg); - svgGenerator.stream(out, true); - - } else { - File temp = new File("test_batik.svg"); - out = new FileWriter(temp); - svgGenerator.stream(out, true); - - svg_URI_input = Paths.get("test_batik.svg").toUri().toString(); - TranscoderInput input_svg_image = new TranscoderInput( - svg_URI_input); - OutputStream ostream; - ostream = new FileOutputStream(path); - - Rectangle r = new Rectangle(maxWidth + 30, maxHeight + 30); - TranscoderOutput output_file = new TranscoderOutput(ostream); - Transcoder transcoder = null; - - if (path.contains(".pdf")) { - transcoder = new PDFTranscoder(); - transcoder.addTranscodingHint(PDFTranscoder.KEY_WIDTH, - new Float(r.width)); - transcoder.addTranscodingHint(PDFTranscoder.KEY_HEIGHT, - new Float(r.height)); - transcoder.addTranscodingHint(PDFTranscoder.KEY_AOI, r); - - } else if (path.contains(".jpg") || path.contains(".jpeg")) { - transcoder = new JPEGTranscoder(); - transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, - new Float(.8)); - transcoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, - new Float(r.width)); - transcoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, - new Float(r.height)); - transcoder.addTranscodingHint(JPEGTranscoder.KEY_AOI, r); - - } else { - transcoder = new PNGTranscoder(); - transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, - new Float(r.width)); - transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, - new Float(r.height)); - transcoder.addTranscodingHint(PNGTranscoder.KEY_AOI, r); - } - - transcoder.transcode(input_svg_image, output_file); - ostream.flush(); - ostream.close(); - temp.delete(); - } - - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (TranscoderException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void updateLatticeGraph() { - init(); - setMove(move); - } - - public void resetHighlighting() { - for (Node n : lastIdeal) { - n.setPartOfAnIdeal(false); - } - } - - public void setMove(boolean change) { - move = change; - for (Node n : state.lattice.getNodes()) { - n.moveSubgraph(change); - } - } - - public void idealHighlighting(boolean change) { - this.idealHighlighting = change; - } + private static final long serialVersionUID = -8623872314193862285L; + private Conf state; + private ArrayList lastIdeal; + private boolean idealHighlighting; + private boolean move; + private static Font font = new Font("Monospaced", Font.PLAIN, 12); + private Stroke drawingStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_BEVEL, 0, new float[] { 9 }, 0); + + public LatticeGraphView(Conf state) { + this.state = state; + this.lastIdeal = new ArrayList(); + } + + private void init() { + this.removeAll(); + for (Node n : state.lattice.getNodes()) { + this.add(n); + n.addMouseMotionListener(new LatticeGraphNodeMouseMotionListener(n)); + n.addMouseListener(new NodeMouseClickListener(n)); + + this.add(n.getAttributesLabel()); + n.getAttributesLabel().addMouseMotionListener( + new LatticeGraphNodeMouseMotionListener(n + .getAttributesLabel())); + + this.add(n.getObjectsLabel()); + n.getObjectsLabel() + .addMouseMotionListener( + new LatticeGraphNodeMouseMotionListener(n + .getObjectsLabel())); + } + + } + + @Override + public void paint(Graphics g0) { + super.paint(g0); + + Graphics2D g = (Graphics2D) g0; + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + g.setColor(Color.BLACK); + int radius = LatticeView.radius; + + for (Node n : state.lattice.getNodes()) { + if (n.isPartOfAnIdeal() && !lastIdeal.contains(n)) { + lastIdeal.clear(); + } + } + + if (!state.lattice.getEdges().isEmpty() && state.guiConf.showEdges) { + for (Edge e : state.lattice.getEdges()) { + g.setColor(Color.BLACK); + if (e.getU().isPartOfAnIdeal() && e.getV().isPartOfAnIdeal() + && idealHighlighting) { + g.setColor(Color.BLUE); + } else if (!(e.getU().isPartOfAnIdeal() && e.getV() + .isPartOfAnIdeal()) && idealHighlighting) { + g.setColor(Color.LIGHT_GRAY); + } + g.drawLine(e.getU().getX() + radius, e.getU().getY() + radius, + e.getV().getX() + radius, e.getV().getY() + radius); + } + } + for (Node n : state.lattice.getNodes()) { + int x = n.getX(); + int y = n.getY(); + + // draw a normal node + g.setColor(Color.WHITE); + g.fillOval(x, y, radius * 2, radius * 2); + g.setColor(Color.BLACK); + g.drawOval(x, y, radius * 2, radius * 2); + + // label drawing + if ((!n.getVisibleObjects().isEmpty()) + && state.guiConf.showObjectLabel) { + g.setColor(Color.BLACK); + + // dashed line + g.setStroke(drawingStroke); + g.drawLine(n.getObjectsLabel().getX() + + n.getObjectsLabel().getBounds().width / 2, n + .getObjectsLabel().getY(), x + radius, y + radius); + g.setStroke(new BasicStroke()); + + // draw the label + String content = n.getObjectsLabel().elementsToString(); + g.setFont(font); + FontMetrics fm = g.getFontMetrics(); + Rectangle r = fm.getStringBounds(content, g).getBounds(); + + g.setColor(Color.WHITE); + g.fillRect(r.x + n.getObjectsLabel().getX(), r.y + + n.getObjectsLabel().getY(), r.width, r.height); + + g.setColor(Color.BLACK); + + g.drawString(content, n.getObjectsLabel().getX(), n + .getObjectsLabel().getY()); + + g.drawRect(r.x + n.getObjectsLabel().getX(), r.y + + n.getObjectsLabel().getY(), r.width, r.height); + + n.getObjectsLabel().setBounds(r.x + n.getObjectsLabel().getX(), + r.y + n.getObjectsLabel().getY(), r.width, r.height); + + } + + // analog like objects + if ((!n.getVisibleAttributes().isEmpty()) + && state.guiConf.showAttributLabel) { + g.setColor(Color.BLACK); + g.setStroke(drawingStroke); + g.drawLine(n.getAttributesLabel().getX() + + n.getAttributesLabel().getBounds().width / 2, n + .getAttributesLabel().getY(), x + radius, y + radius); + g.setStroke(new BasicStroke()); + + String content = n.getAttributesLabel().elementsToString(); + g.setFont(font); + FontMetrics fm = g.getFontMetrics(); + Rectangle r = fm.getStringBounds(content, g).getBounds(); + + g.setColor(Color.WHITE); + g.fillRect(r.x + n.getAttributesLabel().getX(), r.y + + n.getAttributesLabel().getY(), r.width, r.height); + + g.setColor(Color.BLUE); + + g.drawString(content, n.getAttributesLabel().getX(), n + .getAttributesLabel().getY()); + + g.setColor(Color.BLACK); + g.drawRect(r.x + n.getAttributesLabel().getX(), r.y + + n.getAttributesLabel().getY(), r.width, r.height); + + n.getAttributesLabel().setBounds( + r.x + n.getAttributesLabel().getX(), + r.y + n.getAttributesLabel().getY(), r.width, r.height); + + // draw filled node + + } + if (!n.getVisibleAttributes().isEmpty() + && !n.getVisibleObjects().isEmpty()) { + g.setColor(Color.BLACK); + g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + g.setColor(Color.BLUE); + g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, + 0, 180); + g.setColor(Color.BLACK); + g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + + } else if (!n.getVisibleAttributes().isEmpty()) { + g.setColor(Color.BLUE); + g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + g.setColor(Color.WHITE); + g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, + 180, 180); + g.setColor(Color.BLACK); + g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + } else if (!n.getVisibleObjects().isEmpty()) { + g.setColor(Color.BLACK); + g.fillOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + g.setColor(Color.WHITE); + g.fillArc(x, y, LatticeView.radius * 2, LatticeView.radius * 2, + 0, 180); + g.setColor(Color.BLACK); + g.drawOval(x, y, LatticeView.radius * 2, LatticeView.radius * 2); + } + + // highlight an ideal if it selected + + if (n.isPartOfAnIdeal() && idealHighlighting) { + lastIdeal.add(n); + g.setColor(Color.BLUE); + g.drawOval(x, y, radius * 2, radius * 2); + } else if ((!n.isPartOfAnIdeal()) && idealHighlighting) { + g.setColor(Color.LIGHT_GRAY); + g.drawOval(x, y, radius * 2, radius * 2); + } + } + } + + /** + * This method creates an output file of the lattice. + * + * @param path + */ + public void exportLattice(String path) { + DOMImplementation domImpl = GenericDOMImplementation + .getDOMImplementation(); + + String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; + Document document = domImpl.createDocument(svgNS, "svg", null); + + SVGGraphics2D svgGenerator = new SVGGraphics2D(document); + this.paint(svgGenerator); + + Writer out; + String svg_URI_input; + try { + + // calculating the output file size + int maxWidth = 0; + int maxHeight = 0; + for (Node n : state.lattice.getNodes()) { + if (maxWidth < n.getX()) { + maxWidth = n.getX(); + } + if (maxHeight < n.getY()) { + maxHeight = n.getY(); + } + if (state.guiConf.showAttributLabel) { + if (maxWidth < n.getAttributesLabel().getX()) { + maxWidth = n.getAttributesLabel().getX(); + } + if (maxHeight < n.getAttributesLabel().getY()) { + maxHeight = n.getAttributesLabel().getY(); + } + } + if (state.guiConf.showObjectLabel) { + if (maxWidth < n.getObjectsLabel().getX()) { + maxWidth = n.getObjectsLabel().getX(); + } + if (maxHeight < n.getObjectsLabel().getY()) { + maxHeight = n.getObjectsLabel().getY(); + } + } + + } + // default case: create a svg file. + if (!(path.contains(".pdf") || path.contains(".jpg") + || path.contains(".jpeg") || path.contains(".png"))) { + File svg = new File(path + ".svg"); + out = new FileWriter(svg); + svgGenerator.stream(out, true); + + } else { + File temp = new File("test_batik.svg"); + out = new FileWriter(temp); + svgGenerator.stream(out, true); + + svg_URI_input = Paths.get("test_batik.svg").toUri().toString(); + TranscoderInput input_svg_image = new TranscoderInput( + svg_URI_input); + OutputStream ostream; + ostream = new FileOutputStream(path); + + Rectangle r = new Rectangle(maxWidth + 30, maxHeight + 30); + TranscoderOutput output_file = new TranscoderOutput(ostream); + Transcoder transcoder = null; + + if (path.contains(".pdf")) { + transcoder = new PDFTranscoder(); + transcoder.addTranscodingHint(PDFTranscoder.KEY_WIDTH, + new Float(r.width)); + transcoder.addTranscodingHint(PDFTranscoder.KEY_HEIGHT, + new Float(r.height)); + transcoder.addTranscodingHint(PDFTranscoder.KEY_AOI, r); + + } else if (path.contains(".jpg") || path.contains(".jpeg")) { + transcoder = new JPEGTranscoder(); + transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, + new Float(.8)); + transcoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, + new Float(r.width)); + transcoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, + new Float(r.height)); + transcoder.addTranscodingHint(JPEGTranscoder.KEY_AOI, r); + + } else { + transcoder = new PNGTranscoder(); + transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, + new Float(r.width)); + transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, + new Float(r.height)); + transcoder.addTranscodingHint(PNGTranscoder.KEY_AOI, r); + } + + transcoder.transcode(input_svg_image, output_file); + ostream.flush(); + ostream.close(); + temp.delete(); + } + + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (TranscoderException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void updateLatticeGraph() { + init(); + setMove(move); + } + + public void resetHighlighting() { + for (Node n : lastIdeal) { + n.setPartOfAnIdeal(false); + } + } + + public void setMove(boolean change) { + move = change; + for (Node n : state.lattice.getNodes()) { + n.moveSubgraph(change); + } + } + + public void idealHighlighting(boolean change) { + this.idealHighlighting = change; + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeSettings.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeSettings.java index c8789b8..9be777f 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeSettings.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeSettings.java @@ -18,234 +18,244 @@ import fcatools.conexpng.Conf; import fcatools.conexpng.model.FormalContext; +/** + * This class implements the accordion menu of the lattice tab. + * + */ public class LatticeSettings extends WebAccordion { - /** + /** * */ - private static final long serialVersionUID = 3981827958628799515L; - private Conf state; - private FormalContext context; - private List attributeCheckBoxes; - private List objectCheckBoxes; - - public LatticeSettings(Conf state) { - this.state = state; - this.context = state.context; - this.attributeCheckBoxes = new ArrayList<>(); - this.objectCheckBoxes = new ArrayList<>(); - this.addPane(0, "Lattice", getLatticePanel()); - this.addPane(1, "Objects", getObjectPanel()); - this.addPane(2, "Attributes", getAttributePanel()); - } - - private WebScrollPane getLatticePanel() { - WebPanel panel = new WebPanel(new BorderLayout()); - panel.setLayout(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.anchor = GridBagConstraints.WEST; - gbc.gridx = 0; - gbc.gridy = 0; - - panel.add(getLatticeObjectPanel(), gbc); - - gbc.gridx = 1; - - panel.add(getLatticeAttrPanel(), gbc); - - gbc.gridx = 0; - gbc.gridy++; - panel.add(new WebLabel("Edges:"), gbc); - final WebRadioButton noneEdges = new WebRadioButton("none"); - gbc.gridy++; - final WebRadioButton showEdges = new WebRadioButton("show"); - showEdges.setSelected(true); - noneEdges.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showEdges = false; - noneEdges.setSelected(true); - showEdges.setSelected(false); - state.showLabelsChanged(); - } - }); - showEdges.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showEdges = true; - showEdges.setSelected(true); - noneEdges.setSelected(false); - state.showLabelsChanged(); - } - }); - - panel.add(noneEdges, gbc); - gbc.gridx = 1; - panel.add(showEdges, gbc); - - return new WebScrollPane(panel); - } - - // this methode places object's radiobuttons - private WebPanel getLatticeObjectPanel() { - WebPanel panelObjects = new WebPanel(new BorderLayout()); - panelObjects.setLayout(new GridBagLayout()); - GridBagConstraints gbo = new GridBagConstraints(); - gbo.anchor = GridBagConstraints.WEST; - gbo.gridx = 0; - gbo.gridy = 1; - panelObjects.add(new WebLabel("Objects:"), gbo); - gbo.gridy = 2; - final WebRadioButton noneObjects = new WebRadioButton(); - noneObjects.setText("none"); - - final WebRadioButton labelsObjects = new WebRadioButton(); - labelsObjects.setText("labels"); - labelsObjects.setSelected(true); - state.guiConf.showObjectLabel = true; - - noneObjects.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showObjectLabel = false; - noneObjects.setSelected(true); - labelsObjects.setSelected(false); - state.showLabelsChanged(); - } - }); - labelsObjects.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showObjectLabel = true; - labelsObjects.setSelected(true); - noneObjects.setSelected(false); - state.showLabelsChanged(); - } - }); - panelObjects.add(noneObjects, gbo); - gbo.gridy = 3; - panelObjects.add(labelsObjects, gbo); - return panelObjects; - } - - // this methode places attributes' radiobuttons - private WebPanel getLatticeAttrPanel() { - WebPanel panelAttributes = new WebPanel(new BorderLayout()); - panelAttributes.setLayout(new GridBagLayout()); - GridBagConstraints gba = new GridBagConstraints(); - gba.anchor = GridBagConstraints.WEST; - gba.gridx = 0; - gba.gridy = 1; - panelAttributes.add(new WebLabel("Attributes:"), gba); - gba.gridy = 2; - final WebRadioButton noneAttributes = new WebRadioButton(); - noneAttributes.setText("none"); - final WebRadioButton labelsAttributes = new WebRadioButton(); - labelsAttributes.setText("labels"); - labelsAttributes.setSelected(true); - state.guiConf.showAttributLabel = true; - - - noneAttributes.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showAttributLabel = false; - noneAttributes.setSelected(true); - labelsAttributes.setSelected(false); - state.showLabelsChanged(); - } - }); - labelsAttributes.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - state.guiConf.showAttributLabel = true; - labelsAttributes.setSelected(true); - noneAttributes.setSelected(false); - state.showLabelsChanged(); - } - }); - panelAttributes.add(noneAttributes, gba); - gba.gridy = 3; - panelAttributes.add(labelsAttributes, gba); - return panelAttributes; - } - - // creates a jpanel including checkbox for each attribute - private WebScrollPane getAttributePanel() { - WebPanel panel = new WebPanel(new BorderLayout()); - panel.setLayout(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.anchor = GridBagConstraints.WEST; - gbc.gridx = 0; - gbc.gridy = 0; - for (String s : context.getAttributes()) { - gbc.gridy++; - final WebCheckBox box = new WebCheckBox(s); - box.setSelected(!state.context.getDontConsideredAttr().contains(box.getText())); - box.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent arg0) { - if (!box.isSelected()) { - state.context.dontConsiderAttribute(box.getText()); - } else { - state.context.considerAttribute(box.getText()); - } - state.temporaryContextChanged(); - } - }); - - panel.add(box, gbc); - attributeCheckBoxes.add(box); - } - WebScrollPane sp = new WebScrollPane(panel); - return sp; - } - - // creates a jpanel including checkbox for each object - private WebScrollPane getObjectPanel() { - WebPanel panel = new WebPanel(new BorderLayout()); - panel.setLayout(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.anchor = GridBagConstraints.WEST; - gbc.gridx = 0; - gbc.gridy = 0; - for (FullObject s : context.getObjects()) { - gbc.gridy++; - final WebCheckBox box = new WebCheckBox(s.getIdentifier()); - final FullObject temp = s; - box.setSelected(!state.context.getDontConsideredObj().contains(temp)); - box.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent arg0) { - if (!box.isSelected()) { - state.context.dontConsiderObject(temp); - } else { - state.context.considerObject(temp); - } - state.temporaryContextChanged(); - } - }); - - panel.add(box, gbc); - objectCheckBoxes.add(box); - } - WebScrollPane sp = new WebScrollPane(panel); - return sp; - } - - public void update(Conf state) { - this.context = state.context; - this.removePane(1); - objectCheckBoxes.clear(); - this.addPane(1, "Objects", getObjectPanel()); - this.removePane(2); - attributeCheckBoxes.clear(); - this.addPane(2, "Attributes", getAttributePanel()); - } + private static final long serialVersionUID = 3981827958628799515L; + private Conf state; + private FormalContext context; + private List attributeCheckBoxes; + private List objectCheckBoxes; + + public LatticeSettings(Conf state) { + this.state = state; + this.context = state.context; + this.attributeCheckBoxes = new ArrayList<>(); + this.objectCheckBoxes = new ArrayList<>(); + this.addPane(0, "Lattice", getLatticePanel()); + this.addPane(1, "Objects", getObjectPanel()); + this.addPane(2, "Attributes", getAttributePanel()); + } + + private WebScrollPane getLatticePanel() { + WebPanel panel = new WebPanel(new BorderLayout()); + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 0; + gbc.gridy = 0; + + panel.add(getLatticeObjectPanel(), gbc); + + gbc.gridx = 1; + + panel.add(getLatticeAttrPanel(), gbc); + + gbc.gridx = 0; + gbc.gridy++; + panel.add(new WebLabel("Edges:"), gbc); + final WebRadioButton noneEdges = new WebRadioButton("none"); + gbc.gridy++; + final WebRadioButton showEdges = new WebRadioButton("show"); + showEdges.setSelected(true); + noneEdges.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showEdges = false; + noneEdges.setSelected(true); + showEdges.setSelected(false); + state.showLabelsChanged(); + } + }); + showEdges.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showEdges = true; + showEdges.setSelected(true); + noneEdges.setSelected(false); + state.showLabelsChanged(); + } + }); + + panel.add(noneEdges, gbc); + gbc.gridx = 1; + panel.add(showEdges, gbc); + + return new WebScrollPane(panel); + } + + // this methode places object's radiobuttons + private WebPanel getLatticeObjectPanel() { + WebPanel panelObjects = new WebPanel(new BorderLayout()); + panelObjects.setLayout(new GridBagLayout()); + GridBagConstraints gbo = new GridBagConstraints(); + gbo.anchor = GridBagConstraints.WEST; + gbo.gridx = 0; + gbo.gridy = 1; + panelObjects.add(new WebLabel("Objects:"), gbo); + gbo.gridy = 2; + final WebRadioButton noneObjects = new WebRadioButton(); + noneObjects.setText("none"); + + final WebRadioButton labelsObjects = new WebRadioButton(); + labelsObjects.setText("labels"); + labelsObjects.setSelected(true); + state.guiConf.showObjectLabel = true; + + noneObjects.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showObjectLabel = false; + noneObjects.setSelected(true); + labelsObjects.setSelected(false); + state.showLabelsChanged(); + } + }); + labelsObjects.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showObjectLabel = true; + labelsObjects.setSelected(true); + noneObjects.setSelected(false); + state.showLabelsChanged(); + } + }); + panelObjects.add(noneObjects, gbo); + gbo.gridy = 3; + panelObjects.add(labelsObjects, gbo); + return panelObjects; + } + + // this methode places attributes' radiobuttons + private WebPanel getLatticeAttrPanel() { + WebPanel panelAttributes = new WebPanel(new BorderLayout()); + panelAttributes.setLayout(new GridBagLayout()); + GridBagConstraints gba = new GridBagConstraints(); + gba.anchor = GridBagConstraints.WEST; + gba.gridx = 0; + gba.gridy = 1; + panelAttributes.add(new WebLabel("Attributes:"), gba); + gba.gridy = 2; + final WebRadioButton noneAttributes = new WebRadioButton(); + noneAttributes.setText("none"); + final WebRadioButton labelsAttributes = new WebRadioButton(); + labelsAttributes.setText("labels"); + labelsAttributes.setSelected(true); + state.guiConf.showAttributLabel = true; + + noneAttributes.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showAttributLabel = false; + noneAttributes.setSelected(true); + labelsAttributes.setSelected(false); + state.showLabelsChanged(); + } + }); + labelsAttributes.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + state.guiConf.showAttributLabel = true; + labelsAttributes.setSelected(true); + noneAttributes.setSelected(false); + state.showLabelsChanged(); + } + }); + panelAttributes.add(noneAttributes, gba); + gba.gridy = 3; + panelAttributes.add(labelsAttributes, gba); + return panelAttributes; + } + + // creates a jpanel including checkbox for each attribute + private WebScrollPane getAttributePanel() { + WebPanel panel = new WebPanel(new BorderLayout()); + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 0; + gbc.gridy = 0; + for (String s : context.getAttributes()) { + gbc.gridy++; + final WebCheckBox box = new WebCheckBox(s); + box.setSelected(!state.context.getDontConsideredAttr().contains( + box.getText())); + box.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + if (!box.isSelected()) { + state.context.dontConsiderAttribute(box.getText()); + } else { + state.context.considerAttribute(box.getText()); + } + state.temporaryContextChanged(); + } + }); + + panel.add(box, gbc); + attributeCheckBoxes.add(box); + } + WebScrollPane sp = new WebScrollPane(panel); + return sp; + } + + // creates a jpanel including checkbox for each object + private WebScrollPane getObjectPanel() { + WebPanel panel = new WebPanel(new BorderLayout()); + panel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 0; + gbc.gridy = 0; + for (FullObject s : context.getObjects()) { + gbc.gridy++; + final WebCheckBox box = new WebCheckBox(s.getIdentifier()); + final FullObject temp = s; + box.setSelected(!state.context.getDontConsideredObj() + .contains(temp)); + box.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + if (!box.isSelected()) { + state.context.dontConsiderObject(temp); + } else { + state.context.considerObject(temp); + } + state.temporaryContextChanged(); + } + }); + + panel.add(box, gbc); + objectCheckBoxes.add(box); + } + WebScrollPane sp = new WebScrollPane(panel); + return sp; + } + + /** + * Updates the panels. + * + * @param state + */ + public void update(Conf state) { + this.context = state.context; + this.removePane(1); + objectCheckBoxes.clear(); + this.addPane(1, "Objects", getObjectPanel()); + this.removePane(2); + attributeCheckBoxes.clear(); + this.addPane(2, "Attributes", getAttributePanel()); + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/LatticeView.java b/src/main/java/fcatools/conexpng/gui/lattice/LatticeView.java index ab0d125..8f86cb1 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/LatticeView.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/LatticeView.java @@ -27,258 +27,276 @@ import java.io.File; import java.util.HashSet; +/** + * This class implements the lattice tab. It contains the lattice graph view and + * the accordion menu. Furthermore, in this class the action buttons there + * functionallties are implemented and added to the vertical toolbar. + * + */ public class LatticeView extends View { - private static final long serialVersionUID = 1660117627650529212L; - - public static int radius = 7; - private LatticeGraphComputer alg; - private MainFrame mainFrame; - - private boolean updateLater; - - public LatticeView(final Conf state, MainFrame mainframe) { - super(state); - this.mainFrame = mainframe; - alg = new LatticeGraphComputer(); - if (state.lattice.isEmpty()) { - state.lattice = alg.computeLatticeGraph(new ListSet>>(), - new Rectangle()); - } - view = new LatticeGraphView(state); - settings = new LatticeSettings(state); - settings.setMinimumSize(new Dimension(170, 400)); - - JButton export = Util.createButton("Export", "export", "conexp/cameraFlash.gif"); - export.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - final WebFileChooser fc = new WebFileChooser(); - fc.setCurrentDirectory(state.filePath.substring(0, - state.filePath.lastIndexOf(System.getProperty("file.separator")))); - final WebDialog dialog = new WebDialog(mainFrame, "Save file as", true); - dialog.setContentPane(fc); - fc.setMultiSelectionEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - fc.setFileSelectionMode(WebFileChooser.FILES_ONLY); - fc.setDialogType(WebFileChooser.SAVE_DIALOG); - fc.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - String state = (String) e.getActionCommand(); - if ((state.equals(WebFileChooser.APPROVE_SELECTION) && fc.getSelectedFile() != null)) { - File file = fc.getSelectedFile(); - String path = file.getAbsolutePath(); - if (file.exists()) { - OverwritingFileDialog ofd = mainFrame.new OverwritingFileDialog(file); - if (ofd.isYes()) { - ((LatticeGraphView) view).exportLattice(path); - dialog.setVisible(false); - } - } else { - ((LatticeGraphView) view).exportLattice(path); - dialog.setVisible(false); - } - } else if (state.equals(WebFileChooser.CANCEL_SELECTION)) { - dialog.setVisible(false); - return; - } - } - }); - dialog.pack(); - Util.centerDialogInsideMainFrame(mainFrame, dialog); - dialog.setVisible(true); - - if (fc.getSelectedFile() == null) - return; - - } - }); - toolbar.add(export); - - JToggleButton move = Util.createToggleButton("Move subgraph", "move", "conexp/moveMode.gif"); - move.addActionListener(new ActionListener() { - private boolean last = false; - - @Override - public void actionPerformed(ActionEvent e) { - last = !last; - ((LatticeGraphView) view).setMove(last); - - } - }); - toolbar.add(move); - - JToggleButton showIdeal = Util.createToggleButton("Show Ideale", "ideal", "conexp/contextIcon.gif"); - showIdeal.addActionListener(new ActionListener() { - private boolean last = false; - - @Override - public void actionPerformed(ActionEvent arg0) { - last = !last; - ((LatticeGraphView) view).idealHighlighting(last); - ((LatticeGraphView) view).repaint(); - } - }); - toolbar.add(showIdeal); - - super.init(); - splitPane.setDividerLocation(state.guiConf.latticesettingssplitpos); - splitPane.addDividerListener(new ComponentListener() { - @Override - public void componentShown(ComponentEvent arg0) { - } - - @Override - public void componentResized(ComponentEvent arg0) { - } - - @Override - public void componentMoved(ComponentEvent arg0) { - state.guiConf.latticesettingssplitpos = splitPane.getDividerLocation(); - } - - @Override - public void componentHidden(ComponentEvent arg0) { - } - }); - } - - boolean loadedfile = false; - ConceptsLatticeWorker clw; - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt instanceof ContextChangeEvent) { - ContextChangeEvent cce = (ContextChangeEvent) evt; - switch (cce.getName()) { - case CANCELCALCULATIONS: { - if (clw != null) - clw.cancel(true); - break; - } - case CONTEXTCHANGED: { - state.concepts = new HashSet<>(); - state.lattice = new LatticeGraph(); - view.repaint(); - updateLater = true; - break; - } - case NEWCONTEXT: { - state.concepts = new HashSet<>(); - state.lattice = new LatticeGraph(); - view.repaint(); - updateLater = true; - break; - } - case LOADEDFILE: { - if (state.lattice.isEmpty()) - updateLater = true; - else - loadedfile = true; - break; - } - case TEMPORARYCONTEXTCHANGED: { - if (clw != null && !clw.isDone()) { - clw.cancel(true); - } - clw = new ConceptsLatticeWorker(); - clw.execute(); - break; - } - default: - break; - } - } - - if (isVisible() && loadedfile) { - loadedfile = false; - updateLater = false; - if (state.lattice.missingEdges()) { - if (state.concepts.isEmpty()) - new ConceptsWorker().execute(); - else { - state.lattice.addEdges(state.concepts); - ((LatticeGraphView) view).updateLatticeGraph(); - } - } - ((LatticeSettings) settings).update(state); - } - if (isVisible() && updateLater) { - updateLater = false; - if (clw != null && !clw.isDone()) { - clw.cancel(true); - } - clw = new ConceptsLatticeWorker(); - clw.execute(); - } - view.repaint(); - } - - private class ConceptsWorker extends SwingWorker { - ConceptCalculator cc; - - @Override - protected Void doInBackground() throws Exception { - state.startCalculation(StatusMessage.CALCULATINGCONCEPTS); - cc = state.context.new ConceptCalculator(); - Thread t = new Thread(cc); - t.setPriority(Thread.MIN_PRIORITY); - t.start(); - while (t.isAlive()) { - if (isCancelled()) { - t.interrupt(); - t.join(); - return null; - } - } - return null; - } - - protected void done() { - state.endCalculation(StatusMessage.CALCULATINGCONCEPTS); - if (!isCancelled()) { - state.concepts = cc.getConceptLattice(); - state.lattice.addEdges(state.concepts); - ((LatticeGraphView) view).updateLatticeGraph(); - } - super.done(); - }; - } - - private class ConceptsLatticeWorker extends SwingWorker { - - ConceptCalculator cc; - - @Override - protected Void doInBackground() throws Exception { - state.startCalculation(StatusMessage.CALCULATINGCONCEPTS); - cc = state.context.new ConceptCalculator(); - Thread t = new Thread(cc); - t.setPriority(Thread.MIN_PRIORITY); - t.start(); - while (t.isAlive()) { - if (isCancelled()) { - t.interrupt(); - t.join(); - return null; - } - } - return null; - } - - @Override - protected void done() { - state.endCalculation(StatusMessage.CALCULATINGCONCEPTS); - if (!isCancelled()) { - state.concepts = cc.getConceptLattice(); - state.startCalculation(StatusMessage.CALCULATINGLATTICE); - state.lattice = alg.computeLatticeGraph(state.concepts, view.getBounds()); - ((LatticeGraphView) view).updateLatticeGraph(); - ((LatticeSettings) settings).update(state); - state.endCalculation(StatusMessage.CALCULATINGLATTICE); - } - super.done(); - } - } + private static final long serialVersionUID = 1660117627650529212L; + + public static int radius = 7; + private LatticeGraphComputer alg; + private MainFrame mainFrame; + + private boolean updateLater; + + public LatticeView(final Conf state, MainFrame mainframe) { + super(state); + this.mainFrame = mainframe; + alg = new LatticeGraphComputer(); + if (state.lattice.isEmpty()) { + state.lattice = alg.computeLatticeGraph( + new ListSet>>(), + new Rectangle()); + } + view = new LatticeGraphView(state); + settings = new LatticeSettings(state); + settings.setMinimumSize(new Dimension(170, 400)); + + JButton export = Util.createButton("Export", "export", + "conexp/cameraFlash.gif"); + export.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + final WebFileChooser fc = new WebFileChooser(); + fc.setCurrentDirectory(state.filePath.substring(0, + state.filePath.lastIndexOf(System + .getProperty("file.separator")))); + final WebDialog dialog = new WebDialog(mainFrame, + "Save file as", true); + dialog.setContentPane(fc); + fc.setMultiSelectionEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + fc.setFileSelectionMode(WebFileChooser.FILES_ONLY); + fc.setDialogType(WebFileChooser.SAVE_DIALOG); + fc.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String state = (String) e.getActionCommand(); + if ((state.equals(WebFileChooser.APPROVE_SELECTION) && fc + .getSelectedFile() != null)) { + File file = fc.getSelectedFile(); + String path = file.getAbsolutePath(); + if (file.exists()) { + OverwritingFileDialog ofd = mainFrame.new OverwritingFileDialog( + file); + if (ofd.isYes()) { + ((LatticeGraphView) view) + .exportLattice(path); + dialog.setVisible(false); + } + } else { + ((LatticeGraphView) view).exportLattice(path); + dialog.setVisible(false); + } + } else if (state + .equals(WebFileChooser.CANCEL_SELECTION)) { + dialog.setVisible(false); + return; + } + } + }); + dialog.pack(); + Util.centerDialogInsideMainFrame(mainFrame, dialog); + dialog.setVisible(true); + + if (fc.getSelectedFile() == null) + return; + + } + }); + toolbar.add(export); + + JToggleButton move = Util.createToggleButton("Move subgraph", "move", + "conexp/moveMode.gif"); + move.addActionListener(new ActionListener() { + private boolean last = false; + + @Override + public void actionPerformed(ActionEvent e) { + last = !last; + ((LatticeGraphView) view).setMove(last); + + } + }); + toolbar.add(move); + + JToggleButton showIdeal = Util.createToggleButton("Show Ideale", + "ideal", "conexp/contextIcon.gif"); + showIdeal.addActionListener(new ActionListener() { + private boolean last = false; + + @Override + public void actionPerformed(ActionEvent arg0) { + last = !last; + ((LatticeGraphView) view).idealHighlighting(last); + ((LatticeGraphView) view).repaint(); + } + }); + toolbar.add(showIdeal); + + super.init(); + splitPane.setDividerLocation(state.guiConf.latticesettingssplitpos); + splitPane.addDividerListener(new ComponentListener() { + @Override + public void componentShown(ComponentEvent arg0) { + } + + @Override + public void componentResized(ComponentEvent arg0) { + } + + @Override + public void componentMoved(ComponentEvent arg0) { + state.guiConf.latticesettingssplitpos = splitPane + .getDividerLocation(); + } + + @Override + public void componentHidden(ComponentEvent arg0) { + } + }); + } + + boolean loadedfile = false; + ConceptsLatticeWorker clw; + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt instanceof ContextChangeEvent) { + ContextChangeEvent cce = (ContextChangeEvent) evt; + switch (cce.getName()) { + case CANCELCALCULATIONS: { + if (clw != null) + clw.cancel(true); + break; + } + case CONTEXTCHANGED: { + state.concepts = new HashSet<>(); + state.lattice = new LatticeGraph(); + view.repaint(); + updateLater = true; + break; + } + case NEWCONTEXT: { + state.concepts = new HashSet<>(); + state.lattice = new LatticeGraph(); + view.repaint(); + updateLater = true; + break; + } + case LOADEDFILE: { + if (state.lattice.isEmpty()) + updateLater = true; + else + loadedfile = true; + break; + } + case TEMPORARYCONTEXTCHANGED: { + if (clw != null && !clw.isDone()) { + clw.cancel(true); + } + clw = new ConceptsLatticeWorker(); + clw.execute(); + break; + } + default: + break; + } + } + + if (isVisible() && loadedfile) { + loadedfile = false; + updateLater = false; + if (state.lattice.missingEdges()) { + if (state.concepts.isEmpty()) + new ConceptsWorker().execute(); + else { + state.lattice.addEdges(state.concepts); + ((LatticeGraphView) view).updateLatticeGraph(); + } + } + ((LatticeSettings) settings).update(state); + } + if (isVisible() && updateLater) { + updateLater = false; + if (clw != null && !clw.isDone()) { + clw.cancel(true); + } + clw = new ConceptsLatticeWorker(); + clw.execute(); + } + view.repaint(); + } + + private class ConceptsWorker extends SwingWorker { + ConceptCalculator cc; + + @Override + protected Void doInBackground() throws Exception { + state.startCalculation(StatusMessage.CALCULATINGCONCEPTS); + cc = state.context.new ConceptCalculator(); + Thread t = new Thread(cc); + t.setPriority(Thread.MIN_PRIORITY); + t.start(); + while (t.isAlive()) { + if (isCancelled()) { + t.interrupt(); + t.join(); + return null; + } + } + return null; + } + + protected void done() { + state.endCalculation(StatusMessage.CALCULATINGCONCEPTS); + if (!isCancelled()) { + state.concepts = cc.getConceptLattice(); + state.lattice.addEdges(state.concepts); + ((LatticeGraphView) view).updateLatticeGraph(); + } + super.done(); + }; + } + + private class ConceptsLatticeWorker extends SwingWorker { + + ConceptCalculator cc; + + @Override + protected Void doInBackground() throws Exception { + state.startCalculation(StatusMessage.CALCULATINGCONCEPTS); + cc = state.context.new ConceptCalculator(); + Thread t = new Thread(cc); + t.setPriority(Thread.MIN_PRIORITY); + t.start(); + while (t.isAlive()) { + if (isCancelled()) { + t.interrupt(); + t.join(); + return null; + } + } + return null; + } + + @Override + protected void done() { + state.endCalculation(StatusMessage.CALCULATINGCONCEPTS); + if (!isCancelled()) { + state.concepts = cc.getConceptLattice(); + state.startCalculation(StatusMessage.CALCULATINGLATTICE); + state.lattice = alg.computeLatticeGraph(state.concepts, + view.getBounds()); + ((LatticeGraphView) view).updateLatticeGraph(); + ((LatticeSettings) settings).update(state); + state.endCalculation(StatusMessage.CALCULATINGLATTICE); + } + super.done(); + } + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/Node.java b/src/main/java/fcatools/conexpng/gui/lattice/Node.java index 15d4f62..68962c1 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/Node.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/Node.java @@ -10,286 +10,308 @@ import java.util.Set; import java.util.TreeSet; +/** + * This class implementes the nodes of the lattice graph. It is the model for + * the concepts. Each concept are represented as a node which knows his position + * , the objects and attributes as well as the labels which contained visible + * objects resp. attributes. + * + */ public class Node extends JPanel implements LatticeGraphElement { - /** + /** * */ - private static final long serialVersionUID = 4253192979583459657L; - private Set objects; - private Set attributes; - private int x; - private int y; - private List below; - private ListSet ideal; - private ListSet filter; - private boolean isIdealVisibile; - private Label visibleObjects; - private Label visibleAttributes; - private boolean moveSubgraph; - private int level; - private boolean hitBorder; - - /** + private static final long serialVersionUID = 4253192979583459657L; + private Set objects; + private Set attributes; + private int x; + private int y; + // list of nodes which are below neighbors + private List below; + private ListSet ideal; + private ListSet filter; + private boolean isIdealVisibile; + private Label visibleObjects; + private Label visibleAttributes; + // true, if this node and his subgraph are moveable. + private boolean moveSubgraph; + // level of the node in the graph + private int level; + // true if the node hit the viewport's borders + private boolean hitBorder; + + /** + * + * @param extent + * @param intent + * @param x + * @param y + */ + public Node(Set extent, Set intent, int x, int y) { + this.objects = extent; + this.attributes = intent; + this.x = x; + this.y = y; + this.setBounds(x, y, 15, 15); + this.below = new ArrayList<>(); + + } + + /** * - * @param extent - * @param intent - * @param x - * @param y */ - public Node(Set extent, Set intent, int x, int y) { - this.objects = extent; - this.attributes = intent; - this.x = x; - this.y = y; - this.setBounds(x, y, 15, 15); - this.below = new ArrayList<>(); - - } - - /** - * - */ - public Node() { - this.objects = new TreeSet<>(); - this.attributes = new TreeSet<>(); - this.visibleObjects = new Label(new TreeSet(), this, true); - this.visibleAttributes = new Label(new TreeSet(), this, false); - this.ideal = new ListSet<>(); - this.x = 0; - this.y = 0; - this.setBounds(x, y, 15, 15); - this.setBackground(Color.white); - this.below = new ArrayList<>(); - this.filter = new ListSet<>(); - } - - @Override - public void paint(Graphics g) { - } - - /** - * - * @return - */ - public int getX() { - return x; - } - - /** - * - * @param x - */ - public void setX(int x) { - this.x = x; - this.setBounds(x, y, 15, 15); - } - - /** - * - * @return - */ - public int getY() { - return y; - } - - /** - * - * @param y - */ - public void setY(int y) { - this.y = y; - this.setBounds(x, y, 15, 15); - } - - /** - * - * @param extent - */ - public void addObject(String extent) { - objects.add(extent); - } - - /** - * - * @param set - */ - public void addAttribute(String set) { - attributes.add(set); - } - - public void addBelowNode(Node n) { - below.add(n); - } - - public List getBelow() { - return below; - } - - public void update(int x, int y, boolean first) { - int updateX; - int updateY; - if (this.x + x >= 2) { - updateX = this.x + x; - } else { - hitBorder = true; - updateX = 1; - } - if (this.y + y >= 2) - updateY = this.y + y; - else { - updateY = 1; - hitBorder = true; - } - - for (Node n : ideal) { - if (!n.isUpdateXPosible(x) || !n.isUpdateYPosible(y)) { - hitBorder = true; - } - } - - if (!hitBorder) { - if (moveSubgraph && first) { - for (Node n : ideal) { - n.update(x, y, false); - } - } - - this.setBounds(updateX, updateY, 15, 15); - this.x = updateX; - this.y = updateY; - visibleAttributes.update(x, y, first); - visibleObjects.update(x, y, first); - - if (getParent() != null) { - getParent().repaint(); - } - } - - hitBorder = false; - } - - public boolean isUpdateXPosible(int x) { - if(this.x > getParent().getWidth()){ - return true; - } - if (this.x + x >= 2 && this.x + x < getParent().getWidth()) { - return true; - } - return false; - } - - public boolean isUpdateYPosible(int y) { - if(this.y > getParent().getHeight()){ - return true; - } - if (this.y + y >= 2 && this.y + y < getParent().getHeight()) { - for(Node n : this.ideal){ - if(this.y + y > n.getY() - 3){ - return false; - } - } - for(Node n : this.filter){ - if(this.y + y < n.getY() + 3){ - return false; - } - } - return true; - } - return false; - } - - public ListSet getIdeal() { - return ideal; - } - - public void addObjects(Set extent) { - objects.addAll(extent); - - } - - public void addAttributs(Set intent) { - attributes.addAll(intent); - - } - - public Set getObjects() { - return objects; - } - - public Set getAttributes() { - return attributes; - } - - public void setLevel(int level) { - this.level = level; - - } - - public int getLevel() { - return level; - } - - public void setVisibleObject(String object) { - visibleObjects.getSet().add(object); - } - - public void setVisibleObjects(Set objects) { - visibleObjects.getSet().clear(); - visibleObjects.getSet().addAll(objects); - } - - public Set getVisibleObjects() { - return this.visibleObjects.getSet(); - } - - public void setVisibleAttribute(String attribute) { - this.visibleAttributes.getSet().add(attribute); - } - - public void setVisibleAttributes(Set attributes) { - visibleAttributes.getSet().clear(); - visibleAttributes.getSet().addAll(attributes); - } - - public Set getVisibleAttributes() { - return this.visibleAttributes.getSet(); - - } - - public Label getObjectsLabel() { - return this.visibleObjects; - } - - public Label getAttributesLabel() { - return this.visibleAttributes; - } - - public void moveSubgraph(boolean b) { - this.moveSubgraph = b; - } - - public void toggleIdealVisibility() { - ((LatticeGraphView) getParent()).resetHighlighting(); - this.isIdealVisibile = !this.isIdealVisibile; - for (Node n : ideal) { - n.setPartOfAnIdeal(isIdealVisibile); - } - if (getParent() != null) { - getParent().repaint(); - } - } - - public boolean isPartOfAnIdeal() { - return this.isIdealVisibile; - } - - public void setPartOfAnIdeal(boolean b) { - this.isIdealVisibile = b; - } - - public ListSet getFilter(){ - return this.filter; - } + public Node() { + this.objects = new TreeSet<>(); + this.attributes = new TreeSet<>(); + this.visibleObjects = new Label(new TreeSet(), this, true); + this.visibleAttributes = new Label(new TreeSet(), this, false); + this.ideal = new ListSet<>(); + this.x = 0; + this.y = 0; + this.setBounds(x, y, 15, 15); + this.setBackground(Color.white); + this.below = new ArrayList<>(); + this.filter = new ListSet<>(); + } + + @Override + public void paint(Graphics g) { + } + + /** + * + * @return + */ + public int getX() { + return x; + } + + /** + * + * @param x + */ + public void setX(int x) { + this.x = x; + this.setBounds(x, y, 15, 15); + } + + /** + * + * @return + */ + public int getY() { + return y; + } + + /** + * + * @param y + */ + public void setY(int y) { + this.y = y; + this.setBounds(x, y, 15, 15); + } + + /** + * + * @param extent + */ + public void addObject(String extent) { + objects.add(extent); + } + + /** + * + * @param set + */ + public void addAttribute(String set) { + attributes.add(set); + } + + public void addBelowNode(Node n) { + below.add(n); + } + + public List getBelow() { + return below; + } + + /** + * Updated the node position + * + * @param x + * , value of which x has to be translated + * @param y + * , value of which y has to be translated + * @param first + * , true, if you what this node is the almost top node of the + * subgraph you want to move. + */ + public void update(int x, int y, boolean first) { + int updateX; + int updateY; + if (this.x + x >= 2) { + updateX = this.x + x; + } else { + hitBorder = true; + updateX = 1; + } + if (this.y + y >= 2) + updateY = this.y + y; + else { + updateY = 1; + hitBorder = true; + } + + for (Node n : ideal) { + if (!n.isUpdateXPosible(x) || !n.isUpdateYPosible(y)) { + hitBorder = true; + } + } + + if (!hitBorder) { + if (moveSubgraph && first) { + for (Node n : ideal) { + n.update(x, y, false); + } + } + + this.setBounds(updateX, updateY, 15, 15); + this.x = updateX; + this.y = updateY; + visibleAttributes.update(x, y, first); + visibleObjects.update(x, y, first); + + if (getParent() != null) { + getParent().repaint(); + } + } + + hitBorder = false; + } + + public boolean isUpdateXPosible(int x) { + if (this.x > getParent().getWidth()) { + return true; + } + if (this.x + x >= 2 && this.x + x < getParent().getWidth()) { + return true; + } + return false; + } + + public boolean isUpdateYPosible(int y) { + if (this.y > getParent().getHeight()) { + return true; + } + if (this.y + y >= 2 && this.y + y < getParent().getHeight()) { + for (Node n : this.ideal) { + if (this.y + y > n.getY() - 3) { + return false; + } + } + for (Node n : this.filter) { + if (this.y + y < n.getY() + 3) { + return false; + } + } + return true; + } + return false; + } + + public ListSet getIdeal() { + return ideal; + } + + public void addObjects(Set extent) { + objects.addAll(extent); + + } + + public void addAttributs(Set intent) { + attributes.addAll(intent); + + } + + public Set getObjects() { + return objects; + } + + public Set getAttributes() { + return attributes; + } + + public void setLevel(int level) { + this.level = level; + + } + + public int getLevel() { + return level; + } + + public void setVisibleObject(String object) { + visibleObjects.getSet().add(object); + } + + public void setVisibleObjects(Set objects) { + visibleObjects.getSet().clear(); + visibleObjects.getSet().addAll(objects); + } + + public Set getVisibleObjects() { + return this.visibleObjects.getSet(); + } + + public void setVisibleAttribute(String attribute) { + this.visibleAttributes.getSet().add(attribute); + } + + public void setVisibleAttributes(Set attributes) { + visibleAttributes.getSet().clear(); + visibleAttributes.getSet().addAll(attributes); + } + + public Set getVisibleAttributes() { + return this.visibleAttributes.getSet(); + + } + + public Label getObjectsLabel() { + return this.visibleObjects; + } + + public Label getAttributesLabel() { + return this.visibleAttributes; + } + + public void moveSubgraph(boolean b) { + this.moveSubgraph = b; + } + + public void toggleIdealVisibility() { + ((LatticeGraphView) getParent()).resetHighlighting(); + this.isIdealVisibile = !this.isIdealVisibile; + for (Node n : ideal) { + n.setPartOfAnIdeal(isIdealVisibile); + } + if (getParent() != null) { + getParent().repaint(); + } + } + + public boolean isPartOfAnIdeal() { + return this.isIdealVisibile; + } + + public void setPartOfAnIdeal(boolean b) { + this.isIdealVisibile = b; + } + + public ListSet getFilter() { + return this.filter; + } } diff --git a/src/main/java/fcatools/conexpng/gui/lattice/NodeMouseClickListener.java b/src/main/java/fcatools/conexpng/gui/lattice/NodeMouseClickListener.java index 1c962cd..4f6dcd7 100644 --- a/src/main/java/fcatools/conexpng/gui/lattice/NodeMouseClickListener.java +++ b/src/main/java/fcatools/conexpng/gui/lattice/NodeMouseClickListener.java @@ -8,9 +8,10 @@ public class NodeMouseClickListener implements MouseListener { private Node node; private boolean clicked = false; - public NodeMouseClickListener(Node n){ + public NodeMouseClickListener(Node n) { this.node = n; } + @Override public void mouseClicked(MouseEvent arg0) { } @@ -29,10 +30,9 @@ public void mouseExited(MouseEvent arg0) { @Override public void mousePressed(MouseEvent arg0) { - if(!node.isPartOfAnIdeal()){ + if (!node.isPartOfAnIdeal()) { node.toggleIdealVisibility(); - } - else if(!clicked){ + } else if (!clicked) { node.toggleIdealVisibility(); } @@ -41,7 +41,6 @@ else if(!clicked){ @Override public void mouseReleased(MouseEvent arg0) { - } } diff --git a/src/main/java/fcatools/conexpng/model/ILatticeGraphAlgorithm.java b/src/main/java/fcatools/conexpng/model/ILatticeGraphAlgorithm.java index 570dccf..5b6b19d 100644 --- a/src/main/java/fcatools/conexpng/model/ILatticeGraphAlgorithm.java +++ b/src/main/java/fcatools/conexpng/model/ILatticeGraphAlgorithm.java @@ -2,8 +2,27 @@ import fcatools.conexpng.gui.lattice.LatticeGraph; +/** + * For adding an new lattice drawing algorithm you have to implement this + * interface. + * + * + */ public interface ILatticeGraphAlgorithm { - - public abstract LatticeGraph computeLatticeGraphPositions(LatticeGraph graph, int screenWidth, int screenHeight); + + /** + * This method will compute the correct position of the graph's nodes. + * + * @param graph + * contains already initialized nodes with correct y-values and + * random x-values + * @param screenWidth + * width of the viewport + * @param screenHeight + * height of the viewport + * @return + */ + public abstract LatticeGraph computeLatticeGraphPositions( + LatticeGraph graph, int screenWidth, int screenHeight); } diff --git a/src/main/java/fcatools/conexpng/model/LatticeConcept.java b/src/main/java/fcatools/conexpng/model/LatticeConcept.java index a025acc..d03b22c 100644 --- a/src/main/java/fcatools/conexpng/model/LatticeConcept.java +++ b/src/main/java/fcatools/conexpng/model/LatticeConcept.java @@ -1,22 +1,26 @@ package fcatools.conexpng.model; import java.util.Set; -import java.util.TreeSet; import de.tudresden.inf.tcs.fcaapi.Concept; import de.tudresden.inf.tcs.fcalib.FullObject; import de.tudresden.inf.tcs.fcalib.utils.ListSet; -public class LatticeConcept implements Concept> { +/** + * This class implemented the Concept interface of the fcalib. + * + */ +public class LatticeConcept implements + Concept> { private ListSet> extent; private ListSet intent; - - public LatticeConcept(){ + + public LatticeConcept() { extent = new ListSet<>(); intent = new ListSet<>(); } - + @Override public Set> getExtent() { return this.extent; @@ -28,7 +32,7 @@ public Set getIntent() { } @Override - public String toString(){ - return "Objects: "+extent+"\nAttributes: "+intent+"\n"; + public String toString() { + return "Objects: " + extent + "\nAttributes: " + intent + "\n"; } } diff --git a/src/main/java/fcatools/conexpng/model/LatticeGraphComputer.java b/src/main/java/fcatools/conexpng/model/LatticeGraphComputer.java index c718f9c..f46486a 100644 --- a/src/main/java/fcatools/conexpng/model/LatticeGraphComputer.java +++ b/src/main/java/fcatools/conexpng/model/LatticeGraphComputer.java @@ -18,211 +18,222 @@ import fcatools.conexpng.gui.lattice.Node; /** - * - * @author Jan - * + * This class representing the conncetion between the view and the lattice + * drawing algorithms. All this algorithms have to be implemented the + * ILatticeGraphAlgorithm and after that, they have to be added to this class. + * */ public class LatticeGraphComputer { - private LatticeGraph graph; - private Set>> lattConcepts; - private HashMap algorithms; - private ILatticeGraphAlgorithm usedAlgorithm; - private int screenWidth; - private int screenHeight; - - /** - * - * @param set - * @param bounds - * @return - */ - public LatticeGraphComputer(){ - algorithms = new HashMap<>(); - algorithms.put("Test", new TestLatticeAlgorithm()); - usedAlgorithm = algorithms.get("Test"); - } - - public void chooseAlgorithm(String name){ - if(!algorithms.containsKey(name)){ - System.err.println("The chosen algorithm don't exists!"); - }else{ - usedAlgorithm = algorithms.get(name); - } - } - - - public LatticeGraph computeLatticeGraph( - Set>> concepts, Rectangle bounds) { - this.lattConcepts = concepts; - this.screenWidth = bounds.width; - this.screenHeight = bounds.height; - initGraph(); - graph.computeAllIdeals(); - computeVisibleObjectsAndAttributes(); - this.graph = usedAlgorithm.computeLatticeGraphPositions(graph, screenWidth, screenHeight); - return graph; - } - - public void initGraph() { - graph = new LatticeGraph(); - - Iterator>> iter = lattConcepts - .iterator(); - while (iter.hasNext()) { - Node n = new Node(); - Concept> c = (Concept>) iter - .next(); - n.addAttributs(c.getIntent()); - - ListSet extent = new ListSet<>(); - for (FullObject fo : c.getExtent()) { - extent.add(fo.getIdentifier()); - } - n.getObjects().addAll(extent); - graph.getNodes().add(n); - } - - graph.removeAllDuplicates(); - - List topNode = new ArrayList<>(); - for (Node u : graph.getNodes()) { - topNode.add(u); - Set uEx = u.getObjects(); - for (Node v : graph.getNodes()) { - Set vEx = v.getObjects(); - if (isLowerNeighbour(uEx, vEx)) { - v.addBelowNode(u); - graph.getEdges().add(new Edge(u, v)); - topNode.remove(u); - } - } - } - Queue q = new LinkedList<>(); - q.addAll(topNode); - while (!q.isEmpty()) { - Node n = q.remove(); - for (Node v : n.getBelow()) { - if (v.getLevel() == 0 || v.getLevel() == n.getLevel()) { - v.setLevel(n.getLevel() + 1); - v.update((int) (Math.random() * 500), 100 * v.getLevel(), - true); - v.getAttributesLabel() - .setXYWRTLabelType(v.getX(), v.getY()); - v.getObjectsLabel().setXYWRTLabelType(v.getX(), v.getY()); - q.add(v); - } - } - } - - } - - - /** - * - * @param subEx - * @param superEx - * @return - */ - public boolean isSubconcept(Set subEx, Set superEx) { - if (subEx == superEx) { - return false; - } - if (subEx.size() > superEx.size()) { - return false; - } - for (String s : subEx) { - if (!superEx.contains(s)) { - return false; - } - } - return true; - } - - /** - * - * @param subEx - * @param superEx - * @return - */ - public boolean isLowerNeighbour(Set subEx, Set superEx) { - if (subEx == superEx) { - return false; - } - if (!isSubconcept(subEx, superEx)) { - return false; - } - for (Node n : graph.getNodes()) { - Set set = n.getObjects(); - if (!subEx.equals(set)) { - if (!superEx.equals(set)) { - if (isSubconcept(subEx, set)) { - if (isSubconcept(set, superEx)) { - return false; - } - } - } - } - } - return true; - } - - - - public void computeVisibleObjectsAndAttributes() { - // calc which obj/attr has to be shown - Set usedObj = new TreeSet<>(); - Set usedAttr = new TreeSet<>(); - Node maxNode = new Node(); - Node minNode; - if (graph.getNodes().size() == 0) { - minNode = new Node(); - } else { - minNode = graph.getNode(0); - } - - for (Node u : graph.getNodes()) { - if (u.getIdeal().size() >= maxNode.getIdeal().size()) { - maxNode = u; - } else if (u.getIdeal().size() <= minNode.getIdeal().size()) { - minNode = u; - } - } - - Queue pq = new LinkedList<>(); - pq.add(maxNode); - while (!pq.isEmpty()) { - Node n = pq.remove(); - for (String a : n.getAttributes()) { - if (!usedAttr.contains(a)) { - n.setVisibleAttribute(a); - usedAttr.add(a); - } - } - for (Node u : n.getBelow()) { - pq.add(u); - } - } - - pq.add(minNode); - while (!pq.isEmpty()) { - Node n = pq.remove(); - for (String o : n.getObjects()) { - if (!usedObj.contains(o)) { - n.setVisibleObject(o); - usedObj.add(o); - } - } - for (Node u : graph.getNodes()) { - if (u.getBelow().contains(n)) { - pq.add(u); - } - } - } - } - - public void addAlgorithm(String name, ILatticeGraphAlgorithm alg){ - this.algorithms.put(name, alg); - } + private LatticeGraph graph; + private Set>> lattConcepts; + private HashMap algorithms; + private ILatticeGraphAlgorithm usedAlgorithm; + private int screenWidth; + private int screenHeight; + + /** + * + * @param set + * @param bounds + * @return + */ + public LatticeGraphComputer() { + algorithms = new HashMap<>(); + algorithms.put("Test", new TestLatticeAlgorithm()); + usedAlgorithm = algorithms.get("Test"); + } + + public void chooseAlgorithm(String name) { + if (!algorithms.containsKey(name)) { + System.err.println("The chosen algorithm don't exists!"); + } else { + usedAlgorithm = algorithms.get(name); + } + } + + /** + * this method computes the lattice graph. + * + * @param concepts + * set of concepts of the lattice. + * @param bounds + * of the viewport + * @return the lattice graph which has to be drawn + */ + public LatticeGraph computeLatticeGraph( + Set>> concepts, + Rectangle bounds) { + this.lattConcepts = concepts; + this.screenWidth = bounds.width; + this.screenHeight = bounds.height; + initGraph(); + graph.computeAllIdeals(); + computeVisibleObjectsAndAttributes(); + this.graph = usedAlgorithm.computeLatticeGraphPositions(graph, + screenWidth, screenHeight); + return graph; + } + + /** + * Initialize the graph. + */ + public void initGraph() { + graph = new LatticeGraph(); + + Iterator>> iter = lattConcepts + .iterator(); + while (iter.hasNext()) { + Node n = new Node(); + Concept> c = (Concept>) iter + .next(); + n.addAttributs(c.getIntent()); + + ListSet extent = new ListSet<>(); + for (FullObject fo : c.getExtent()) { + extent.add(fo.getIdentifier()); + } + n.getObjects().addAll(extent); + graph.getNodes().add(n); + } + + graph.removeAllDuplicates(); + + List topNode = new ArrayList<>(); + for (Node u : graph.getNodes()) { + topNode.add(u); + Set uEx = u.getObjects(); + for (Node v : graph.getNodes()) { + Set vEx = v.getObjects(); + if (isLowerNeighbour(uEx, vEx)) { + v.addBelowNode(u); + graph.getEdges().add(new Edge(u, v)); + topNode.remove(u); + } + } + } + Queue q = new LinkedList<>(); + q.addAll(topNode); + while (!q.isEmpty()) { + Node n = q.remove(); + for (Node v : n.getBelow()) { + if (v.getLevel() == 0 || v.getLevel() == n.getLevel()) { + v.setLevel(n.getLevel() + 1); + v.update((int) (Math.random() * 500), 100 * v.getLevel(), + true); + v.getAttributesLabel() + .setXYWRTLabelType(v.getX(), v.getY()); + v.getObjectsLabel().setXYWRTLabelType(v.getX(), v.getY()); + q.add(v); + } + } + } + + } + + /** + * + * @param subEx + * @param superEx + * @return + */ + public boolean isSubconcept(Set subEx, Set superEx) { + if (subEx == superEx) { + return false; + } + if (subEx.size() > superEx.size()) { + return false; + } + for (String s : subEx) { + if (!superEx.contains(s)) { + return false; + } + } + return true; + } + + /** + * + * @param subEx + * @param superEx + * @return + */ + public boolean isLowerNeighbour(Set subEx, Set superEx) { + if (subEx == superEx) { + return false; + } + if (!isSubconcept(subEx, superEx)) { + return false; + } + for (Node n : graph.getNodes()) { + Set set = n.getObjects(); + if (!subEx.equals(set)) { + if (!superEx.equals(set)) { + if (isSubconcept(subEx, set)) { + if (isSubconcept(set, superEx)) { + return false; + } + } + } + } + } + return true; + } + + public void computeVisibleObjectsAndAttributes() { + // calc which obj/attr has to be shown + Set usedObj = new TreeSet<>(); + Set usedAttr = new TreeSet<>(); + Node maxNode = new Node(); + Node minNode; + if (graph.getNodes().size() == 0) { + minNode = new Node(); + } else { + minNode = graph.getNode(0); + } + + for (Node u : graph.getNodes()) { + if (u.getIdeal().size() >= maxNode.getIdeal().size()) { + maxNode = u; + } else if (u.getIdeal().size() <= minNode.getIdeal().size()) { + minNode = u; + } + } + + Queue pq = new LinkedList<>(); + pq.add(maxNode); + while (!pq.isEmpty()) { + Node n = pq.remove(); + for (String a : n.getAttributes()) { + if (!usedAttr.contains(a)) { + n.setVisibleAttribute(a); + usedAttr.add(a); + } + } + for (Node u : n.getBelow()) { + pq.add(u); + } + } + + pq.add(minNode); + while (!pq.isEmpty()) { + Node n = pq.remove(); + for (String o : n.getObjects()) { + if (!usedObj.contains(o)) { + n.setVisibleObject(o); + usedObj.add(o); + } + } + for (Node u : graph.getNodes()) { + if (u.getBelow().contains(n)) { + pq.add(u); + } + } + } + } + + public void addAlgorithm(String name, ILatticeGraphAlgorithm alg) { + this.algorithms.put(name, alg); + } }