package com.michaelbaranov.microba.marker.ui; import java.awt.Insets; import java.awt.Polygon; import java.awt.Rectangle; import javax.swing.SwingConstants; import javax.swing.plaf.ComponentUI; import com.michaelbaranov.microba.common.BoundedTableModel; import com.michaelbaranov.microba.marker.MarkerBar; public class MarkerBarUI extends ComponentUI { protected int MARKER_BODY_WIDTH = 12; protected int MARKER_BODY_HEIGHT = 12; protected int MARKER_BICK_HEIGHT = 6; protected int baselineLeft; protected int baselineTop; protected int baselineLength; protected Rectangle viewRect = new Rectangle(); protected Polygon[] polys = new Polygon[0]; protected Polygon[] calculateMarkerAreas(MarkerBar bar) { BoundedTableModel model = bar.getDataModel(); int count = model.getRowCount(); if (polys.length < count) { // grow shared polygon array polys = new Polygon[count * 2]; for (int i = 0; i < polys.length; i++) { int xx[] = new int[5]; int yy[] = new int[5]; Polygon p = new Polygon(xx, yy, 5); polys[i] = p; } } for (int i = 0; i < count; i++) { int intValueAt = ((Integer) model.getValueAt(i, bar .getPositionColumn())).intValue(); int logicalOffset = intValueAt - model.getLowerBound(); int baselineOffset = logicalOffsetToBaselineOffset(logicalOffset, model); int xx[] = polys[i].xpoints; int yy[] = polys[i].ypoints; if (bar.getOrientation() == SwingConstants.HORIZONTAL) { int x = baselineLeft + baselineOffset; if (bar.isFliped()) { xx[0] = x; yy[0] = baselineTop; xx[1] = x + MARKER_BODY_WIDTH / 2; yy[1] = baselineTop + MARKER_BICK_HEIGHT; xx[2] = x + MARKER_BODY_WIDTH / 2; yy[2] = baselineTop + MARKER_BICK_HEIGHT + MARKER_BODY_HEIGHT; xx[3] = x - MARKER_BODY_WIDTH / 2; yy[3] = baselineTop + MARKER_BICK_HEIGHT + MARKER_BODY_HEIGHT; xx[4] = x - MARKER_BODY_WIDTH / 2; yy[4] = baselineTop + MARKER_BICK_HEIGHT; } else { xx[0] = x; yy[0] = baselineTop; xx[1] = x + MARKER_BODY_WIDTH / 2; yy[1] = baselineTop - MARKER_BICK_HEIGHT; xx[2] = x + MARKER_BODY_WIDTH / 2; yy[2] = baselineTop - MARKER_BICK_HEIGHT - MARKER_BODY_HEIGHT; xx[3] = x - MARKER_BODY_WIDTH / 2; yy[3] = baselineTop - MARKER_BICK_HEIGHT - MARKER_BODY_HEIGHT; xx[4] = x - MARKER_BODY_WIDTH / 2; yy[4] = baselineTop - MARKER_BICK_HEIGHT; } } else { int y = baselineLeft + baselineOffset; if (bar.isFliped()) { xx[0] = baselineTop; yy[0] = y; yy[1] = y + MARKER_BODY_WIDTH / 2; xx[1] = baselineTop - MARKER_BICK_HEIGHT; yy[2] = y + MARKER_BODY_WIDTH / 2; xx[2] = baselineTop - MARKER_BICK_HEIGHT - MARKER_BODY_HEIGHT; yy[3] = y - MARKER_BODY_WIDTH / 2; xx[3] = baselineTop - MARKER_BICK_HEIGHT - MARKER_BODY_HEIGHT; yy[4] = y - MARKER_BODY_WIDTH / 2; xx[4] = baselineTop - MARKER_BICK_HEIGHT; } else { xx[0] = baselineTop; yy[0] = y; yy[1] = y + MARKER_BODY_WIDTH / 2; xx[1] = baselineTop + MARKER_BICK_HEIGHT; yy[2] = y + MARKER_BODY_WIDTH / 2; xx[2] = baselineTop + MARKER_BICK_HEIGHT + MARKER_BODY_HEIGHT; yy[3] = y - MARKER_BODY_WIDTH / 2; xx[3] = baselineTop + MARKER_BICK_HEIGHT + MARKER_BODY_HEIGHT; yy[4] = y - MARKER_BODY_WIDTH / 2; xx[4] = baselineTop + MARKER_BICK_HEIGHT; } } polys[i].invalidate(); } return polys; } protected int logicalOffsetToBaselineOffset(int logicalOffset, BoundedTableModel model) { int positionRange = model.getUpperBound() - model.getLowerBound(); return logicalOffset * baselineLength / positionRange; } protected int baselineOffsetToLogicalOffset(int baselineOffset, BoundedTableModel model) { int positionRange = model.getUpperBound() - model.getLowerBound(); return baselineOffset * positionRange / baselineLength; } protected int componentOffsetToLogicalOffset(int componentOffsetLeft, BoundedTableModel dataModel) { return baselineOffsetToLogicalOffset( componentOffsetLeft - baselineLeft, dataModel); } protected void calculateViewRectAndBaseline(MarkerBar bar) { Insets insets = bar.getInsets(); viewRect.x = insets.left; viewRect.y = insets.top; viewRect.width = bar.getWidth() - (insets.right + viewRect.x); viewRect.height = bar.getHeight() - (insets.bottom + viewRect.y); if (bar.getOrientation() == SwingConstants.HORIZONTAL) { baselineLeft = viewRect.x + MARKER_BODY_WIDTH / 2; baselineLength = viewRect.width - MARKER_BODY_WIDTH - 1; if (bar.isFliped()) { baselineTop = viewRect.y; } else { baselineTop = viewRect.y + viewRect.height - 1; } } else { baselineLeft = viewRect.y + MARKER_BODY_WIDTH / 2; baselineLength = viewRect.height - MARKER_BODY_WIDTH - 1; if (bar.isFliped()) { baselineTop = viewRect.x + viewRect.width - 1; } else { baselineTop = viewRect.x; } } } public int getMarkerSideGap() { return MARKER_BODY_WIDTH / 2; } }