|
@@ -3,13 +3,17 @@ package view;
|
|
|
import java.awt.BasicStroke;
|
|
|
import java.awt.Color;
|
|
|
import java.awt.Component;
|
|
|
-import java.awt.Dimension;
|
|
|
import java.awt.Graphics;
|
|
|
import java.awt.Graphics2D;
|
|
|
-import java.awt.Point;
|
|
|
+import java.awt.event.ComponentEvent;
|
|
|
+import java.awt.event.ComponentListener;
|
|
|
+import java.awt.event.MouseEvent;
|
|
|
+import java.awt.event.MouseListener;
|
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
+import javax.swing.JFrame;
|
|
|
import javax.swing.JPanel;
|
|
|
+import javax.swing.SwingUtilities;
|
|
|
import javax.swing.border.Border;
|
|
|
|
|
|
import bk.LayoutType;
|
|
@@ -20,119 +24,142 @@ import graph.LayeredGraphNode;
|
|
|
* @author kolja
|
|
|
*
|
|
|
*/
|
|
|
-public class NodeView extends JPanel {
|
|
|
+public class NodeView extends JPanel implements AnnimatedView, MouseListener {
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
private LayeredGraphNode model;
|
|
|
private LayoutType layout;
|
|
|
+ private JFrame mainView;
|
|
|
|
|
|
- public NodeView( LayeredGraphNode model, LayoutType lt ) {
|
|
|
+ public NodeView( LayeredGraphNode model, LayoutType lt, JFrame mv ) {
|
|
|
+ mainView = mv;
|
|
|
this.model = model;
|
|
|
layout = lt;
|
|
|
setSize( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
|
|
|
+ addMouseListener( this );
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public Point getLocation()
|
|
|
- {
|
|
|
- return new Point( (int)model.getX( layout ), (int)model.getY( layout ) );
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Dimension getPreferredSize()
|
|
|
+ private synchronized void update()
|
|
|
{
|
|
|
- return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
|
|
|
+ SwingUtilities.invokeLater(new Runnable() {
|
|
|
+ public void run() {
|
|
|
+ for( ComponentListener l : mainView.getComponentListeners() )
|
|
|
+ {
|
|
|
+ l.componentResized( new ComponentEvent(mainView, 0) );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public int getScaledX( int x )
|
|
|
{
|
|
|
- double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
x *= scale;
|
|
|
- if( scale == (double)super.getHeight() / (int)model.getHeight( layout ) )
|
|
|
- x += (super.getWidth() - (model.getWidth( layout ) * scale )) / 2;
|
|
|
return x;
|
|
|
}
|
|
|
|
|
|
public int getScaledY( int y )
|
|
|
{
|
|
|
- double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
y *= scale;
|
|
|
- if( scale == (double)super.getWidth() / (int)model.getWidth( layout ) )
|
|
|
- y += (super.getHeight() - (model.getHeight( layout ) * scale )) / 2;
|
|
|
return y;
|
|
|
}
|
|
|
|
|
|
- public String updateTooltipText( int mx, int my ) {
|
|
|
- int x = 0;
|
|
|
- int y = 0;
|
|
|
- double scaleW = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
|
|
|
- double scaleH = scaleW;
|
|
|
- int width = (int)(super.getWidth() / scaleW);
|
|
|
- if( scaleW == (double)super.getWidth() / (int)model.getWidth( layout ) )
|
|
|
- y += (super.getHeight() - (model.getHeight( layout ) * scaleH )) / scaleH / 2;
|
|
|
- if( scaleH == (double)super.getHeight() / (int)model.getHeight( layout ) )
|
|
|
- x += (super.getWidth() - (model.getWidth( layout ) * scaleW )) / scaleW / 2;
|
|
|
- if( model.isDummyNode() )
|
|
|
+ public void updateTooltipText() {
|
|
|
+ if( layout != LayoutType.COMBINED )
|
|
|
{
|
|
|
- scaleW *= 1 / 4.0;
|
|
|
- x += width / (3/4.0);
|
|
|
+ setToolTipText( "<html>Name: " + model.toString() +
|
|
|
+ "<br>Root: " + model.getRoot( layout ).toString() +
|
|
|
+ "<br>Shink: " + model.getSink( layout ).toString() +
|
|
|
+ "<br>Shift: " + model.getShift( layout ) + "</html>" );
|
|
|
}
|
|
|
- double minX = Double.POSITIVE_INFINITY;
|
|
|
+ else
|
|
|
+ setToolTipText( "Name: " + model.toString() );
|
|
|
for( Component c : getComponents() )
|
|
|
{
|
|
|
- minX = Math.min( c.getLocation().x, minX);
|
|
|
+ if( !(c instanceof NodeView) )
|
|
|
+ continue;
|
|
|
+ ((NodeView)c).updateTooltipText();
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getXOffset()
|
|
|
+ {
|
|
|
+ int x = 0;
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
+ x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
|
|
|
+ return x;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getYOffset()
|
|
|
+ {
|
|
|
+ int y = 0;
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
+ y += (getHeight()-50) / 2 - (getVirtualHeight() * scale ) / 2 + 25;
|
|
|
+ return y;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void doLayout() {
|
|
|
+ double minX = Double.POSITIVE_INFINITY;
|
|
|
for( Component c : getComponents() )
|
|
|
{
|
|
|
- int nx = (int)(mx / scaleW) - (c.getLocation().x + 25 - (int)minX + x);
|
|
|
- int ny = (int)(my / scaleH) - (c.getLocation().y + 25 + y);
|
|
|
- int width1 = Math.min( (int)model.getWidth( layout ) - 25, c.getPreferredSize().width + 25 );
|
|
|
- int height1 = Math.min( (int)model.getHeight( layout ) - 25, c.getPreferredSize().height + 25 );
|
|
|
- if( nx < width1 && ny < height1 && nx > 0 && ny > 0 && c instanceof NodeView )
|
|
|
- return ((NodeView)c).updateTooltipText( nx, ny );
|
|
|
+ if( !(c instanceof AnnimatedView) )
|
|
|
+ continue;
|
|
|
+ minX = Math.min( ((AnnimatedView)c).getVirtualX(), minX);
|
|
|
}
|
|
|
- if( layout != LayoutType.COMBINED )
|
|
|
+ int x = 0;
|
|
|
+ int y = 0;
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
+ y += (getHeight()-50) / 2 - (getVirtualHeight() * scale ) / 2 + 25;
|
|
|
+ x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
|
|
|
+ for( Component c : getComponents() )
|
|
|
{
|
|
|
- return "<html>Name: " + model.toString() +
|
|
|
- "<br>Root: " + model.getRoot( layout ).toString() +
|
|
|
- "<br>Shink: " + model.getSink( layout ).toString() +
|
|
|
- "<br>Shift: " + model.getShift( layout ) + "</html>";
|
|
|
+ if( !(c instanceof AnnimatedView) )
|
|
|
+ continue;
|
|
|
+ AnnimatedView view = (AnnimatedView)c;
|
|
|
+ c.setLocation( getScaledX( view.getVirtualX() - (int)minX ) + x, getScaledY( view.getVirtualY() ) + y);
|
|
|
+ c.setSize( getScaledX( view.getVirtualWidth() ), getScaledY( view.getVirtualHeight() ) );
|
|
|
+ c.doLayout();
|
|
|
}
|
|
|
- return "Name: " + model.toString();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void paint( Graphics g )
|
|
|
{
|
|
|
- if( layout == LayoutType.COMBINED && model.getColor( layout ) == null )
|
|
|
+ if( layout == LayoutType.COMBINED && model.getColor( null ) == null )
|
|
|
return;
|
|
|
- double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
|
|
|
- ((Graphics2D)g).scale( scale, scale );
|
|
|
- int x = 0;
|
|
|
- int y = 0;
|
|
|
- int width = (int)(super.getWidth() / scale);
|
|
|
- int height = (int)(super.getHeight() / scale);
|
|
|
- if( scale == (double)super.getWidth() / (int)model.getWidth( layout ) )
|
|
|
- y += (super.getHeight() - (model.getHeight( layout ) * scale )) / scale / 2;
|
|
|
- if( scale == (double)super.getHeight() / (int)model.getHeight( layout ) )
|
|
|
- x += (super.getWidth() - (model.getWidth( layout ) * scale )) / scale / 2;
|
|
|
- if( model.isDummyNode() )
|
|
|
- {
|
|
|
- ((Graphics2D)g).scale( 1 / 4.0, 1 );
|
|
|
- x += width / (3/4.0);
|
|
|
- }
|
|
|
- paintComponent( g.create( x, y, width, height ) );
|
|
|
+ updateTooltipText();
|
|
|
+ paintComponent( g );
|
|
|
double minX = Double.POSITIVE_INFINITY;
|
|
|
for( Component c : getComponents() )
|
|
|
{
|
|
|
- minX = Math.min( c.getLocation().x, minX);
|
|
|
+ if( !(c instanceof AnnimatedView) )
|
|
|
+ continue;
|
|
|
+ minX = Math.min( ((AnnimatedView)c).getVirtualX(), minX);
|
|
|
}
|
|
|
+ int x = 0;
|
|
|
+ double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
|
|
|
+ x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
|
|
|
for( Component c : getComponents() )
|
|
|
{
|
|
|
- c.paint( g.create(
|
|
|
- c.getLocation().x + 25 - (int)minX + x,
|
|
|
- c.getLocation().y + 25 + y,
|
|
|
- Math.min( (int)model.getWidth( layout ) - 25, c.getPreferredSize().width + Math.abs(c.getLocation().x) + 25 ),
|
|
|
- Math.min( (int)model.getHeight( layout ) - 25, c.getPreferredSize().height + Math.abs(c.getLocation().y) + 25 ) ) );
|
|
|
+ if( c instanceof NodeView )
|
|
|
+ {
|
|
|
+ if( layout != LayoutType.COMBINED )
|
|
|
+ {
|
|
|
+ NodeView v = (NodeView)c;
|
|
|
+ v.renderClass( g.create( getScaledX( v.getPlainVirtualX() - (int)minX - 12 ) + x, c.getY() - getScaledY(12), getScaledX( v.getPlainVirtualWidth() + 22 ), c.getHeight() + getScaledY(22) ) );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c.paint( g.create( c.getX(), c.getY(), c.getWidth(), c.getHeight() ) );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void renderClass( Graphics g ) {
|
|
|
+ g.setColor( model.getRoot( layout ).getClassColor( layout ) );
|
|
|
+ if( model.getContainedNodes().size() == 0 && model.getRoot( layout ).getClassColor( layout ) != Color.LIGHT_GRAY )
|
|
|
+ {
|
|
|
+ g.setColor( new Color( (g.getColor().getRed() + 500) / 3, (g.getColor().getGreen() + 500) / 3, (g.getColor().getBlue() + 500) / 3 ) );
|
|
|
+ g.fillRect( 0, 0, g.getClipBounds().width, g.getClipBounds().height );
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -145,9 +172,9 @@ public class NodeView extends JPanel {
|
|
|
if( model.getContainedNodes().size() == 0 )
|
|
|
{
|
|
|
if( model.getRoot( layout ) == model )
|
|
|
- g2.fillOval( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
|
|
|
+ g2.fillOval( 0, 0, getWidth(), getHeight() );
|
|
|
else
|
|
|
- g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
|
|
|
+ g2.fillRect( 0, 0, getWidth(), getHeight() );
|
|
|
}
|
|
|
boolean selected = model.isSelected( layout );
|
|
|
if( selected )
|
|
@@ -155,21 +182,68 @@ public class NodeView extends JPanel {
|
|
|
g.setColor( Color.BLACK );
|
|
|
if( model.getContainedNodes().size() > 0 )
|
|
|
g.setColor( Color.GRAY );
|
|
|
- g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
|
|
|
+ g.fillRect( 0, 0, getWidth(), getHeight() );
|
|
|
}
|
|
|
Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
|
|
|
if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0 )
|
|
|
- linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
|
|
|
- if( layout != LayoutType.COMBINED )
|
|
|
+ linebor.paintBorder( this, g2, 0, 0, getWidth(), getHeight() );
|
|
|
+ if( model.isMouseOver() && model.getContainedNodes().size() == 0 )
|
|
|
{
|
|
|
- g.setColor( model.getRoot( layout ).getClassColor( layout ) );
|
|
|
- if( model.getContainedNodes().size() == 0 )
|
|
|
- {
|
|
|
- if( selected )
|
|
|
- g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 5, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 5, (int)model.getWidth( layout ) / 5 * 2, (int)model.getHeight( layout ) / 5 * 2 );
|
|
|
- else
|
|
|
- g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
|
|
|
- }
|
|
|
+ g.setColor( Color.WHITE );
|
|
|
+ g.fillOval( getWidth() / 4, getHeight() / 4, getWidth() / 2, getHeight() / 2 );
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public int getPlainVirtualX() {
|
|
|
+ return (int)model.getX( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getVirtualX() {
|
|
|
+ if( model.isDummyNode() )
|
|
|
+ return (int)(model.getX( layout ) + getVirtualWidth() / (3/4.0) );
|
|
|
+ return (int)model.getX( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getVirtualY() {
|
|
|
+ return (int)model.getY( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getVirtualWidth() {
|
|
|
+ if( model.isDummyNode() )
|
|
|
+ return (int)(model.getWidth( layout ) / 3);
|
|
|
+ return (int)model.getWidth( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getPlainVirtualWidth() {
|
|
|
+ return (int)model.getWidth( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getVirtualHeight() {
|
|
|
+ return (int)model.getHeight( layout );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseClicked(MouseEvent e) {}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mousePressed(MouseEvent e) {}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseReleased(MouseEvent e) {}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseEntered(MouseEvent e) {
|
|
|
+ model.setMouseOver( true );
|
|
|
+ update();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseExited(MouseEvent e) {
|
|
|
+ model.setMouseOver( false );
|
|
|
+ update();
|
|
|
+ }
|
|
|
}
|