JAL-1807 still testing
[jalviewjs.git] / unused / appletgui / RotatableCanvas.java
index 7eb8269..798dae0 100644 (file)
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.appletgui;
-
-import jalview.api.RotatableCanvasI;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.datamodel.SequencePoint;
-import jalview.math.RotatableMatrix;
-import jalview.util.Format;
-import jalview.util.MessageManager;
-import jalview.viewmodel.AlignmentViewport;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Image;
-import javax.swing.JPanel;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.util.Vector;
-
-public class RotatableCanvas extends JPanel implements MouseListener,
-        MouseMotionListener, KeyListener, RotatableCanvasI
-{
-  RotatableMatrix idmat = new RotatableMatrix(3, 3);
-
-  RotatableMatrix objmat = new RotatableMatrix(3, 3);
-
-  RotatableMatrix rotmat = new RotatableMatrix(3, 3);
-
-  String tooltip;
-
-  int toolx, tooly;
-
-  // RubberbandRectangle rubberband;
-
-  boolean drawAxes = true;
-
-  int omx = 0;
-
-  int mx = 0;
-
-  int omy = 0;
-
-  int my = 0;
-
-  Image img;
-
-  Graphics ig;
-
-  Dimension prefsize;
-
-  float centre[] = new float[3];
-
-  float width[] = new float[3];
-
-  float max[] = new float[3];
-
-  float min[] = new float[3];
-
-  float maxwidth;
-
-  float scale;
-
-  int npoint;
-
-  Vector points;
-
-  float[][] orig;
-
-  float[][] axes;
-
-  int startx;
-
-  int starty;
-
-  int lastx;
-
-  int lasty;
-
-  int rectx1;
-
-  int recty1;
-
-  int rectx2;
-
-  int recty2;
-
-  float scalefactor = 1;
-
-  AlignmentViewport av;
-
-  boolean showLabels = false;
-
-  public RotatableCanvas(AlignmentViewport av)
-  {
-    this.av = av;
-  }
-
-  public void showLabels(boolean b)
-  {
-    showLabels = b;
-    repaint();
-  }
-
-  public void setPoints(Vector points, int npoint)
-  {
-    this.points = points;
-    this.npoint = npoint;
-    PaintRefresher.Register(this, av.getSequenceSetId());
-
-    prefsize = getPreferredSize();
-    orig = new float[npoint][3];
-
-    for (int i = 0; i < npoint; i++)
-    {
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      for (int j = 0; j < 3; j++)
-      {
-        orig[i][j] = sp.coord[j];
-      }
-    }
-    // Initialize the matrices to identity
-
-    for (int i = 0; i < 3; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        if (i != j)
-        {
-          idmat.addElement(i, j, 0);
-          objmat.addElement(i, j, 0);
-          rotmat.addElement(i, j, 0);
-        }
-        else
-        {
-          idmat.addElement(i, j, 0);
-          objmat.addElement(i, j, 0);
-          rotmat.addElement(i, j, 0);
-        }
-      }
-    }
-
-    axes = new float[3][3];
-    initAxes();
-
-    findCentre();
-    findWidth();
-
-    scale = findScale();
-
-    // System.out.println("Scale factor = " + scale);
-
-    addMouseListener(this);
-    addKeyListener(this);
-    // if (getParent() != null) {
-    // getParent().addKeyListener(this);
-    // }
-    addMouseMotionListener(this);
-
-    // Add rubberband
-    // rubberband = new RubberbandRectangle(this);
-    // rubberband.setActive(true);
-    // rubberband.addListener(this);
-  }
-
-  /*
-   * public boolean handleSequenceSelectionEvent(SequenceSelectionEvent evt) {
-   * redrawneeded = true; repaint(); return true; }
-   * 
-   * public void removeNotify() { controller.removeListener(this);
-   * super.removeNotify(); }
-   */
-
-  public void initAxes()
-  {
-    for (int i = 0; i < 3; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        if (i != j)
-        {
-          axes[i][j] = 0;
-        }
-        else
-        {
-          axes[i][j] = 1;
-        }
-      }
-    }
-  }
-
-  public void findWidth()
-  {
-    max = new float[3];
-    min = new float[3];
-
-    max[0] = (float) -1e30;
-    max[1] = (float) -1e30;
-    max[2] = (float) -1e30;
-
-    min[0] = (float) 1e30;
-    min[1] = (float) 1e30;
-    min[2] = (float) 1e30;
-
-    for (int i = 0; i < 3; i++)
-    {
-      for (int j = 0; j < npoint; j++)
-      {
-        SequencePoint sp = (SequencePoint) points.elementAt(j);
-        if (sp.coord[i] >= max[i])
-        {
-          max[i] = sp.coord[i];
-        }
-        if (sp.coord[i] <= min[i])
-        {
-          min[i] = sp.coord[i];
-        }
-      }
-    }
-
-    // System.out.println("xmax " + max[0] + " min " + min[0]);
-    // System.out.println("ymax " + max[1] + " min " + min[1]);
-    // System.out.println("zmax " + max[2] + " min " + min[2]);
-
-    width[0] = Math.abs(max[0] - min[0]);
-    width[1] = Math.abs(max[1] - min[1]);
-    width[2] = Math.abs(max[2] - min[2]);
-
-    maxwidth = width[0];
-
-    if (width[1] > width[0])
-    {
-      maxwidth = width[1];
-    }
-    if (width[2] > width[1])
-    {
-      maxwidth = width[2];
-    }
-
-    // System.out.println("Maxwidth = " + maxwidth);
-  }
-
-  public float findScale()
-  {
-    int dim, width, height;
-    if (getSize().width != 0)
-    {
-      width = getSize().width;
-      height = getSize().height;
-    }
-    else
-    {
-      width = prefsize.width;
-      height = prefsize.height;
-    }
-
-    if (width < height)
-    {
-      dim = width;
-    }
-    else
-    {
-      dim = height;
-    }
-
-    return dim * scalefactor / (2 * maxwidth);
-  }
-
-  public void findCentre()
-  {
-    // Find centre coordinate
-    findWidth();
-
-    centre[0] = (max[0] + min[0]) / 2;
-    centre[1] = (max[1] + min[1]) / 2;
-    centre[2] = (max[2] + min[2]) / 2;
-
-    // System.out.println("Centre x " + centre[0]);
-    // System.out.println("Centre y " + centre[1]);
-    // System.out.println("Centre z " + centre[2]);
-  }
-
-  public Dimension getPreferredSize()
-  {
-    if (prefsize != null)
-    {
-      return prefsize;
-    }
-    else
-    {
-      return new Dimension(400, 400);
-    }
-  }
-
-  public Dimension getMinimumSize()
-  {
-    return getPreferredSize();
-  }
-
-  public void update(Graphics g)
-  {
-    paint(g);
-  }
-
-  public void paint(Graphics g)
-  {
-    if (points == null)
-    {
-      g.setFont(new Font("Verdana", Font.PLAIN, 18));
-      g.drawString(MessageManager.getString("label.calculating_pca")
-              + "....", 20, getSize().height / 2);
-    }
-    else
-    {
-
-      // Only create the image at the beginning -
-      if ((img == null) || (prefsize.width != getSize().width)
-              || (prefsize.height != getSize().height))
-      {
-        prefsize.width = getSize().width;
-        prefsize.height = getSize().height;
-
-        scale = findScale();
-
-        // System.out.println("New scale = " + scale);
-        img = createImage(getSize().width, getSize().height);
-        ig = img.getGraphics();
-
-      }
-
-      drawBackground(ig, Color.black);
-      drawScene(ig);
-      if (drawAxes == true)
-      {
-        drawAxes(ig);
-      }
-
-      if (tooltip != null)
-      {
-        ig.setColor(Color.red);
-        ig.drawString(tooltip, toolx, tooly);
-      }
-
-      g.drawImage(img, 0, 0, this);
-    }
-  }
-
-  public void drawAxes(Graphics g)
-  {
-
-    g.setColor(Color.yellow);
-    for (int i = 0; i < 3; i++)
-    {
-      g.drawLine(getSize().width / 2, getSize().height / 2,
-              (int) (axes[i][0] * scale * max[0] + getSize().width / 2),
-              (int) (axes[i][1] * scale * max[1] + getSize().height / 2));
-    }
-  }
-
-  public void drawBackground(Graphics g, Color col)
-  {
-    g.setColor(col);
-    g.fillRect(0, 0, prefsize.width, prefsize.height);
-  }
-
-  public void drawScene(Graphics g)
-  {
-    // boolean darker = false;
-
-    int halfwidth = getSize().width / 2;
-    int halfheight = getSize().height / 2;
-
-    for (int i = 0; i < npoint; i++)
-    {
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      int x = (int) ((sp.coord[0] - centre[0]) * scale) + halfwidth;
-      int y = (int) ((sp.coord[1] - centre[1]) * scale)
-              + halfheight;
-      float z = sp.coord[1] - centre[2];
-
-      if (av.getSequenceColour(sp.sequence) == Color.black)
-      {
-        g.setColor(Color.white);
-      }
-      else
-      {
-        g.setColor(av.getSequenceColour(sp.sequence));
-      }
-
-      if (av.getSelectionGroup() != null)
-      {
-        if (av.getSelectionGroup().getSequences(null)
-                .contains(((SequencePoint) points.elementAt(i)).sequence))
-        {
-          g.setColor(Color.gray);
-        }
-      }
-      if (z < 0)
-      {
-        g.setColor(g.getColor().darker());
-      }
-
-      g.fillRect(x - 3, y - 3, 6, 6);
-      if (showLabels)
-      {
-        g.setColor(Color.red);
-        g.drawString(
-                ((SequencePoint) points.elementAt(i)).sequence.getName(),
-                x - 3, y - 4);
-      }
-    }
-  }
-
-  public Dimension minimumsize()
-  {
-    return prefsize;
-  }
-
-  public Dimension preferredsize()
-  {
-    return prefsize;
-  }
-
-  public void keyTyped(KeyEvent evt)
-  {
-  }
-
-  public void keyReleased(KeyEvent evt)
-  {
-  }
-
-  public void keyPressed(KeyEvent evt)
-  {
-    if (evt.getKeyCode() == KeyEvent.VK_UP)
-    {
-      scalefactor = (float) (scalefactor * 1.1);
-      scale = findScale();
-    }
-    else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
-    {
-      scalefactor = (float) (scalefactor * 0.9);
-      scale = findScale();
-    }
-    else if (evt.getKeyChar() == 's')
-    {
-      System.err.println("DEBUG: Rectangle selection"); // log.debug
-      if (rectx2 != -1 && recty2 != -1)
-      {
-        rectSelect(rectx1, recty1, rectx2, recty2);
-
-      }
-    }
-    repaint();
-  }
-
-  public void printPoints()
-  {
-    for (int i = 0; i < npoint; i++)
-    {
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      Format.printLong(System.out, "%5d ", i);
-      for (int j = 0; j < 3; j++)
-      {
-        Format.printDouble(System.out, "%13.3f  ", sp.coord[j]);
-      }
-      System.out.println();
-    }
-  }
-
-  public void mouseClicked(MouseEvent evt)
-  {
-  }
-
-  public void mouseEntered(MouseEvent evt)
-  {
-  }
-
-  public void mouseExited(MouseEvent evt)
-  {
-  }
-
-  public void mouseReleased(MouseEvent evt)
-  {
-  }
-
-  public void mousePressed(MouseEvent evt)
-  {
-    int x = evt.getX();
-    int y = evt.getY();
-
-    mx = x;
-    my = y;
-
-    omx = mx;
-    omy = my;
-
-    startx = x;
-    starty = y;
-
-    rectx1 = x;
-    recty1 = y;
-
-    rectx2 = -1;
-    recty2 = -1;
-
-    SequenceI found = findPoint(x, y);
-
-    if (found != null)
-    {
-      // TODO: applet PCA is not associatable with multi-panels - only parent
-      // view
-      if (av.getSelectionGroup() != null)
-      {
-        av.getSelectionGroup().addOrRemove(found, true);
-        av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);
-      }
-      else
-      {
-        av.setSelectionGroup(new SequenceGroup());
-        av.getSelectionGroup().addOrRemove(found, true);
-        av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);
-
-      }
-      PaintRefresher.Refresh(this, av.getSequenceSetId());
-      av.sendSelection();
-    }
-    repaint();
-  }
-
-  public void mouseMoved(MouseEvent evt)
-  {
-    SequenceI found = findPoint(evt.getX(), evt.getY());
-    if (found == null)
-    {
-      tooltip = null;
-    }
-    else
-    {
-      tooltip = found.getName();
-      toolx = evt.getX();
-      tooly = evt.getY();
-    }
-    repaint();
-  }
-
-  public void mouseDragged(MouseEvent evt)
-  {
-    mx = evt.getX();
-    my = evt.getY();
-
-    rotmat.setIdentity();
-
-    rotmat.rotate(my - omy, 'x');
-    rotmat.rotate(mx - omx, 'y');
-
-    for (int i = 0; i < npoint; i++)
-    {
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      sp.coord[0] -= centre[0];
-      sp.coord[1] -= centre[1];
-      sp.coord[2] -= centre[2];
-
-      // Now apply the rotation matrix
-      sp.coord = rotmat.vectorMultiply(sp.coord);
-
-      // Now translate back again
-      sp.coord[0] += centre[0];
-      sp.coord[1] += centre[1];
-      sp.coord[2] += centre[2];
-    }
-
-    for (int i = 0; i < 3; i++)
-    {
-      axes[i] = rotmat.vectorMultiply(axes[i]);
-    }
-    omx = mx;
-    omy = my;
-
-    paint(this.getGraphics());
-  }
-
-  public void rectSelect(int x1, int y1, int x2, int y2)
-  {
-    // boolean changedSel = false;
-    for (int i = 0; i < npoint; i++)
-    {
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      int tmp1 = (int) ((sp.coord[0] - centre[0]) * scale + getSize().width / 2.0);
-      int tmp2 = (int) ((sp.coord[1] - centre[1]) * scale + getSize().height / 2.0);
-
-      if (tmp1 > x1 && tmp1 < x2 && tmp2 > y1 && tmp2 < y2)
-      {
-        if (av != null)
-        {
-          if (!av.getSelectionGroup().getSequences(null)
-                  .contains(sp.sequence))
-          {
-            av.getSelectionGroup().addSequence(sp.sequence, true);
-          }
-        }
-      }
-    }
-  }
-
-  public SequenceI findPoint(int x, int y)
-  {
-
-    int halfwidth = getSize().width / 2;
-    int halfheight = getSize().height / 2;
-
-    int found = -1;
-
-    for (int i = 0; i < npoint; i++)
-    {
-
-      SequencePoint sp = (SequencePoint) points.elementAt(i);
-      int px = (int) ((sp.coord[0] - centre[0]) * scale)
-              + halfwidth;
-      int py = (int) ((sp.coord[1] - centre[1]) * scale)
-              + halfheight;
-
-      if (Math.abs(px - x) < 3 && Math.abs(py - y) < 3)
-      {
-        found = i;
-      }
-    }
-    if (found != -1)
-    {
-      return ((SequencePoint) points.elementAt(found)).sequence;
-    }
-    else
-    {
-      return null;
-    }
-  }
-
-}
+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)\r
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3\r
+ * of the License, or (at your option) any later version.\r
+ *  \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE.  See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
+ * The Jalview Authors are detailed in the 'AUTHORS' file.\r
+ */\r
+package jalview.appletgui;\r
+\r
+import jalview.api.RotatableCanvasI;\r
+import jalview.datamodel.SequenceGroup;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.datamodel.SequencePoint;\r
+import jalview.math.RotatableMatrix;\r
+import jalview.util.Format;\r
+import jalview.util.MessageManager;\r
+import jalview.viewmodel.AlignmentViewport;\r
+\r
+import java.awt.Color;\r
+import java.awt.Dimension;\r
+import java.awt.Font;\r
+import java.awt.Graphics;\r
+import java.awt.Image;\r
+import javax.swing.JPanel;\r
+import java.awt.event.KeyEvent;\r
+import java.awt.event.KeyListener;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseListener;\r
+import java.awt.event.MouseMotionListener;\r
+import java.util.Vector;\r
+\r
+public class RotatableCanvas extends JPanel implements MouseListener,\r
+        MouseMotionListener, KeyListener, RotatableCanvasI\r
+{\r
+  RotatableMatrix idmat = new RotatableMatrix(3, 3);\r
+\r
+  RotatableMatrix objmat = new RotatableMatrix(3, 3);\r
+\r
+  RotatableMatrix rotmat = new RotatableMatrix(3, 3);\r
+\r
+  String tooltip;\r
+\r
+  int toolx, tooly;\r
+\r
+  // RubberbandRectangle rubberband;\r
+\r
+  boolean drawAxes = true;\r
+\r
+  int omx = 0;\r
+\r
+  int mx = 0;\r
+\r
+  int omy = 0;\r
+\r
+  int my = 0;\r
+\r
+  Image img;\r
+\r
+  Graphics ig;\r
+\r
+  Dimension prefsize;\r
+\r
+  float centre[] = new float[3];\r
+\r
+  float width[] = new float[3];\r
+\r
+  float max[] = new float[3];\r
+\r
+  float min[] = new float[3];\r
+\r
+  float maxwidth;\r
+\r
+  float scale;\r
+\r
+  int npoint;\r
+\r
+  Vector points;\r
+\r
+  float[][] orig;\r
+\r
+  float[][] axes;\r
+\r
+  int startx;\r
+\r
+  int starty;\r
+\r
+  int lastx;\r
+\r
+  int lasty;\r
+\r
+  int rectx1;\r
+\r
+  int recty1;\r
+\r
+  int rectx2;\r
+\r
+  int recty2;\r
+\r
+  float scalefactor = 1;\r
+\r
+  AlignmentViewport av;\r
+\r
+  boolean showLabels = false;\r
+\r
+  public RotatableCanvas(AlignmentViewport av)\r
+  {\r
+    this.av = av;\r
+  }\r
+\r
+  public void showLabels(boolean b)\r
+  {\r
+    showLabels = b;\r
+    repaint();\r
+  }\r
+\r
+  public void setPoints(Vector points, int npoint)\r
+  {\r
+    this.points = points;\r
+    this.npoint = npoint;\r
+    PaintRefresher.Register(this, av.getSequenceSetId());\r
+\r
+    prefsize = getPreferredSize();\r
+    orig = new float[npoint][3];\r
+\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      for (int j = 0; j < 3; j++)\r
+      {\r
+        orig[i][j] = sp.coord[j];\r
+      }\r
+    }\r
+    // Initialize the matrices to identity\r
+\r
+    for (int i = 0; i < 3; i++)\r
+    {\r
+      for (int j = 0; j < 3; j++)\r
+      {\r
+        if (i != j)\r
+        {\r
+          idmat.addElement(i, j, 0);\r
+          objmat.addElement(i, j, 0);\r
+          rotmat.addElement(i, j, 0);\r
+        }\r
+        else\r
+        {\r
+          idmat.addElement(i, j, 0);\r
+          objmat.addElement(i, j, 0);\r
+          rotmat.addElement(i, j, 0);\r
+        }\r
+      }\r
+    }\r
+\r
+    axes = new float[3][3];\r
+    initAxes();\r
+\r
+    findCentre();\r
+    findWidth();\r
+\r
+    scale = findScale();\r
+\r
+    // System.out.println("Scale factor = " + scale);\r
+\r
+    addMouseListener(this);\r
+    addKeyListener(this);\r
+    // if (getParent() != null) {\r
+    // getParent().addKeyListener(this);\r
+    // }\r
+    addMouseMotionListener(this);\r
+\r
+    // Add rubberband\r
+    // rubberband = new RubberbandRectangle(this);\r
+    // rubberband.setActive(true);\r
+    // rubberband.addListener(this);\r
+  }\r
+\r
+  /*\r
+   * public boolean handleSequenceSelectionEvent(SequenceSelectionEvent evt) {\r
+   * redrawneeded = true; repaint(); return true; }\r
+   * \r
+   * public void removeNotify() { controller.removeListener(this);\r
+   * super.removeNotify(); }\r
+   */\r
+\r
+  public void initAxes()\r
+  {\r
+    for (int i = 0; i < 3; i++)\r
+    {\r
+      for (int j = 0; j < 3; j++)\r
+      {\r
+        if (i != j)\r
+        {\r
+          axes[i][j] = 0;\r
+        }\r
+        else\r
+        {\r
+          axes[i][j] = 1;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  public void findWidth()\r
+  {\r
+    max = new float[3];\r
+    min = new float[3];\r
+\r
+    max[0] = (float) -1e30;\r
+    max[1] = (float) -1e30;\r
+    max[2] = (float) -1e30;\r
+\r
+    min[0] = (float) 1e30;\r
+    min[1] = (float) 1e30;\r
+    min[2] = (float) 1e30;\r
+\r
+    for (int i = 0; i < 3; i++)\r
+    {\r
+      for (int j = 0; j < npoint; j++)\r
+      {\r
+        SequencePoint sp = (SequencePoint) points.elementAt(j);\r
+        if (sp.coord[i] >= max[i])\r
+        {\r
+          max[i] = sp.coord[i];\r
+        }\r
+        if (sp.coord[i] <= min[i])\r
+        {\r
+          min[i] = sp.coord[i];\r
+        }\r
+      }\r
+    }\r
+\r
+    // System.out.println("xmax " + max[0] + " min " + min[0]);\r
+    // System.out.println("ymax " + max[1] + " min " + min[1]);\r
+    // System.out.println("zmax " + max[2] + " min " + min[2]);\r
+\r
+    width[0] = Math.abs(max[0] - min[0]);\r
+    width[1] = Math.abs(max[1] - min[1]);\r
+    width[2] = Math.abs(max[2] - min[2]);\r
+\r
+    maxwidth = width[0];\r
+\r
+    if (width[1] > width[0])\r
+    {\r
+      maxwidth = width[1];\r
+    }\r
+    if (width[2] > width[1])\r
+    {\r
+      maxwidth = width[2];\r
+    }\r
+\r
+    // System.out.println("Maxwidth = " + maxwidth);\r
+  }\r
+\r
+  public float findScale()\r
+  {\r
+    int dim, width, height;\r
+    if (getSize().width != 0)\r
+    {\r
+      width = getSize().width;\r
+      height = getSize().height;\r
+    }\r
+    else\r
+    {\r
+      width = prefsize.width;\r
+      height = prefsize.height;\r
+    }\r
+\r
+    if (width < height)\r
+    {\r
+      dim = width;\r
+    }\r
+    else\r
+    {\r
+      dim = height;\r
+    }\r
+\r
+    return dim * scalefactor / (2 * maxwidth);\r
+  }\r
+\r
+  public void findCentre()\r
+  {\r
+    // Find centre coordinate\r
+    findWidth();\r
+\r
+    centre[0] = (max[0] + min[0]) / 2;\r
+    centre[1] = (max[1] + min[1]) / 2;\r
+    centre[2] = (max[2] + min[2]) / 2;\r
+\r
+    // System.out.println("Centre x " + centre[0]);\r
+    // System.out.println("Centre y " + centre[1]);\r
+    // System.out.println("Centre z " + centre[2]);\r
+  }\r
+\r
+  public Dimension getPreferredSize()\r
+  {\r
+    if (prefsize != null)\r
+    {\r
+      return prefsize;\r
+    }\r
+    else\r
+    {\r
+      return new Dimension(400, 400);\r
+    }\r
+  }\r
+\r
+  public Dimension getMinimumSize()\r
+  {\r
+    return getPreferredSize();\r
+  }\r
+\r
+  public void update(Graphics g)\r
+  {\r
+    paint(g);\r
+  }\r
+\r
+  public void paint(Graphics g)\r
+  {\r
+    if (points == null)\r
+    {\r
+      g.setFont(new Font("Verdana", Font.PLAIN, 18));\r
+      g.drawString(MessageManager.getString("label.calculating_pca")\r
+              + "....", 20, getSize().height / 2);\r
+    }\r
+    else\r
+    {\r
+\r
+      // Only create the image at the beginning -\r
+      if ((img == null) || (prefsize.width != getSize().width)\r
+              || (prefsize.height != getSize().height))\r
+      {\r
+        prefsize.width = getSize().width;\r
+        prefsize.height = getSize().height;\r
+\r
+        scale = findScale();\r
+\r
+        // System.out.println("New scale = " + scale);\r
+        img = createImage(getSize().width, getSize().height);\r
+        ig = img.getGraphics();\r
+\r
+      }\r
+\r
+      drawBackground(ig, Color.black);\r
+      drawScene(ig);\r
+      if (drawAxes == true)\r
+      {\r
+        drawAxes(ig);\r
+      }\r
+\r
+      if (tooltip != null)\r
+      {\r
+        ig.setColor(Color.red);\r
+        ig.drawString(tooltip, toolx, tooly);\r
+      }\r
+\r
+      g.drawImage(img, 0, 0, this);\r
+    }\r
+  }\r
+\r
+  public void drawAxes(Graphics g)\r
+  {\r
+\r
+    g.setColor(Color.yellow);\r
+    for (int i = 0; i < 3; i++)\r
+    {\r
+      g.drawLine(getSize().width / 2, getSize().height / 2,\r
+              (int) (axes[i][0] * scale * max[0] + getSize().width / 2),\r
+              (int) (axes[i][1] * scale * max[1] + getSize().height / 2));\r
+    }\r
+  }\r
+\r
+  public void drawBackground(Graphics g, Color col)\r
+  {\r
+    g.setColor(col);\r
+    g.fillRect(0, 0, prefsize.width, prefsize.height);\r
+  }\r
+\r
+  public void drawScene(Graphics g)\r
+  {\r
+    // boolean darker = false;\r
+\r
+    int halfwidth = getSize().width / 2;\r
+    int halfheight = getSize().height / 2;\r
+\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      int x = (int) ((sp.coord[0] - centre[0]) * scale) + halfwidth;\r
+      int y = (int) ((sp.coord[1] - centre[1]) * scale)\r
+              + halfheight;\r
+      float z = sp.coord[1] - centre[2];\r
+\r
+      if (av.getSequenceColour(sp.sequence) == Color.black)\r
+      {\r
+        g.setColor(Color.white);\r
+      }\r
+      else\r
+      {\r
+        g.setColor(av.getSequenceColour(sp.sequence));\r
+      }\r
+\r
+      if (av.getSelectionGroup() != null)\r
+      {\r
+        if (av.getSelectionGroup().getSequences(null)\r
+                .contains(((SequencePoint) points.elementAt(i)).sequence))\r
+        {\r
+          g.setColor(Color.gray);\r
+        }\r
+      }\r
+      if (z < 0)\r
+      {\r
+        g.setColor(g.getColor().darker());\r
+      }\r
+\r
+      g.fillRect(x - 3, y - 3, 6, 6);\r
+      if (showLabels)\r
+      {\r
+        g.setColor(Color.red);\r
+        g.drawString(\r
+                ((SequencePoint) points.elementAt(i)).sequence.getName(),\r
+                x - 3, y - 4);\r
+      }\r
+    }\r
+  }\r
+\r
+  public Dimension minimumsize()\r
+  {\r
+    return prefsize;\r
+  }\r
+\r
+  public Dimension preferredsize()\r
+  {\r
+    return prefsize;\r
+  }\r
+\r
+  public void keyTyped(KeyEvent evt)\r
+  {\r
+  }\r
+\r
+  public void keyReleased(KeyEvent evt)\r
+  {\r
+  }\r
+\r
+  public void keyPressed(KeyEvent evt)\r
+  {\r
+    if (evt.getKeyCode() == KeyEvent.VK_UP)\r
+    {\r
+      scalefactor = (float) (scalefactor * 1.1);\r
+      scale = findScale();\r
+    }\r
+    else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
+    {\r
+      scalefactor = (float) (scalefactor * 0.9);\r
+      scale = findScale();\r
+    }\r
+    else if (evt.getKeyChar() == 's')\r
+    {\r
+      System.err.println("DEBUG: Rectangle selection"); // log.debug\r
+      if (rectx2 != -1 && recty2 != -1)\r
+      {\r
+        rectSelect(rectx1, recty1, rectx2, recty2);\r
+\r
+      }\r
+    }\r
+    repaint();\r
+  }\r
+\r
+  public void printPoints()\r
+  {\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      Format.printLong(System.out, "%5d ", i);\r
+      for (int j = 0; j < 3; j++)\r
+      {\r
+        Format.printDouble(System.out, "%13.3f  ", sp.coord[j]);\r
+      }\r
+      System.out.println();\r
+    }\r
+  }\r
+\r
+  public void mouseClicked(MouseEvent evt)\r
+  {\r
+  }\r
+\r
+  public void mouseEntered(MouseEvent evt)\r
+  {\r
+  }\r
+\r
+  public void mouseExited(MouseEvent evt)\r
+  {\r
+  }\r
+\r
+  public void mouseReleased(MouseEvent evt)\r
+  {\r
+  }\r
+\r
+  public void mousePressed(MouseEvent evt)\r
+  {\r
+    int x = evt.getX();\r
+    int y = evt.getY();\r
+\r
+    mx = x;\r
+    my = y;\r
+\r
+    omx = mx;\r
+    omy = my;\r
+\r
+    startx = x;\r
+    starty = y;\r
+\r
+    rectx1 = x;\r
+    recty1 = y;\r
+\r
+    rectx2 = -1;\r
+    recty2 = -1;\r
+\r
+    SequenceI found = findPoint(x, y);\r
+\r
+    if (found != null)\r
+    {\r
+      // TODO: applet PCA is not associatable with multi-panels - only parent\r
+      // view\r
+      if (av.getSelectionGroup() != null)\r
+      {\r
+        av.getSelectionGroup().addOrRemove(found, true);\r
+        av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);\r
+      }\r
+      else\r
+      {\r
+        av.setSelectionGroup(new SequenceGroup());\r
+        av.getSelectionGroup().addOrRemove(found, true);\r
+        av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);\r
+\r
+      }\r
+      PaintRefresher.Refresh(this, av.getSequenceSetId());\r
+      av.sendSelection();\r
+    }\r
+    repaint();\r
+  }\r
+\r
+  public void mouseMoved(MouseEvent evt)\r
+  {\r
+    SequenceI found = findPoint(evt.getX(), evt.getY());\r
+    if (found == null)\r
+    {\r
+      tooltip = null;\r
+    }\r
+    else\r
+    {\r
+      tooltip = found.getName();\r
+      toolx = evt.getX();\r
+      tooly = evt.getY();\r
+    }\r
+    repaint();\r
+  }\r
+\r
+  public void mouseDragged(MouseEvent evt)\r
+  {\r
+    mx = evt.getX();\r
+    my = evt.getY();\r
+\r
+    rotmat.setIdentity();\r
+\r
+    rotmat.rotate(my - omy, 'x');\r
+    rotmat.rotate(mx - omx, 'y');\r
+\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      sp.coord[0] -= centre[0];\r
+      sp.coord[1] -= centre[1];\r
+      sp.coord[2] -= centre[2];\r
+\r
+      // Now apply the rotation matrix\r
+      sp.coord = rotmat.vectorMultiply(sp.coord);\r
+\r
+      // Now translate back again\r
+      sp.coord[0] += centre[0];\r
+      sp.coord[1] += centre[1];\r
+      sp.coord[2] += centre[2];\r
+    }\r
+\r
+    for (int i = 0; i < 3; i++)\r
+    {\r
+      axes[i] = rotmat.vectorMultiply(axes[i]);\r
+    }\r
+    omx = mx;\r
+    omy = my;\r
+\r
+    paint(this.getGraphics());\r
+  }\r
+\r
+  public void rectSelect(int x1, int y1, int x2, int y2)\r
+  {\r
+    // boolean changedSel = false;\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      int tmp1 = (int) ((sp.coord[0] - centre[0]) * scale + getSize().width / 2.0);\r
+      int tmp2 = (int) ((sp.coord[1] - centre[1]) * scale + getSize().height / 2.0);\r
+\r
+      if (tmp1 > x1 && tmp1 < x2 && tmp2 > y1 && tmp2 < y2)\r
+      {\r
+        if (av != null)\r
+        {\r
+          if (!av.getSelectionGroup().getSequences(null)\r
+                  .contains(sp.sequence))\r
+          {\r
+            av.getSelectionGroup().addSequence(sp.sequence, true);\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  public SequenceI findPoint(int x, int y)\r
+  {\r
+\r
+    int halfwidth = getSize().width / 2;\r
+    int halfheight = getSize().height / 2;\r
+\r
+    int found = -1;\r
+\r
+    for (int i = 0; i < npoint; i++)\r
+    {\r
+\r
+      SequencePoint sp = (SequencePoint) points.elementAt(i);\r
+      int px = (int) ((sp.coord[0] - centre[0]) * scale)\r
+              + halfwidth;\r
+      int py = (int) ((sp.coord[1] - centre[1]) * scale)\r
+              + halfheight;\r
+\r
+      if (Math.abs(px - x) < 3 && Math.abs(py - y) < 3)\r
+      {\r
+        found = i;\r
+      }\r
+    }\r
+    if (found != -1)\r
+    {\r
+      return ((SequencePoint) points.elementAt(found)).sequence;\r
+    }\r
+    else\r
+    {\r
+      return null;\r
+    }\r
+  }\r
+\r
+}\r