if imgWidth <0
[jalview.git] / src / jalview / gui / TreeCanvas.java
index 484e05a..d4c88de 100755 (executable)
@@ -4,13 +4,14 @@ package jalview.gui;
 import jalview.analysis.*;\r
 import jalview.datamodel.*;\r
 import jalview.util.*;\r
+import jalview.schemes.*;\r
 import javax.swing.*;\r
 import java.awt.*;\r
 import java.awt.event.*;\r
 import java.util.*;\r
-import java.io.*;\r
+import java.awt.print.*;\r
 \r
-public class TreeCanvas extends JPanel implements MouseListener\r
+public class TreeCanvas extends JPanel implements MouseListener, Runnable, Printable\r
 {\r
   NJTree tree;\r
   JScrollPane scrollPane;\r
@@ -19,20 +20,20 @@ public class TreeCanvas extends JPanel implements MouseListener
   Font font;\r
   int  fontSize = 12;\r
 \r
+  boolean fitToWindow = true;\r
   boolean showDistances = false;\r
   boolean showBootstrap = false;\r
 \r
   int offx = 20;\r
   int offy = 20;\r
 \r
-  int threshold;\r
+  float threshold;\r
 \r
   String longestName;\r
   int labelLength=-1;\r
 \r
   //RubberbandRectangle rubberband;\r
 \r
-  Selection selected;\r
   Vector    listeners;\r
 \r
   Hashtable nameHash = new Hashtable();\r
@@ -42,7 +43,6 @@ public class TreeCanvas extends JPanel implements MouseListener
   {\r
     this.av = av;\r
     this.tree     = tree;\r
-    selected = av.getSelection();\r
     scrollPane = scroller;\r
     addMouseListener(this);\r
     tree.findHeight(tree.getTopNode());\r
@@ -52,23 +52,22 @@ public class TreeCanvas extends JPanel implements MouseListener
   }\r
   public void TreeSelectionChanged(Sequence sequence)\r
  {\r
-    selected = av.getSelection();\r
+    SequenceGroup selected = av.getSelectionGroup();\r
+    if(selected == null)\r
+    {\r
+      selected = new SequenceGroup();\r
+      av.setSelectionGroup(selected);\r
+    }\r
+\r
+    selected.setEndRes(av.alignment.getWidth());\r
+    selected.addOrRemove(sequence);\r
 \r
-    if (selected.contains(sequence))\r
-        selected.removeElement(sequence);\r
-    else\r
-        selected.addElement(sequence);\r
 \r
-    setSelected(selected);\r
     PaintRefresher.Refresh(this);\r
     repaint();\r
  }\r
 \r
 \r
-  public void setSelected(Selection selected)\r
-  {\r
-        this.selected = selected;\r
-  }\r
 \r
   public void setTree(NJTree tree) {\r
     this.tree = tree;\r
@@ -134,7 +133,8 @@ public class TreeCanvas extends JPanel implements MouseListener
 \r
       nameHash.put((SequenceI)node.element(),rect);\r
 \r
-      if (selected.contains((SequenceI)node.element())) {\r
+      SequenceGroup selected = av.getSelectionGroup();\r
+      if (selected!=null && selected.sequences.contains((SequenceI)node.element())) {\r
         g.setColor(Color.gray);\r
 \r
         g.fillRect(xend + 10, ypos - charHeight + 3,charWidth,charHeight);\r
@@ -201,7 +201,7 @@ public class TreeCanvas extends JPanel implements MouseListener
 \r
   }\r
 \r
-  public void pickNodes(Rectangle pickBox, Selection sel) {\r
+  public void pickNodes(Rectangle pickBox) {\r
     int width  = getWidth();\r
     int height = getHeight();\r
 \r
@@ -214,10 +214,10 @@ public class TreeCanvas extends JPanel implements MouseListener
     }\r
     float chunk = (float)(height-offy*2)/top.count;\r
 \r
-    pickNode(pickBox,sel,top,chunk,wscale,width,offx,offy);\r
+    pickNode(pickBox,top,chunk,wscale,width,offx,offy);\r
   }\r
 \r
-  public void pickNode(Rectangle pickBox, Selection sel, SequenceNode node, float chunk, float scale, int width,int offx, int offy) {\r
+  public void pickNode(Rectangle pickBox, SequenceNode node, float chunk, float scale, int width,int offx, int offy) {\r
     if (node == null) {\r
       return;\r
     }\r
@@ -234,40 +234,107 @@ public class TreeCanvas extends JPanel implements MouseListener
       if (pickBox.contains(new Point(xend,ypos))) {\r
         if (node.element() instanceof SequenceI) {\r
           SequenceI seq = (SequenceI)node.element();\r
-          if (sel.contains(seq)) {\r
-            sel.removeElement(seq);\r
-          } else {\r
-            sel.addElement(seq);\r
-          }\r
+          SequenceGroup sg = av.getSelectionGroup();\r
+          if(sg!=null)\r
+            sg.addOrRemove(seq);\r
         }\r
       }\r
     } else {\r
-      pickNode(pickBox,sel,(SequenceNode)node.left(), chunk,scale,width,offx,offy);\r
-      pickNode(pickBox,sel,(SequenceNode)node.right(),chunk,scale,width,offx,offy);\r
+      pickNode(pickBox,(SequenceNode)node.left(), chunk,scale,width,offx,offy);\r
+      pickNode(pickBox,(SequenceNode)node.right(),chunk,scale,width,offx,offy);\r
     }\r
   }\r
 \r
-  public void setColor(SequenceNode node, Color c) {\r
-    if (node == null) {\r
+  public void setColor(SequenceNode node, Color c)\r
+  {\r
+    if (node == null)\r
       return;\r
-    }\r
 \r
-    if (node.left() == null && node.right() == null) {\r
+    if (node.left() == null && node.right() == null)\r
+    {\r
       node.color = c;\r
 \r
-      if (node.element() instanceof SequenceI) {\r
+      if (node.element() instanceof SequenceI)\r
           ((SequenceI)node.element()).setColor(c);\r
-      }\r
-    } else {\r
+    } else\r
+    {\r
       node.color = c;\r
       setColor((SequenceNode)node.left(),c);\r
       setColor((SequenceNode)node.right(),c);\r
     }\r
   }\r
 \r
+  void startPrinting()\r
+  {\r
+    Thread thread = new Thread(this);\r
+    thread.start();\r
+  }\r
+\r
+  // put printing in a thread to avoid painting problems\r
+  public void run()\r
+  {\r
+    PrinterJob printJob = PrinterJob.getPrinterJob();\r
+    PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
+\r
+    printJob.setPrintable(this, pf);\r
+    if (printJob.printDialog())\r
+    {\r
+      try\r
+      {\r
+        printJob.print();\r
+      }\r
+      catch (Exception PrintException)\r
+      {\r
+        PrintException.printStackTrace();\r
+      }\r
+    }\r
+  }\r
+\r
+\r
+  public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
+  {\r
+\r
+    pg.setFont(font);\r
+    pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
+    int pwidth = (int) pf.getImageableWidth();\r
+    int pheight = (int) pf.getImageableHeight();\r
+\r
+    int noPages = getHeight() / pheight;\r
+    if(pi>noPages)\r
+      return Printable.NO_SUCH_PAGE;\r
+\r
+\r
+    if (pwidth > getWidth())\r
+        pwidth = getWidth();\r
 \r
-  public void paintComponent(Graphics g) {\r
+    if(fitToWindow)\r
+    {\r
+      if (pheight > getHeight())\r
+        pheight = getHeight();\r
+\r
+      noPages = 0;\r
+    }\r
+    else\r
+    {\r
+\r
+        FontMetrics fm = pg.getFontMetrics(font);\r
+        int height = fm.getHeight() * nameHash.size();\r
+        pg.translate(0, -pi*pheight  );\r
+        pg.setClip(0,pi*pheight, pwidth,pi*pheight + pheight);\r
+       // translate number of pages,\r
+       // height is screen size as this is the\r
+       // non overlapping text size\r
+        pheight = height;\r
+    }\r
+\r
+    draw(pg, pwidth, pheight);\r
+\r
+    return Printable.PAGE_EXISTS;\r
 \r
+  }\r
+\r
+  public void paintComponent(Graphics g)\r
+  {\r
 \r
     font = new Font("Verdana",Font.PLAIN,fontSize);\r
     g.setFont(font);\r
@@ -278,24 +345,17 @@ public class TreeCanvas extends JPanel implements MouseListener
       repaint();\r
 \r
 \r
-    if( scrollPane.getHeight() > fm.getHeight() * nameHash.size()+offy)\r
+    if( fitToWindow || (!fitToWindow && scrollPane.getHeight() > fm.getHeight() * nameHash.size()+offy ) )\r
      {\r
          draw(g,scrollPane.getWidth(),scrollPane.getHeight());\r
-         setPreferredSize(new Dimension(scrollPane.getWidth(), scrollPane.getHeight()));\r
+         setPreferredSize(null);\r
      }\r
     else\r
      {\r
-         setPreferredSize(new Dimension(getWidth(), fm.getHeight() * nameHash.size()));\r
-         draw( g,getWidth(), fm.getHeight() * nameHash.size());\r
+         setPreferredSize(new Dimension(scrollPane.getWidth(), fm.getHeight() * nameHash.size()));\r
+         draw( g,scrollPane.getWidth(), fm.getHeight() * nameHash.size());\r
      }\r
 \r
-\r
-    if (threshold != 0)\r
-    {\r
-        g.setColor(Color.red);\r
-        g.drawLine(threshold,0,threshold,getHeight());\r
-    }\r
-\r
     scrollPane.revalidate();\r
   }\r
     public int getFontSize() {\r
@@ -305,12 +365,15 @@ public class TreeCanvas extends JPanel implements MouseListener
         this.fontSize = fontSize;\r
         repaint();\r
     }\r
-  public void draw(Graphics g, int width, int height) {\r
-      g.setColor(Color.white);\r
-      g.fillRect(0,0,width,height);\r
+  public void draw(Graphics g1, int width, int height) {\r
 \r
+      Graphics2D g2 = (Graphics2D)g1;\r
+      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+      g2.setColor(Color.white);\r
+      g2.fillRect(0,0,width,height);\r
 \r
-      labelLength = g.getFontMetrics(font).stringWidth(longestName)+ 20;//20 allows for scrollbar\r
+\r
+      labelLength = g2.getFontMetrics(font).stringWidth(longestName)+ 20;//20 allows for scrollbar\r
 \r
       float wscale =(float)(width - labelLength -offx*2)/tree.getMaxHeight();\r
 \r
@@ -321,7 +384,20 @@ public class TreeCanvas extends JPanel implements MouseListener
       }\r
       float chunk = (float)(height-offy*2)/top.count ;\r
 \r
-      drawNode(g,tree.getTopNode(),chunk,wscale,width,offx,offy);\r
+      drawNode(g2,tree.getTopNode(),chunk,wscale,width,offx,offy);\r
+\r
+      if (threshold != 0)\r
+      {\r
+        if(av.getCurrentTree() == tree)\r
+          g2.setColor(Color.red);\r
+        else\r
+          g2.setColor(Color.gray);\r
+\r
+          int x = (int)(    threshold * (float)(getWidth()-labelLength - 2*offx) +offx   ) ;\r
+\r
+          g2.drawLine(x,0,x,getHeight());\r
+      }\r
+\r
   }\r
 \r
   public void mouseReleased(MouseEvent e) { }\r
@@ -331,6 +407,9 @@ public class TreeCanvas extends JPanel implements MouseListener
   }\r
 \r
   public void mousePressed(MouseEvent e) {\r
+\r
+      av.setCurrentTree(tree);\r
+\r
       int x = e.getX();\r
       int y = e.getY();\r
 \r
@@ -351,21 +430,53 @@ public class TreeCanvas extends JPanel implements MouseListener
           // Find threshold\r
 \r
           if (tree.getMaxHeight() != 0) {\r
-              float fthreshold = (float)(x - offx)/(float)(getWidth()-labelLength - 2*offx);\r
-              this.threshold = x;\r
+              threshold = (float)(x - offx)/(float)(getWidth()-labelLength - 2*offx);\r
+\r
               tree.getGroups().removeAllElements();\r
-              tree.groupNodes(tree.getTopNode(),fthreshold);\r
+              tree.groupNodes(tree.getTopNode(),threshold);\r
               setColor(tree.getTopNode(),Color.black);\r
 \r
-              for (int i=0; i < tree.getGroups().size(); i++) {\r
+              av.setSelectionGroup(null);\r
+              av.alignment.deleteAllGroups();\r
+\r
+              for (int i=0; i < tree.getGroups().size(); i++)\r
+              {\r
 \r
                   Color col = new Color((int)(Math.random()*255),\r
                                         (int)(Math.random()*255),\r
                                         (int)(Math.random()*255));\r
                   setColor((SequenceNode)tree.getGroups().elementAt(i),col.brighter());\r
 \r
-                  // l is vector of Objects\r
-                 // Vector l = tree.findLeaves((SequenceNode)tree.getGroups().elementAt(i),new Vector());\r
+                  Vector l = tree.findLeaves((SequenceNode)tree.getGroups().elementAt(i),new Vector());\r
+                  SequenceGroup sg = null;\r
+                  for (int j = 0; j < l.size(); j++)\r
+                  {\r
+                    SequenceNode sn = (SequenceNode) l.elementAt(j);\r
+                    if(sg==null)\r
+                       sg = new SequenceGroup("TreeGroup", av.getGlobalColourScheme(), true, true,false,0,av.alignment.getWidth());\r
+\r
+                    sg.addSequence( (Sequence) sn.element());\r
+                  }\r
+\r
+                  if (av.getGlobalColourScheme() instanceof ConservationColourScheme)\r
+                  {\r
+                    ConservationColourScheme ccs = (ConservationColourScheme) av.getGlobalColourScheme();\r
+                    Conservation c = new Conservation("Group",\r
+                                                      ResidueProperties.propHash, 3,\r
+                                                      sg.sequences, sg.getStartRes(),\r
+                                                      sg.getEndRes());\r
+\r
+                    c.calculate();\r
+                    c.verdict(false, av.ConsPercGaps);\r
+                    ccs = new ConservationColourScheme(c, ccs.cs);\r
+\r
+                    sg.cs = ccs;\r
+\r
+                  }\r
+\r
+\r
+\r
+                  av.alignment.addGroup(sg);\r
 \r
               }\r
           }\r