/* * AlignmentPane.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.beauti.alignmentviewer; import javax.swing.*; import java.awt.*; /** * @author Andrew Rambaut * @version $Id: AlignmentPane.java,v 1.2 2005/11/11 16:40:41 rambaut Exp $ */ public class AlignmentPane extends JComponent implements Scrollable { private final TaxonPane taxonPane; private final RulerPane rulerPane; private AlignmentBuffer alignment = null; private int rowCount = 0; private int columnCount = 0; private int rowHeight = 0; private int columnWidth = 0; private int ascent = 0; private int col1 = 0; private int col2 = 0; private int row1 = 0; private int row2 = 0; private RowDecorator rowDecorator = null; private ColumnDecorator columnDecorator = null; private CellDecorator cellDecorator = null; public AlignmentPane(TaxonPane taxonPane, RulerPane rulerPane) { this.taxonPane = taxonPane; this.rulerPane = rulerPane; setFont( new Font("monospaced", Font.PLAIN, 12)); } public void setRowDecorator(RowDecorator rowDecorator) { this.rowDecorator = rowDecorator; } public void setColumnDecorator(ColumnDecorator columnDecorator) { this.columnDecorator = columnDecorator; } public void setCellDecorator(CellDecorator cellDecorator) { this.cellDecorator = cellDecorator; } public void setAlignmentBuffer(AlignmentBuffer alignment) { this.alignment = alignment; if (alignment != null) { rowCount = alignment.getSequenceCount(); columnCount = alignment.getSiteCount(); } else { rowCount = 0; columnCount = 0; } FontMetrics fm = getFontMetrics(getFont()); rowHeight = fm.getHeight(); columnWidth = fm.charWidth('M'); ascent = fm.getAscent(); if (taxonPane != null) { taxonPane.setRowHeight(rowHeight); } rulerPane.setColumnWidth(columnWidth); setPreferredSize(new Dimension(columnWidth * columnCount, rowHeight * rowCount)); invalidate(); } public Rectangle getVisibleArea() { return new Rectangle(col1, row1, col2 - col1 + 1, row2 - row1 + 1); } public void setTopRow(int row) { Rectangle rect = getVisibleRect(); rect.y = getTop(row); scrollRectToVisible(rect); } public void setLeftColumn(int col) { Rectangle rect = getVisibleRect(); rect.x = getLeft(col); scrollRectToVisible(rect); } public void setCentreColumn(int col) { Rectangle rect = getVisibleRect(); rect.x = Math.max(0, (getLeft(col) + getLeft(col) + columnWidth - rect.width) / 2); scrollRectToVisible(rect); } public void setRightColumn(int col) { Rectangle rect = getVisibleRect(); rect.x = Math.max(0, getLeft(col) + columnWidth - rect.width); scrollRectToVisible(rect); } public void paint(Graphics graphics) { if (alignment == null) return; Graphics2D g2 = (Graphics2D)graphics; String[] stateTable = alignment.getStateTable(); Rectangle bounds = g2.getClipBounds(); col1 = Math.min(getColumn(bounds.x), columnCount - 1); col2 = Math.min(getColumn(bounds.x + bounds.width), columnCount - 1); row1 = Math.min(getRow(bounds.y), rowCount - 1); row2 = Math.min(getRow(bounds.y + bounds.height), rowCount - 1); int x1 = getLeft(col1); int x2 = getLeft(col2 + 1); int y1 = getTop(row1); int y2 = getTop(row2 + 1); byte[] seq = new byte[columnCount]; int y = y1; if (rowDecorator != null) { for (int row = row1; row <= row2; row++) { Paint rowBackground = rowDecorator.getRowBackground(row); if (rowBackground != null) { g2.setPaint(rowBackground); Rectangle rect = new Rectangle(x1, y, x2 - x1, rowHeight); g2.fill(rect); } y += rowHeight; } } int x = x1; // if (columnDecorator != null) { // for (int col = col1; col <= col2; col++) { // Paint columnBackground = columnDecorator.getColumnBackground(col); // if (columnBackground != null) { // g2.setPaint(columnBackground); // Rectangle rect = new Rectangle(x, y1, columnWidth, y2 - y1); // g2.fill(rect); // } // x += columnWidth; // } // } y = y1; for (int row = row1; row <= row2; row++) { alignment.getStates(row, col1, col2, seq); if (cellDecorator != null) { x = x1; int i = 0; for (int col = col1; col <= col2; col++) { g2.setPaint(cellDecorator.getCellBackground(row, col, seq[i])); Rectangle rect = new Rectangle(x, y, x + columnWidth, y + rowHeight); g2.fill(rect); g2.setPaint(cellDecorator.getCellForeground(row, col, seq[i])); g2.drawString(stateTable[seq[i]], x, y + ascent); x += columnWidth; i++; } } else { g2.setPaint(Color.BLACK); x = x1; int i = 0; for (int col = col1; col <= col2; col++) { g2.drawString(stateTable[seq[i]], x, y + ascent); x += columnWidth; i++; } } y += rowHeight; } x = x1; if (columnDecorator != null) { for (int col = col1; col <= col2; col++) { Paint columnBackground = columnDecorator.getColumnBackground(col); if (columnBackground != null) { g2.setPaint(columnBackground); Rectangle rect = new Rectangle(x, y1, columnWidth, y2 - y1); g2.fill(rect); } x += columnWidth; } } } public int getColumn(int x) { return x / columnWidth; } public int getLeft(int column) { return column * columnWidth; } public int getColumnWidth() { return columnWidth; } public int getColumnCount() { return columnCount; } public int getRow(int y) { return y / rowHeight; } public int getTop(int row) { return row * rowHeight; } public int getRowHeight() { return rowHeight; } public int getRowCount() { return rowCount; } public Dimension getPreferredSize() { return new Dimension(columnWidth * columnCount, rowHeight * rowCount); } public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { if (orientation == SwingConstants.HORIZONTAL) { return columnWidth; } else { return rowHeight; } } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { if (orientation == SwingConstants.HORIZONTAL) { return columnWidth * 10; } else { return rowHeight * 10; } } public boolean getScrollableTracksViewportWidth() { return false; } public boolean getScrollableTracksViewportHeight() { return false; } }