📄 abstractgroupstrategy.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 + -