package statalign.postprocess.gui.treeviews; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.ImageIcon; import javax.swing.JToggleButton; import statalign.postprocess.plugins.TreeNode; /** * The graphical interface for showing the current tree. * @author miklos, novak * * TODO: remove? */ public class VerticalPhylogramTreeView extends TreeView { private static final long serialVersionUID = 1L; @Override public JToggleButton getToolBarButton() { JToggleButton button = new JToggleButton(new ImageIcon( ClassLoader.getSystemResource("icons/vert.png"))); button.setToolTipText("Vertical tree view"); return button; } // Repaints the graphics. @Override public void paintComponent(Graphics gr) { if (root == null) { return; } //System.out.println("Updating tree"); Graphics2D g = (Graphics2D) gr.create(); g.setBackground(Color.WHITE); g.setFont(new Font("MONOSPACED", Font.PLAIN, 12)); g.setClip(0, 0, getParent().getWidth(), getParent().getHeight()); g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.BLACK); if (root == null) { // TODO: move to error handler. g.drawString("Waiting for data..", 30, 30); } else { root.countNameLengthSum(); double maxDepth = root.maxDepth() * 1.15; drawTree(g, root, maxDepth, 0, getWidth(), (int) (getHeight() * 0.05)); } } private void drawTree(Graphics g, TreeNode node, double maxDepth, int x1, int x2, int y) { if (node.isLeaf()) { String s = ((node.name.trim()).length() > 10 ? node.name.substring(0, 10) + "..." : node.name); g.drawString(s, (x1 + x2) / 2 - (s.indexOf(' ') == -1 ? s.length() : s.indexOf(' ')) * 4, y + 15); g.drawLine((x1 + x2) / 2, y, (x1 + x2) / 2, y - (int) (node.edgeLength * getHeight() / maxDepth)); } else { // HACK: TreeNode left = node.children.get(0); TreeNode right = node.children.get(1); int xmid = x1 + (x2 - x1) * left.nameLengthSum / (left.nameLengthSum + right.nameLengthSum); if (node.edgeLength > 0.0d) { g.drawLine(xmid, y, xmid, y - (int) (node.edgeLength * getHeight() / maxDepth)); } // Best code ever TreeNode leftleft = left.isLeaf() ? null : left.children.get(0); TreeNode leftright = left.isLeaf() ? null : left.children.get(1); TreeNode rightleft = right.isLeaf() ? null : right.children.get(0); TreeNode rightright = right.isLeaf() ? null : right.children.get(1); int xleft = (leftleft != null) ? x1 + (xmid - x1) * leftleft.nameLengthSum / (leftleft.nameLengthSum + leftright.nameLengthSum) : x1 + (xmid - x1) / 2; int xright = (rightleft != null) ? xmid + (x2 - xmid) * rightleft.nameLengthSum / (rightleft.nameLengthSum + rightright.nameLengthSum) : xmid + (x2 - xmid) / 2; g.drawLine(xleft, y, xright, y); drawTree(g, left, maxDepth, x1, xmid, y + (int) (left.edgeLength * getHeight() / maxDepth)); drawTree(g, right, maxDepth, xmid, x2, y + (int) (right.edgeLength * getHeight() / maxDepth)); } } // Gives the minimum size of the component @Override public Dimension getMinimumSize() { return getPreferredSize(); } // It gives the preferred size of the component @Override public Dimension getPreferredSize() { return new Dimension(0, 100); } }