NodeView.java 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package view;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.event.ComponentEvent;
  8. import java.awt.event.ComponentListener;
  9. import java.awt.event.MouseEvent;
  10. import java.awt.event.MouseListener;
  11. import javax.swing.BorderFactory;
  12. import javax.swing.JFrame;
  13. import javax.swing.JPanel;
  14. import javax.swing.SwingUtilities;
  15. import javax.swing.border.Border;
  16. import bk.LayoutType;
  17. import graph.LayeredGraphNode;
  18. /**
  19. * A drawable representation of a node.
  20. * @author kolja
  21. *
  22. */
  23. public class NodeView extends JPanel implements AnnimatedView, MouseListener {
  24. private static final long serialVersionUID = 1L;
  25. private LayeredGraphNode model;
  26. private LayoutType layout;
  27. private JFrame mainView;
  28. private int originalWidth;
  29. private int originalHeight;
  30. public NodeView( LayeredGraphNode model, LayoutType lt, JFrame mv ) {
  31. mainView = mv;
  32. this.model = model;
  33. layout = lt;
  34. addMouseListener( this );
  35. originalWidth = (int)model.getWidth( lt );
  36. originalHeight = (int)model.getHeight( lt );
  37. }
  38. private synchronized void update()
  39. {
  40. SwingUtilities.invokeLater(new Runnable() {
  41. public void run() {
  42. for( ComponentListener l : mainView.getComponentListeners() )
  43. {
  44. l.componentResized( new ComponentEvent(mainView, 0) );
  45. }
  46. }
  47. });
  48. }
  49. public int getScaledX( int x )
  50. {
  51. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  52. x *= scale;
  53. return x;
  54. }
  55. public int getScaledY( int y )
  56. {
  57. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  58. y *= scale;
  59. return y;
  60. }
  61. public void updateTooltipText() {
  62. if( layout != LayoutType.COMBINED )
  63. {
  64. setToolTipText( "<html>Name: " + model.toString() +
  65. "<br>Root: " + model.getRoot( layout ).toString() +
  66. "<br>Shink: " + model.getSink( layout ).toString() +
  67. "<br>Shift: " + model.getShift( layout ) + "</html>" );
  68. }
  69. else
  70. setToolTipText( "Name: " + model.toString() );
  71. for( Component c : getComponents() )
  72. {
  73. if( !(c instanceof NodeView) )
  74. continue;
  75. ((NodeView)c).updateTooltipText();
  76. }
  77. }
  78. public int getXOffset()
  79. {
  80. int x = 0;
  81. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  82. x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
  83. return x;
  84. }
  85. public int getYOffset()
  86. {
  87. int y = 0;
  88. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  89. y += (getHeight()-50) / 2 - (getVirtualHeight() * scale ) / 2 + 25;
  90. return y;
  91. }
  92. public int getOriginalWidth() {
  93. return originalWidth;
  94. }
  95. public int getOriginalHeight() {
  96. return originalHeight;
  97. }
  98. @Override
  99. public void doLayout() {
  100. double minX = Double.POSITIVE_INFINITY;
  101. for( Component c : getComponents() )
  102. {
  103. if( !(c instanceof AnnimatedView) )
  104. continue;
  105. minX = Math.min( ((AnnimatedView)c).getVirtualX(), minX);
  106. }
  107. int x = 0;
  108. int y = 0;
  109. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  110. y += (getHeight()-50) / 2 - (getVirtualHeight() * scale ) / 2 + 25;
  111. x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
  112. for( Component c : getComponents() )
  113. {
  114. if( !(c instanceof AnnimatedView) )
  115. continue;
  116. AnnimatedView view = (AnnimatedView)c;
  117. c.setLocation( getScaledX( view.getVirtualX() - (int)minX ) + x, getScaledY( view.getVirtualY() ) + y);
  118. if( c instanceof NodeView )
  119. c.setSize( getScaledX( ((NodeView)c).getOriginalWidth() ), getScaledY( ((NodeView)c).getOriginalHeight() ) );
  120. else
  121. c.setSize( getScaledX( view.getVirtualWidth() ), getScaledY( view.getVirtualHeight() ) );
  122. c.doLayout();
  123. }
  124. }
  125. @Override
  126. public void paint( Graphics g )
  127. {
  128. if( layout == LayoutType.COMBINED && model.getColor( null ) == null )
  129. return;
  130. updateTooltipText();
  131. paintComponent( g );
  132. double minX = Double.POSITIVE_INFINITY;
  133. for( Component c : getComponents() )
  134. {
  135. if( !(c instanceof AnnimatedView) )
  136. continue;
  137. minX = Math.min( ((AnnimatedView)c).getVirtualX(), minX);
  138. }
  139. int x = 0;
  140. double scale = Math.min( (getWidth()-50) / (double)getVirtualWidth(), (getHeight()-50) / (double)getVirtualHeight());
  141. x += (getWidth()-50) / 2 - (getVirtualWidth() * scale ) / 2 + 25;
  142. for( Component c : getComponents() )
  143. {
  144. if( c instanceof NodeView )
  145. {
  146. if( layout != LayoutType.COMBINED )
  147. {
  148. NodeView v = (NodeView)c;
  149. v.renderClass( g.create( getScaledX( v.getPlainVirtualX() - (int)minX - 12 ) + x, c.getY() - getScaledY(12), getScaledX( v.getPlainVirtualWidth() + 22 ), c.getHeight() + getScaledY(22) ) );
  150. }
  151. }
  152. c.paint( g.create( c.getX(), c.getY(), c.getWidth(), c.getHeight() ) );
  153. }
  154. }
  155. public void renderClass( Graphics g ) {
  156. g.setColor( model.getRoot( layout ).getClassColor( layout ) );
  157. if( model.getContainedNodes().size() == 0 && model.getRoot( layout ).getClassColor( layout ) != Color.LIGHT_GRAY )
  158. {
  159. g.setColor( new Color( (g.getColor().getRed() + 500) / 3, (g.getColor().getGreen() + 500) / 3, (g.getColor().getBlue() + 500) / 3 ) );
  160. g.fillRect( 0, 0, g.getClipBounds().width, g.getClipBounds().height );
  161. }
  162. }
  163. @Override
  164. public void paintComponent( Graphics g )
  165. {
  166. Graphics2D g2 = (Graphics2D)g;
  167. g2.setColor( model.getColor( layout ) );
  168. g2.setStroke(new BasicStroke(5));
  169. if( model.getContainedNodes().size() == 0 )
  170. {
  171. if( model.getRoot( layout ) == model )
  172. g2.fillOval( 0, 0, getWidth(), getHeight() );
  173. else
  174. g2.fillRect( 0, 0, getWidth(), getHeight() );
  175. }
  176. boolean selected = model.isSelected( layout );
  177. if( selected )
  178. {
  179. g.setColor( Color.BLACK );
  180. if( model.getContainedNodes().size() > 0 )
  181. g.setColor( Color.GRAY );
  182. g.fillRect( 0, 0, getWidth(), getHeight() );
  183. }
  184. Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
  185. if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0 )
  186. linebor.paintBorder( this, g2, 0, 0, getWidth(), getHeight() );
  187. if( model.isMouseOver() && model.getContainedNodes().size() == 0 )
  188. {
  189. g.setColor( Color.WHITE );
  190. g.fillOval( getWidth() / 4, getHeight() / 4, getWidth() / 2, getHeight() / 2 );
  191. }
  192. }
  193. public int getPlainVirtualX() {
  194. return (int)model.getX( layout );
  195. }
  196. @Override
  197. public int getVirtualX() {
  198. if( model.isDummyNode() )
  199. return (int)(model.getX( layout ) + getVirtualWidth() / (3/4.0) );
  200. return (int)model.getX( layout );
  201. }
  202. @Override
  203. public int getVirtualY() {
  204. return (int)model.getY( layout );
  205. }
  206. @Override
  207. public int getVirtualWidth() {
  208. if( model.isDummyNode() )
  209. return (int)(model.getWidth( layout ) / 3);
  210. return (int)model.getWidth( layout );
  211. }
  212. public int getPlainVirtualWidth() {
  213. return (int)model.getWidth( layout );
  214. }
  215. @Override
  216. public int getVirtualHeight() {
  217. return (int)model.getHeight( layout );
  218. }
  219. @Override
  220. public void mouseClicked(MouseEvent e) {}
  221. @Override
  222. public void mousePressed(MouseEvent e) {}
  223. @Override
  224. public void mouseReleased(MouseEvent e) {}
  225. @Override
  226. public void mouseEntered(MouseEvent e) {
  227. model.setMouseOver( true );
  228. update();
  229. }
  230. @Override
  231. public void mouseExited(MouseEvent e) {
  232. model.setMouseOver( false );
  233. update();
  234. }
  235. }