Package TimeTable

Source Code of TimeTable.TimeSpanInternal

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package TimeTable;

import TimeTable.model.TimeTableModel;
import TimeTable.model.TableModelListener;
import TimeTable.model.TimeTableModelDefault;
import TimeTable.relocators.RelocationEngine;
import TimeTable.relocators.SimpleRectangleEngine;
import TimeTable.relocators.SpanRelocationInfo;
import TimeTable.spans.SpanException;
import TimeTable.spans.TimeSpan;
import TimeTable.scaler.TimeScaler;
import TimeTable.scaler.TimeScalerFlat;
import TimeTable.scaler.TimeScalerListener;
import TimeTable.spans.TimeSpanListener;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.JComponent;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Collections;
import java.util.Date;





/**
* Главный элемент управления
* @author Axe Ilshat
*/
public class JTimeTable extends JComponent
        implements TimeSpanListener, TableModelListener, TimeScalerListener {

    private ArrayList<TimeSpanInternal> spans = new ArrayList<TimeSpanInternal>();

    protected static final int TTE_RESIZE = 1;
    protected static final int TTE_MOVE = 2;
    protected static final int TTE_OVER = 3;
    protected static final int TTE_MOUSELEFT = 4;
    protected static final int TTE_MOUSEENTER = 5;
    protected static final int TTE_ACTIVATE = 6;
    protected static final int TTE_CONTEXTMENU = 7;
    protected static final int TTE_SPANMENU = 8;
   
    private Dimension preferredSize =new Dimension(100, 300);

    private Day day;
           
    private TimeSpan mouseOverSpan;
    private boolean canExceed24 = false;
    private RelocationEngine relocator;
    private TimeTableModel model;
    private TimeScaler scaler;
    boolean recalcLayout = true;
    boolean rebuildInternal = true;
    private int shiftBegin;
    private int shiftEnd;
    private GenericMouseEventsListener genericMouseEventsListener = new GenericMouseEventsListener();
    private ReadOnlyMouseListener readOnlyMouseListener = new ReadOnlyMouseListener();
    private boolean readOnly;
   
    static AlphaComposite readOnlyBlend = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.15f);
    static AlphaComposite disabledBlend = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f);
   
    public JTimeTable() {
        this(new Day(2007, 0, 1));
    }
   
    public JTimeTable(Day day) {
        this(day, new SimpleRectangleEngine(), new TimeScalerFlat());
    }
   
    /**
     *
     * @param relocator
     * @param scaler
     */
    public JTimeTable(Day day, RelocationEngine relocator, TimeScaler scaler) {
        this(day, new TimeTableModelDefault(), relocator, scaler);
    }
   
    /**
     * Создает новый объект
     * @param relocator - релокатор
     * @param model - модель
     * @param scaler - скалер
     */
    public JTimeTable(Day day, TimeTableModel model, RelocationEngine relocator, TimeScaler scaler) {
        this.day = day;
        this.scaler = scaler;
        scaler.addTimeScalerListener(this);
        this.relocator = relocator;
        addComponentListener(new ComponentListenerInt());
        updateListeners();
        setModel(model);
    }

    /**
     *
     * @param model
     */
    public void setModel(TimeTableModel model) {
        if (this.model != null) {
            this.model.removeTimeModelListener(this);
        }
        this.model = model;
        model.addTimeModelListener(this);
        rebuildInternal = true;
        rebuildInternalSpans();

        recalcLayout = true;
        repaint();
    }
   
    public void setScaler(TimeScaler scaler) {
        if(this.scaler != null) {
            this.scaler.removeTimeScalerListener(this);
        }
        this.scaler = scaler;
        recalcLayout = true;
        scaler.setMaxPoint(getHeight());
        scaler.addTimeScalerListener(this);
        repaint();
    }

    @Override
    public void setEnabled(boolean enable) {
        super.setEnabled(enable);
        updateListeners();
        repaint();
    }
   
    private void updateListeners() {
        if(!isEnabled()) {
            removeMouseListener(genericMouseEventsListener);
            removeMouseListener(readOnlyMouseListener);
            removeMouseMotionListener(genericMouseEventsListener);
            removeMouseMotionListener(readOnlyMouseListener);
        } else if(!isReadOnly()) {
            removeMouseMotionListener(readOnlyMouseListener);
            removeMouseListener(readOnlyMouseListener);
           
            removeMouseListener(genericMouseEventsListener);
            removeMouseMotionListener(genericMouseEventsListener);
            addMouseListener(genericMouseEventsListener);
            addMouseMotionListener(genericMouseEventsListener);
        } else {
            removeMouseListener(genericMouseEventsListener);
            removeMouseMotionListener(genericMouseEventsListener);
           
            removeMouseMotionListener(readOnlyMouseListener);
            removeMouseListener(readOnlyMouseListener);
            addMouseMotionListener(readOnlyMouseListener);
            addMouseListener(readOnlyMouseListener);
        }
    }

    /**
     * Setups day for time table
     * @param year
     * @param month
     * @param day
     */
    public void setDay(Day day) {
        this.day = day;
    }

    /**
     *
     * @return
     */
    public final Day getDay() {
        return day;
    }

    /**
     *
     * @return
     */
    @Override
    public Dimension getPreferredSize() {
        return getMinimumSize();
    }

    /**
     *
     * @return
     */
    @Override
    public Dimension getMaximumSize() {
        return preferredSize;
    }

    /**
     *
     * @return
     */
    @Override
    public Dimension getMinimumSize() {
        return new Dimension(100, 300);
    }

    /**
     * Setups new relocator engine
     * @param relocator
     */
    public void setRelocator(RelocationEngine relocator) {
        this.relocator = relocator;
    }

    /**
     * Paints component
     * @param g
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Insets insets = getInsets();
        int currentWidth = getWidth() - insets.left - insets.right;
        int currentHeight = getHeight() - insets.top - insets.bottom;
        Graphics2D g2d = (Graphics2D) g.create();

        //antialias on
        RenderingHints rh = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHints(rh);

        rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHints(rh);

        //erase bg
        if(shiftBegin != 0 && shiftEnd != 0) {
            g2d.setColor(Color.white);
            g2d.fillRect(insets.left, insets.top, currentWidth, currentHeight);

            //SHIFTS
            g2d.setColor(Color.GRAY);
            int shiftY = scaler.getPosAtTime(shiftBegin);
            if(shiftY > 0) {
                g2d.fillRect(insets.left, insets.top, currentWidth, shiftY);
            }
            shiftY = scaler.getPosAtTime(shiftEnd);
            if(shiftY > 0) {
                g2d.fillRect(insets.left, shiftY, currentWidth, currentHeight-shiftY);
            }
        } else {
            g2d.setColor(Color.GRAY);
            g2d.fillRect(insets.left, insets.top, currentWidth, currentHeight);
        }
       
        //draw grid and rules
        g2d.setColor(Color.LIGHT_GRAY);
        g2d.drawRect(insets.left, insets.top, currentWidth, currentHeight);
        int iHours = 1;
        while (iHours < 24) {
            int y2 = scaler.getPosAtTime(iHours * 3600 * 1000);
            g2d.drawLine(insets.left, y2, currentWidth + insets.left, y2);
            iHours++;
        }

        Rectangle rc = new Rectangle(insets.left, insets.top, currentWidth, currentHeight);
        if (recalcLayout) {
            rebuildInternalSpans();
            recalcLayout = false;
        }

        //SPANS
        Rectangle activeRC = null;
        for (TimeSpanInternal s : spans) {
            if (s.visible) {
                if (mouseOverSpan != s.span) {
                    s.span.paint(g2d, false, s.rc);
                } else {
                    activeRC = s.rc;
                }
            }
        }
        if (mouseOverSpan != null && activeRC != null) {
            mouseOverSpan.paint(g2d, true, activeRC);
        }
       
        if(!isEnabled()){
            g2d.setComposite(disabledBlend);           
            g2d.setColor(Color.BLACK);
            g2d.fillRect(insets.left, insets.top, currentWidth, currentHeight);
        }       
        //READ ONLY
        else if(isReadOnly()) {
            g2d.setComposite(readOnlyBlend);           
            g2d.setColor(Color.BLACK);
            g2d.fillRect(insets.left, insets.top, currentWidth, currentHeight);
        }       

        g2d.dispose();
    }

    /**
     *
     */
    public void relocateSpans() {
        ArrayList<TimeSpanInternal> info = new ArrayList<TimeSpanInternal>();
        long beginTime = day.getMilliseconds();
        long endTime = beginTime + 24*3600*1000;
       
        // Y coord
        for (int i = 0; i < spans.size(); i++) {
            TimeSpanInternal s = spans.get(i);
            TimeSpan ts = s.span;
            long spanBegin = ts.getBegin().getTime();
            long spanEnd = spanBegin + ts.getLength()*60*1000;
           
            //pass hidden
            if (spanBegin >= endTime || spanEnd <= beginTime) {
                s.visible = false;
                continue;
            }
           
            if (s.relocateY) {
                int begin = (int) (spanBegin - beginTime);
                int end = (int) (spanEnd - beginTime);
               
                s.rc.y = scaler.getPosAtTime(begin);
                s.rc.height = scaler.getPosAtTime(end) - s.rc.y;
                s.relocateY = false;
            }
            info.add(s);
            s.visible = true;
        }
       
        //System.out.println("Relocate Y " + day + "  size: " + info.size());

        if (info.size() > 0) {
            SpanRelocationInfo[] out = new SpanRelocationInfo[info.size()];
            for (int i = 0; i < info.size(); i++) {
                TimeSpanInternal s = info.get(i);
                out[i] = new SpanRelocationInfo();
                out[i].begin = s.span.getBegin().getTime();
                out[i].duration = s.span.getLength()*60*1000;
            }
            Insets insets = getInsets();
            int currentWidth = getWidth() - insets.left - insets.right;

            relocator.updateTimeSpanPositions(out, insets.left, currentWidth);
            for (int i = 0; i < out.length; i++) {
                TimeSpanInternal s = info.get(i);
                s.rc.x = out[i].x;
                s.rc.width = out[i].width;
            }
        }
    }

    /**
     *
     */
    private void rebuildInternalSpans() {
        if (rebuildInternal) {
            for (int i = 0; i < spans.size(); i++) {
                spans.get(i).span.removeTimeSpanListener(this);
            }
            spans.clear();

            for (int i = 0; i < model.getSpanCount(); i++) {
                TimeSpan span = model.getSpan(i);
                TimeSpanInternal internal = new TimeSpanInternal();
                internal.span = span;
                internal.rc = new Rectangle();
                internal.relocateY = true;
                spans.add(internal);
                span.addTimeSpanListener(this);
                System.out.println("rebuild content: item added at " + span.getBegin()
                        + ", length " + span.getLength() + " LOADED");
            }
            rebuildInternal = false;
            System.out.println("rebuild content finished: " + model.getSpanCount() + " LOADED");
        }

        Collections.sort(spans);
        relocateSpans();
    }

    /**
     * Post custom event to avery listener
     * @param type - event type
     * @param span - event subject
     */
    private void fireEvent(int type, TimeSpan span, int x, int y) {
        switch (type) {
            case TTE_RESIZE: {
                model.spanResized(span, this);
                break;
            }
            case TTE_MOVE: {
                model.spanMoved(span, this);
                break;
            }
            case TTE_OVER: {
                model.mouseOverSpan(span, this);
                break;
            }
            case TTE_MOUSELEFT: {
                model.mouseLeftSpan(span, this);
                break;
            }
            case TTE_MOUSEENTER: {
                model.mouseEnterSpan(span, this);
                break;
            }
            case TTE_ACTIVATE: {
                model.spanActivated(span, this);
                break;
            }
            case TTE_CONTEXTMENU: {
                model.contextMenu(this, x, y);
                break;
            }
            case TTE_SPANMENU: {
                model.spanContextMenu(span, this, x, y);
                break;
            }
        }
    }

    public boolean isCanExceed24() {
        return canExceed24;
    }

    public void setCanExceed24(boolean canExceed24) {
        this.canExceed24 = canExceed24;
    }

   
    /**
     * Возвращает время начала смены.
     * Время до начала смены и после конца смены закрашивается серым цветом
     * @return миллисекунды с начала суток
     */
    public int getShiftBegin() {
        return shiftBegin;
    }

    /**
     * Задает время начала смены.
     * Время до начала смены и после конца смены закрашивается серым цветом
     * @param shiftBegin - миллисекунды с начала суток
     */
    public void setShiftBegin(int shiftBegin) {
        this.shiftBegin = shiftBegin;
    }

    /**
     * Возвращает время конца смены.
     * Время до начала смены и после конца смены закрашивается серым цветом
     * @return миллисекунды с начала суток
     */
    public int getShiftEnd() {
        return shiftEnd;
    }

    /**
     * Задает время конца смены.
     * Время до начала смены и после конца смены закрашивается серым цветом
     * @param shiftBegin миллисекунды с начала суток
     */
    public void setShiftEnd(int shiftEnd) {
        this.shiftEnd = shiftEnd;
    }

    /**
     * Является ли элемент только для чтения
     * @return
     */
    public boolean isReadOnly() {
        return readOnly;
    }

    /**
     * Устанаваливает состояние элемента в "только для чтения" или "чтения-записи"
     * @param readOnly
     */
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
        updateListeners();
    }
   
    /**
     * возвращает количество миллисекунд, прошедших с начала суток для
     * координаты y
     * @param y координата в пикселях
     */
    public int getTimeAt(int y) {
        return scaler.getTimeAtPos(y);
    }

    /**
     * Helper class
     */
    private class ComponentListenerInt implements ComponentListener {

        public void componentResized(ComponentEvent e) {
            Insets insets = getInsets();
            int currentHeight = getHeight() - insets.top - insets.bottom;
            scaler.setMaxPoint(currentHeight);
           
            preferredSize.height = scaler.getMinHeight();
           
            for (int i = 0; i < spans.size(); i++) {
                TimeSpanInternal timeSpanInternal = spans.get(i);
                timeSpanInternal.relocateY = true;
            }
           
            relocateSpans();
            repaint();
        }

        public void componentMoved(ComponentEvent e) {}
        public void componentShown(ComponentEvent e) {}
        public void componentHidden(ComponentEvent e) {        }
    } // end of ComponentListener

   

    /**
     * Helper class
     * Processes mouse input events
     */
    private class GenericMouseEventsListener implements MouseListener, MouseMotionListener {

        TimeSpan spanDragged;
        TimeSpan spanResizedTop;
        TimeSpan spanResizedBottom;
        int dragOffsetY;

        /**
         * @param event
         */
        public void mouseEntered(MouseEvent event) {
        }

        /**
         * @param event
         */
        public void mouseExited(MouseEvent event) {
            if (spanDragged == null) {
                if (mouseOverSpan != null) {
                    fireMouseEvents(mouseOverSpan, null, event.getX(), event.getY());
                    mouseOverSpan = null;
                    repaint();
                }
            }
        }

        /**
         *
         * @param event
         */
        public void mouseClicked(MouseEvent event) {
            if(!event.isPopupTrigger()) {
                if (event.getClickCount() == 2 && mouseOverSpan != null) {
                    fireEvent(TTE_ACTIVATE, mouseOverSpan, event.getX(), event.getY());
                }                      
            }
        }

        private boolean mouseContext(MouseEvent event) {
            if (event.isPopupTrigger()) {
                System.out.println("Mouse context ");
                if (mouseOverSpan != null) {
                    fireEvent(TTE_SPANMENU, mouseOverSpan, event.getX(), event.getY());
                } else {
                    fireEvent(TTE_CONTEXTMENU, mouseOverSpan, event.getX(), event.getY());
                }
                return true;
            }
            return false;
        }
        /**
         *
         * @param event
         */
        public void mouseReleased(MouseEvent event) {
            if(!mouseContext(event)) {
                if (spanDragged != null) {
                    fireEvent(TTE_MOVE, spanDragged, event.getX(), event.getY());
                    spanDragged = null;
                    repaint();
                } else if (spanResizedBottom != null) {
                    fireEvent(TTE_RESIZE, spanResizedBottom, event.getX(), event.getY());
                    spanResizedBottom = null;
                    repaint();
                } else if (spanResizedTop != null) {
                    fireEvent(TTE_RESIZE, spanResizedTop, event.getX(), event.getY());
                    spanResizedTop = null;
                    repaint();
                }
            }
        }

        public void mousePressed(MouseEvent event) {
            if(mouseContext(event)) {
                return;
            }
            Point pt = event.getPoint();
            //System.out.println("Mouse pressed: " + pt.x + "," + pt.y);
            for (int i = spans.size() - 1; i >= 0; i--) {
                TimeSpanInternal si = spans.get(i);
                TimeSpan span = si.span;

                int resize = span.checkPointResize(pt, si.rc);
                if (resize != TimeSpan.NORESIZE) {
                    if (resize == TimeSpan.RESIZE_TOP) {
                        spanResizedTop = span;
                        spanResizedBottom = null;
                    } else if (resize == TimeSpan.RESIZE_BOTTOM) {
                        spanResizedTop = null;
                        spanResizedBottom = span;
                    }
                    break;
                } else if (span.checkOverDragArea(pt, si.rc)) {
                    //System.out.println("Drag on: " + pt.x + "," + pt.y);
                    spanDragged = span;
                    dragOffsetY = si.rc.y - pt.y;
                    break;
                }
            }
        }

        /**
         *
         * @param event
         */
        public void mouseDragged(MouseEvent event) {
            Point pt = event.getPoint();
            Insets insets = getInsets();
            if (spanDragged != null) {
                pt.y += dragOffsetY;
                long time = day.getMilliseconds() + scaler.getTimeAtPos(pt.y - insets.top);
                if (!isCanExceed24()) {
                    long maxTime = day.getMilliseconds() + 24*3600*1000 - (spanDragged.getLength()*60*1000);
                    if (time > maxTime) {
                        time = maxTime;
                    }
                    if (time < day.getMilliseconds()) {
                        time = day.getMilliseconds();
                    }
                }
                time = granulateTime(time, spanDragged.getTimeGranulation());
                spanDragged.setBegin(new Date(time));
                repaint();

            } else if (spanResizedTop != null) {
                long time = day.getMilliseconds() + scaler.getTimeAtPos(pt.y - insets.top);
                if (!isCanExceed24()) {
                    if (time < day.getMilliseconds()) {
                        time = day.getMilliseconds();
                    }
                }
                time = granulateTime(time, spanResizedTop.getTimeGranulation());
               
                try {
                    spanResizedTop.resizeBegin(new Date(time));
                } catch (SpanException ex) {
                    ex.showError(JTimeTable.this);
                    spanResizedTop = null;
                }
                repaint();
               
            } else if (spanResizedBottom != null) {
                long time = day.getMilliseconds() + scaler.getTimeAtPos(pt.y - insets.top);
                if (!isCanExceed24()) {
                    long maxTime = day.getMilliseconds() + 24*3600*1000;
                    if (time > maxTime) {
                        time = maxTime;
                    }
                }
                time = granulateTime(time, spanResizedBottom.getTimeGranulation());
                try {
                    spanResizedBottom.resizeEnd(new Date(time));
                } catch (SpanException ex) {
                    ex.showError(JTimeTable.this);
                    spanResizedBottom = null;
                }
                repaint();
            }
        }

        /**
         * granulates time
         * @param time
         * @return
         */
        protected long granulateTime(long time, int granulation) {
            int f = granulation * 30000;
            long granulated = ((time + f / 2) / f);
            return granulated * f;
        }

        /**
         *
         * @param event
         */
        public void mouseMoved(MouseEvent event) {
            if (spanDragged != null) {
                return;
            }

            Point pt = event.getPoint();
            TimeSpan last = mouseOverSpan;
            mouseOverSpan = null;
            //find active timespan
            for (int i = spans.size() - 1; i >= 0; i--) {
                TimeSpanInternal si = spans.get(i);
                if (!si.visible) {
                    continue;
                }

                TimeSpan span = si.span;
                int resize = span.checkPointResize(pt, si.rc);
                if (resize != TimeSpan.NORESIZE) {
                    if (resize == TimeSpan.RESIZE_TOP) {
                        mouseOverSpan = span;
                        setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
                    } else if (resize == TimeSpan.RESIZE_BOTTOM) {
                        mouseOverSpan = span;
                        setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
                    }
                    break;

                } else if (span.checkOverDragArea(pt, si.rc)) {
                    mouseOverSpan = span;
                    setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                    break;

                } else {
                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
            }
            //events handling
            fireMouseEvents(last, mouseOverSpan, event.getX(), event.getY());
            if (last != mouseOverSpan) {
                repaint();
            }
        }

        /**
         * Post LEFT and ENTER events to listeners
         * @param oldOver - prevouse mouse over span
         * @param currentOver - current mouse over span
         * @param x - x mouse cursor pos
         * @param y - y mouse cursor pos
         */
        protected void fireMouseEvents(TimeSpan oldOver, TimeSpan currentOver, int x, int y) {
            if (oldOver != currentOver) {
                if (oldOver != null) {
                    fireEvent(TTE_MOUSELEFT, oldOver, x, y);
                }
                if (currentOver != null) {
                    fireEvent(TTE_MOUSEENTER, currentOver, x, y);
                }
            }
        }
    } // end of mouseHandling  
   
    class ReadOnlyMouseListener implements MouseMotionListener, MouseListener {

        public void mouseDragged(MouseEvent arg0) {}

        public void mouseMoved(MouseEvent event) {
            Point pt = event.getPoint();
            TimeSpan last = mouseOverSpan;
            mouseOverSpan = null;
            //find active timespan
            for (int i = spans.size() - 1; i >= 0; i--) {
                TimeSpanInternal si = spans.get(i);
                if (!si.visible) {
                    continue;
                }

                TimeSpan span = si.span;
                if (span.checkOverDragArea(pt, si.rc)) {
                    mouseOverSpan = span;
                    setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                    break;

                } else {
                    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
            }
            if (last != mouseOverSpan) {
                repaint();
            }
        }

        public void mouseClicked(MouseEvent arg0) {}
        public void mousePressed(MouseEvent arg0) {}
        public void mouseReleased(MouseEvent arg0) {}
        public void mouseEntered(MouseEvent arg0) {}

        public void mouseExited(MouseEvent arg0) {
            if (mouseOverSpan != null) {
                mouseOverSpan = null;
                repaint();
            }
        }
    }
   
    /**
     * Вызывается спаном, если у него изменилось время начала или конца.
     * Устанавливает флаг необходимости перерасчета позиции спанов.
     * @param span
     */
    public void timeSpanChanged(TimeSpan span) {
        for (int i = 0; i < spans.size(); i++) {
            TimeSpanInternal si = spans.get(i);
            if (span == si.span) {
                si.relocateY = true;
            }
        }
        recalcLayout = true;
        repaint();
    }

    /**
     * Вызывается спаном, если у него изменилось время начала или конца.
     * Устанавливает флаг необходимости перерасчета
     */
    public void spanCountChanged() {
        recalcLayout = true;
        rebuildInternal = true;
        repaint();
    }

    public void scaleChanged() {
        recalcLayout = true;
        for (int i = 0; i < spans.size(); i++) {
            spans.get(i).relocateY = true;
        }
        repaint();
    }
}
/**
* Класс используется для того что бы хранить ссылки на
* объекты-спаны внтури элемента управления.
* Кроме всего прочего хранят информацию о том, видим ли
* спан, его размеры и необходим ли перерасчет его позиции
* по оси У
* @author Axe Ilshat
*/
class TimeSpanInternal implements Comparable<TimeSpanInternal> {

    public TimeSpan span;
    public Rectangle rc;
    public boolean visible;
    public boolean relocateY;

    /**
     * Comparator. Need for sorting.
     * @param o
     * @return
     */
    public int compareTo(TimeSpanInternal o) {
        if (span.getBegin().equals(o.span.getBegin())) {
            return 0;
        }
        return span.getBegin().after(o.span.getBegin()) ? 1 : -1;
    }
}



TOP

Related Classes of TimeTable.TimeSpanInternal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.