⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractgroupstrategy.java

📁 Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI
💻 JAVA
字号:
/*--------------------------------------------------------------------------*
 | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas               |
 |                                                                          |
 | 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. A copy of the license has been included with   |
 | these distribution in the COPYING file, if not go to www.fsf.org         |
 |                                                                          |
 | As a special exception, you are granted the permissions to link this     |
 | program with every library, which license fulfills the Open Source       |
 | Definition as published by the Open Source Initiative (OSI).             |
 *--------------------------------------------------------------------------*/
package org.rapla.components.calendarview;

import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Collections;
import java.util.Collection;
import java.util.Comparator;

import org.rapla.components.util.SmallIntMap;

/** Arranges blocks into groups, and tries to place one group into one slot.
    The subclass must overide the group method to perform the grouping on a given
    list of blocks.
*/
public abstract class AbstractGroupStrategy implements BuildStrategy {
    boolean m_sortSlotsBySize;
    public static long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
    private boolean m_fixedSlots;
    private boolean m_conflictResolving;
    
   
    Comparator blockComparator = new Comparator() {
            public int compare(Object o1,Object o2) {
                Block b1 = (Block) o1;
                Block b2 = (Block) o2;
                int result = b1.getStart().compareTo(b2.getStart());
                if (result != 0)
                    return result;
                else
                    return -1 * b1.getEnd().compareTo(b2.getEnd());

            }
        };

    Comparator slotComparator = new Comparator() {
            public int compare(Object o1,Object o2) {
                List s1 = (List) o1;
                List s2 = (List) o2;
                if (s1.size() == 0 || s2.size() ==0) {
                    if (s1.size() == s2.size())
                        return 0;
                    else
                        return s1.size() < s2.size() ? -1 : 1;
                }

                Block b1 = (Block) s1.get(0);
                Block b2 = (Block) s2.get(0);
                return b1.getStart().compareTo(b2.getStart());
            }
        };

    public void build(CalendarView wv, List blocks)
    {
        SmallIntMap days = new SmallIntMap();
        Calendar calendar = Calendar.getInstance(wv.getTimeZone());
        Iterator it = blocks.iterator();
        long timespan = wv.getEndDate().getTime() - wv.getStartDate().getTime();
        // guess maxDays
        int maxDays = (int) (timespan / MILLISECONDS_PER_DAY + 2);
        while (it.hasNext()) {
            Block block = (Block) it.next();
            calendar.setTime(block.getStart());
            int day = calendar.get(Calendar.DAY_OF_YEAR)%maxDays;
            List list = (List) days.get(day);
            if (list == null) {
                list = new ArrayList();
                days.put(day,list);
            }
            list.add(block);
        }
        for (int day=0;day<maxDays;day++) {
            List list = (List) days.get(day);
            if (list == null)
                continue;
            insertDay( wv, list );
        }
    }

    private void insertDay(CalendarView wv, List blockList) {
        Iterator it = getSortedSlots(blockList).iterator();
        int slotCount= 0;
        while (it.hasNext()) {
            List col = (List) it.next();
            if (col == null) {
                continue;
            }
            for (int i=0;i<col.size();i++) {
                wv.addBlock((Block)col.get(i),slotCount);
            }
            slotCount ++;
        }
    }

    /** You can split the blockList into different groups.
     *  This method returns a collection of lists.
     *   Each list represents a group
      *  of blocks.       
      * @return a collection of List-objects
      * @see List
      * @see Collection
     */
    abstract protected Collection group(List blockList);

    public boolean isSortSlotsBySize() {
        return m_sortSlotsBySize;
    }

    public void setSortSlotsBySize(boolean enable) {
        m_sortSlotsBySize = enable;
    }

    /** takes a block list and returns a sorted slotList */
    protected List getSortedSlots(List blockList) {
        Collections.sort(blockList, blockComparator);
        ArrayList slots = new ArrayList(group(blockList));
        if ( isResolveConflictsEnabled()) {
        	resolveConflicts(slots);
        }
        if ( !isFixedSlotsEnabled() ) {
            mergeSlots(slots);
        }
        if (isSortSlotsBySize())
            Collections.sort(slots, slotComparator);
        return slots;
    }

    protected boolean isCollision(Object o1, Object o2) {
        Block b1 = (Block) o1;
        Block b2 = (Block) o2;
        boolean result = (b1.getStart().before(b2.getEnd()) && b2.getStart().before(b1.getEnd()));
        return result;
    }


    private void resolveConflicts(List groups) {
        int pos = 0;
        while (pos < groups.size()) {
            List group = (List) groups.get(pos++ );
            List newSlot = null;
            int i = 0;
            while (i< group.size()) {
                Object element1 = group.get( i++ );
                int j = i;
                while (j< group.size()) {
                    Object element2 = group.get( j ++);
                    if ( isCollision( element1, element2 ) ) {
                        group.remove( element2 );
                        j --;
                        if (newSlot == null) {
                            newSlot = new ArrayList();
                            groups.add(pos, newSlot);
                        }
                        newSlot.add( element2);
                    }
                }
            }
        }
    }

    /** the lists must be sorted */
    private boolean canMerge(List slot1,List slot2) {
        int size1 = slot1.size();
        int size2 = slot2.size();
        int i = 0;
        int j = 0;
        while (i<size1 && j < size2) {
            Block b1 = (Block) slot1.get(i);
            Block b2 = (Block) slot2.get(j);
            if (isCollision( b1, b2))
                return false;
            if ( b1.getStart().before( b2.getStart() ))
                i ++;
            else
                j ++;
        }
        return true;
    }

    /** merge two slots */
    private void mergeSlots(List slots) {
        // We use a (sub-optimal) greedy algorithm for merging slots
        int pos = 0;
        while (pos < slots.size()) {
            List slot1 = (List) slots.get(pos ++);
            for (int i= pos; i<slots.size(); i++) {
                List slot2 = (List) slots.get(i);
                if (canMerge(slot1, slot2)) {
                    slot1.addAll(slot2);
                    Collections.sort(slot1, blockComparator);
                    slots.remove(slot2);
                    pos --;
                    break;
                }
            }
        }
    }

    public void setFixedSlotsEnabled( boolean enable) {
        m_fixedSlots = enable;
    }
    
    public boolean isFixedSlotsEnabled() {
        return m_fixedSlots;
    }


    /** enables or disables conflict resolving. If turned on and 2 blocks ocupy the same slot,
     * a new slot will be inserted dynamicly
     * @param enable
     */
    public void setResolveConflictsEnabled( boolean enable) {
        m_conflictResolving = enable;
    }
    
    public boolean isResolveConflictsEnabled() {
        return m_conflictResolving;
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -