/*
* ConcreteSplitViewer program for analazing splits.
* Copyright (C) 2006-2007 Mytinski Leonid (Leonid.Mytinski@gmail.com)
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* LapsTopPanel.java
*
* Created on 22 Май 2007 г., 21:31
*/
package ru.concretesoft.concretesplitviewer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.GeneralPath;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
/**
*
* @author Mytinski Leonid
*
* Panel show all laps as bricks with same heigths and length relate to size of lap. Color of filling brick means selected or not it lap.
*/
public class LapsTopPanel extends javax.swing.JPanel implements ListDataListener,MouseListener,XCoordinatesListener{
private AthleteListModel model;
private int[] xCoord;
private boolean[] selected;
private SplitViewer splitViewer;
private int yOtst = 10;
/** Creates new form LapsTopPanel */
private LapsTopPanel() {
}
public LapsTopPanel(AthleteListModel model, SplitViewer splitViewer) {
setModel(model);
xCoord = null;
this.addMouseListener(this);
setSplitViewer(splitViewer);
}
@Override
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Dimension d = getSize();
double width = d.getWidth();
double height = d.getHeight();
g2.setPaint(Color.WHITE);
g2.fillRect(0, 0, (int) width, (int) height);
Distance distance = model.getDistance();
if((model!=null)&&(distance!=null)){
//determin shift from left side (same way that in SplitViewer)
int otst;
FontMetrics fM = g2.getFontMetrics();
otst = fM.stringWidth("-000:00")+5;
//Determin scale (pixels/meters)
int allLength = Tools.calculateTotalLength(distance);
double scale = (width-otst) / allLength;
int nOfCp = distance.getNumberOfCP();
xCoord = new int[nOfCp+1];
int[] xCoordFromViewer = splitViewer.getXCoordinatesOfLaps();
//Creating boolean array of selected laps
selected = new boolean[nOfCp];
for(boolean b:selected){
b=false;
}
int[] viewSplits = model.getViewingSplits();
for(int i: viewSplits){
selected[i-1]=true;
}
int curX = otst;
xCoord[0]=curX;
yOtst = (int)(height/2);
//if x coordiantes of laps in SplitViewer are known and
//numbers of viewing splits and x coordinates are same then draw
if((xCoordFromViewer!=null)&&(xCoordFromViewer.length==viewSplits.length)){
//set anti-alialiasing on
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int lastView=0;
for(int i = 1; i < nOfCp+1; i++){
//size of lap in pixels
double w = distance.getLengthOfDist(i)*scale;
curX=curX+(int)w;//right side of lap
xCoord[i]=curX;
//Create two GeneralPaths for top(vertical sides) and bottom(connection zone) parts of lap
GeneralPath pathTop = new GeneralPath();
GeneralPath pathBottom = new GeneralPath();
//Top Path
pathTop.moveTo(xCoord[i-1],yOtst);
pathTop.lineTo(xCoord[i-1],0);
pathTop.lineTo(xCoord[i],0);
pathTop.lineTo(xCoord[i],yOtst);
//Fill top path green if selected else red
if(selected[i-1])
g2.setPaint(Color.GREEN);
else
g2.setPaint(Color.RED);
g2.fill(pathTop);
//draw sides of lap
g2.setStroke(new BasicStroke(1.0f));
g2.setPaint(Color.BLACK);
g2.draw(pathTop);
//Bottom path
pathBottom.moveTo(xCoord[i],yOtst);
if(lastView < viewSplits.length){
if(viewSplits[lastView]>i){
int x = (lastView>0)?xCoordFromViewer[lastView-1]:xCoord[0];
pathBottom.lineTo(x,(float)height);
}else if(viewSplits[lastView]==i){
pathBottom.lineTo(xCoordFromViewer[lastView],(float)height);
int x = (lastView>0)?xCoordFromViewer[lastView-1]:xCoord[0];
pathBottom.lineTo(x,(float)height);
lastView++;
}else;
}else{
pathBottom.lineTo(xCoordFromViewer[xCoordFromViewer.length-1],(float)height);
}
pathBottom.lineTo(xCoord[i-1],yOtst);
//Fill bottom path
GradientPaint greenToWhite = new GradientPaint(xCoord[0],yOtst,Color.GREEN,xCoord[0],(int)height,Color.WHITE);
if(selected[i-1])
g2.setPaint(greenToWhite);
else
g2.setPaint(Color.RED);
g2.fill(pathBottom);
//draw connection lines
float dash1[] = {1.0f};
BasicStroke dashed = new BasicStroke(0.5f,
java.awt.BasicStroke.CAP_BUTT,
java.awt.BasicStroke.JOIN_MITER,
10.0f, dash1, 0.0f);
g2.setStroke(dashed);
g2.setPaint(Color.BLACK);
g2.draw(pathBottom);
}
}else;
}else;
}
/** Sets model
*
* @param a <code>AthleteListModel</code> model
*/
public void setModel(AthleteListModel a){
model = a;
model.addListDataListener(this);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.BorderLayout());
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
public void intervalAdded(ListDataEvent e) {
}
public void intervalRemoved(ListDataEvent e) {
}
public void contentsChanged(ListDataEvent e) {
repaint();
}
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if((xCoord[0]<x)&&(y<yOtst)){//If click was made in area with laps and vertical dividers
//find on which lap was made click
for(int i=1;i<xCoord.length;i++){
if(xCoord[i]>x){
if(selected[i-1])
model.removeSplitsForN(i);
else
model.addSplitsForN(i);
break;
}else;
}
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public SplitViewer getSplitViewer() {
return splitViewer;
}
public void setSplitViewer(SplitViewer splitViewer) {
//remove listener from previous SplitViewer
if(this.splitViewer!=null){
this.splitViewer.removeXCoordinatesListener(this);
}
//set new SplitViewer and add on it listener
this.splitViewer = splitViewer;
this.splitViewer.addXCoordinatesListener(this);
}
public void xCoordinatesChanged(SplitViewer source) {
repaint();
}
}