home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-08-14 | 12.0 KB | 557 lines |
- package como.commlet.scheduler;
-
- import java.awt.*;
- import java.util.*;
- import java.io.*;
-
- import como.sys.*;
- import como.util.*;
- import como.awt.*;
- import como.commlet.*;
- import como.commlet.*;
- import como.commlet.chat.*;
- import como.commlet.userlist.*;
-
- public class Scheduler extends MetaCommlet
- {
- MenuItem miclear;
- MenuItem misuggest;
- MenuItem miallok;
- MenuItem miallno;
- Board board = null;
- TextField statusfield;
- static final int MSG_NEW_SCHEDULE = 13045;
- static final int MSG_NEW_SCHEDULE_PART = 13046;
- static final int MSG_NEW_SCHEDULE_ROW = 13047;
- static final int MSG_NEW_SCHEDULE_COL = 13048;
- UserSchedule myschedule;
- Hashtable schedules;
-
- public Scheduler() {
- return;
- }
-
- public String getCommletName()
- {
- return "Scheduler Commlet, V1.0, (c) Jan Kautz & Ulrich Gall";
- }
-
- public String getCommletInfo()
- {
- return
- "(c) 1996 Ulrich Gall & Jan Kautz\n"+
- "\n";
- }
-
- public void init()
- {
- super.init();
-
- Chat c = new Chat();
- addCommlet(c,"Chat");
-
- UserList ul = new UserList();
- addCommlet(ul,"Users");
-
- Menu men= new Menu("Scheduler");
-
-
- miclear = new MenuItem("Clear");
- miallok = new MenuItem("Set all: OK");
- miallno = new MenuItem("Set all: No");
- misuggest = new MenuItem("Suggest date (see Chat)");
-
- men.add(miclear);
- men.add(miallok);
- men.add(miallno);
- men.add(misuggest);
- getMenuBar().add(men);
-
- statusfield = new TextField();
- statusfield.setEditable( false );
-
- board = new Board( UserSchedule.WEEK_DAYS, UserSchedule.MIN_HOUR, UserSchedule.MAX_HOUR );
-
- add("Center",board);
- add("South",statusfield);
- pack();
-
- schedules = new Hashtable();
- }
-
- public void addUser(int id)
- {
- status(com.getUserName(id) + " has joined.");
-
- UserSchedule s = new UserSchedule();
-
- if( id == com.getMyID() ) {
- myschedule = s;
- }
- else {
- com.sendTo( new Msg( MSG_NEW_SCHEDULE, id, myschedule ) );
- }
-
- schedules.put( new Integer(id), s );
- }
-
- public void userLeft(int id)
- {
- schedules.remove(new Integer(id));
- status(com.getUserName(id) + " has left.");
-
- recalculateAll();
- }
-
- public void stop()
- {
- super.stop();
- }
-
- void status(String s)
- {
- statusfield.setText(s);
- }
-
- public boolean handleMsg(Msg msg)
- {
- if( msg.type == Msg.NEW_USER_INFO ) {
- User olduser = (User)msg.arg;
- status( "User "+olduser.getName()+" is now known as "+com.getUserName(msg.from) );
- }
-
- if( msg.type == MSG_NEW_SCHEDULE ) {
- if( msg.from == com.getMyID() ) return true; // This can't happen...
-
- if( msg.arg == null )
- {
- Debug.msg( 30, "Scheduler().handleMsg(): NEW_SCHEDULE: no schedule sent!" );
- return true;
- }
-
- schedules.put(new Integer(msg.from), (UserSchedule)msg.arg );
- recalculateAll();
-
- return true;
- }
-
- if( msg.type == MSG_NEW_SCHEDULE_ROW || msg.type == MSG_NEW_SCHEDULE_COL ) {
- int array[];
-
- array = (int[])msg.arg;
-
- UserSchedule s = (UserSchedule)schedules.get( new Integer(msg.from) );
-
- if( s != null )
- {
- if( msg.type == MSG_NEW_SCHEDULE_COL )
- {
- s.setCol( array[0], (byte)array[1] );
- recalculateCol( array[0] );
- }
- else
- {
- s.setRow( array[0], (byte)array[1] );
- recalculateRow( array[0] );
- }
- }
-
- return true;
- }
- if( msg.type == MSG_NEW_SCHEDULE_PART ) {
- int array[];
-
- array = (int[])msg.arg;
-
- UserSchedule s = (UserSchedule)schedules.get( new Integer(msg.from) );
-
- if( s != null )
- {
- s.set( array[0], array[1], (byte)array[2] );
- recalculateSumAndMe( array[0], array[1] );
- }
-
- return true;
- }
-
- return super.handleMsg(msg);
- }
-
- int scaleToRange( double how ) {
- int maxf = myschedule.getMaxFitness();
- double scale = 100.0/(double)maxf;
-
- int scaled = (int)(scale*how);
-
- if( scaled < -100 ) scaled = -100;
- if( scaled > 100 ) scaled = 100;
-
- return scaled;
- }
-
- String makeSuggestion() {
- StringBuffer suggestion = new StringBuffer( "The best dates are: " );
- boolean first = true;
- int max = -1000;
- int test;
- int x, y;
-
- for( x = 1; x <= UserSchedule.WEEK_DAYS; x++ ) {
- for( y = 1; y <= UserSchedule.NR_HOURS; y++ ) {
- test = board.getSum( x, y );
- if( test > max ) {
- max = test;
- }
- }
- }
-
- for( x = 1; x <= UserSchedule.WEEK_DAYS; x++ ) {
- for( y = 1; y <= UserSchedule.NR_HOURS; y++ ) {
- test = board.getSum( x, y );
- if( test == max ) {
- if( first )
- {
- suggestion.append( board.getDate( x, y ) );
- first = false;
- }
- else
- suggestion.append( ", "+board.getDate( x, y ) );
- }
- }
- }
-
- suggestion.append( "." );
- return suggestion.toString();
- }
-
- void recalculateSumAndMe( int x, int y ) {
- double sum = 0;
- Enumeration e = schedules.elements();
-
- while( e.hasMoreElements() ) {
- UserSchedule sch = (UserSchedule)e.nextElement();
-
- sum += (double)sch.fitness( x, y );
- }
-
- if( schedules.size() > 0 )
- sum /= (double)schedules.size();
-
- board.set( x, y, scaleToRange( myschedule.get( x, y ) ), scaleToRange( sum ) );
- }
-
- void recalculateCol( int x ) {
- for( int y = 0; y <= UserSchedule.NR_HOURS; y++ ) {
- recalculateSumAndMe( x, y );
- }
- }
-
- void recalculateRow( int y ) {
- for( int x = 0; x <= UserSchedule.WEEK_DAYS; x++ ) {
- recalculateSumAndMe( x, y );
- }
- }
-
- void recalculateAll() {
- for( int x = 0; x <= UserSchedule.WEEK_DAYS; x++ ) {
- for( int y = 0; y <= UserSchedule.NR_HOURS; y++ ) {
- recalculateSumAndMe( x, y );
- }
- }
- }
-
- public boolean mouseDown( Event evt, int x, int y ) {
- int array[] = new int[3];
- byte how;
-
- if( myschedule == null ) return false;
-
- status( schedules.size()+" users." );
-
- if( evt.target == board ) {
- if( x > 0 && y > 0 ) {
- myschedule.clickThrough( x, y );
- how = myschedule.get( x, y );
-
- recalculateSumAndMe( x, y );
-
- array[0] = x;
- array[1] = y;
- array[2] = (int)how;
- com.sendToOthers( new Msg( MSG_NEW_SCHEDULE_PART, array ) );
- }
- else {
- if( x == 0 && y > 0 ) {
- // take the first one and take it as a start...
- myschedule.clickThrough( 1, y );
- how = myschedule.get( 1, y );
-
- myschedule.setRow( y, how );
- recalculateRow( y );
- array[0] = y;
- array[1] = (int)how;
- com.sendToOthers( new Msg( MSG_NEW_SCHEDULE_ROW, array ) );
- }
- if( y == 0 && x > 0 ) {
- // take the first one and take it as a start...
- myschedule.clickThrough( x, 1 );
- how = myschedule.get( x, 1 );
-
- myschedule.setCol( x, how );
- recalculateCol( x );
- array[0] = x;
- array[1] = (int)how;
- com.sendToOthers( new Msg( MSG_NEW_SCHEDULE_COL, array ) );
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- public boolean action(Event evt,Object what)
- {
- if( evt.target == miclear || evt.target == miallok || evt.target == miallno ) {
- if( evt.target == miclear ) myschedule.clear();
- else if( evt.target == miallok ) myschedule.set( UserSchedule.ME_OK );
- else if( evt.target == miallno ) myschedule.set( UserSchedule.ME_NO );
-
- recalculateAll();
- com.sendToOthers( new Msg( MSG_NEW_SCHEDULE, myschedule ) );
-
- return true;
- }
- if( evt.target == misuggest ) {
- String suggestion = makeSuggestion();
- com.sendToAll( new Msg( Msg.CHAT_DIALOG_STRING, suggestion ) );
-
- return true;
- }
- return false;
- }
- }
-
- class Board extends Canvas {
- int week_days, min_hour, max_hour, nr_hours;
- int xs, ys; // xsize and ysize
-
- int board[][];
-
- String weekdays[] = { "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday" };
-
- public Board( int week_days, int min_hour, int max_hour ) {
- super();
-
- this.week_days = week_days;
- this.min_hour = min_hour;
- this.max_hour = max_hour;
- this.nr_hours = max_hour-min_hour+1;
- this.xs = week_days * 2 + 2;
- this.ys = nr_hours + 1;
-
- board = new int[xs][ys];
- clear();
- }
-
- synchronized public void clear() {
- for( int x = 0; x < xs; x++ ) {
- for( int y = 0; y < ys; y++ ) {
- board[x][y] = 0;
- }
- }
- }
-
- // the range from the others go from -100 to 100!
- // -100: does not fit at all
- // 100: fits very well
- synchronized public void setMe( int x, int y, int me ) {
- board[x*2][y] = me;
- drawCell( x*2, y );
- }
-
- synchronized public void setSum( int x, int y, int sum ) {
- board[x*2+1][y] = sum;
- drawCell( x*2+1, y );
- }
-
- synchronized public int getSum( int x, int y ) {
- return board[x*2+1][y];
- }
-
- public void set( int x, int y, int me, int sums ) {
- setMe( x, y, me );
- setSum( x, y, sums );
- }
-
- /**
- * returns to the cell (internal numbers) the corresponding realcoords.
- */
- public Rectangle getRect(int x, int y) {
- int xsize = size().width;
- int ysize = size().height;
- int csx = xsize/xs;
- int csy = ysize/ys;
- int bx = (xsize-csx*xs)/2;
- int by = (ysize-csy*ys)/2;
-
- return new Rectangle(bx+csx*x+1,by+csy*y+1,csx-2,csy-2);
- }
-
- /**
- * returns the cell (internal numbers) of the corresponding readlcoords.
- */
- public Point whichRect(int x, int y) {
- if ((xs!=0)&&(ys!=0)) {
- int xsize = size().width;
- int ysize = size().height;
- int csx = xsize/xs;
- int csy = ysize/ys;
- int bx = (xsize-csx*xs)/2;
- int by = (ysize-csy*ys)/2;
-
- return new Point((x-bx)/csx,(y-by)/csy);
- }
- else return null;
- }
-
- public void paint(Graphics g) {
- g.clearRect(0,0,size().width,size().height);
- int x,y;
- int xmin = getRect(0,0).x;
- int xmax = getRect(xs,0).x;
- int ymin = getRect(0,0).y;
- int ymax = getRect(0,ys).y;
-
- for (x=0;x<=xs;x+=2) {
- Rectangle r = getRect(x,x);
- g.drawLine(r.x-1,ymin-1,r.x-1,ymax-1);
- }
-
- for (y=0;y<=ys;y++) {
- Rectangle r = getRect(y,y);
- g.drawLine(xmin-1,r.y-1,xmax-1,r.y-1);
- }
-
- for( x=0; x<xs; x++ ) {
- for( y=0; y<ys; y++ ) {
- drawCell(x,y);
- }
- }
- }
-
- public void drawCell(int x, int y) {
- Rectangle r = getRect(x,y);
- Graphics g = getGraphics();
- if (g != null) {
-
- if( x > 1 && y > 0 ) {
- g.clearRect(r.x,r.y,r.width,r.height);
-
- if( board[x][y] < 0 )
- g.setColor(Color.red);
- else
- g.setColor(Color.green);
-
-
- if( x % 2 == 0 ) // me
- {
- FontMetrics fm = g.getFontMetrics();
-
- int nr = 1;
- String type[] = { "No", " ", "OK" };
-
- if( board[x][y] < -33 ) nr = 0;
- else if( board[x][y] < 33 ) nr = 1;
- else nr = 2;
-
- int baseline = (r.height-fm.getHeight())/2+fm.getAscent();
- g.drawString( type[nr], r.x+2, r.y+baseline );
- }
- else
- {
- int val = Math.abs(board[x][y]);
- g.fillRect(r.x,r.y,r.width*val/100,r.height);
- }
- }
- else {
- if( x == 0 && y > 0 ) {
- printInCell( g, x, y, String.valueOf(min_hour+y-1)+":00", Color.black );
- }
- if( y == 0 && x > 0 && (x % 2) == 0 ) {
- Color color = Color.black;
- int day = x/2 - 1;
-
- if( day == (new Date()).getDay() )
- color = Color.red;
-
- printInCell( g, x, y, weekdays[day], color );
- }
- }
- }
- }
-
- private void printInCell( Graphics g, int x, int y, String text, Color color ) {
- FontMetrics fm = g.getFontMetrics();
- Rectangle r = getRect(x,y);
- Rectangle r2 = getRect(x+1,y);
- int height = fm.getHeight();
- int width = fm.stringWidth( text );
-
- if( width > 2*r.width && !(text.charAt(0) >= '0' && text.charAt(0) <= '9') ) {
- text = text.substring( 0, 3 );
- width = fm.stringWidth( text );
- }
-
- int baseline = (r.height-height)/2+fm.getAscent();
- int leading = r.width-width/2;
-
- g.setColor(color);
-
- g.clearRect(r.x,r.y,r.width,r.height);
- g.clearRect(r2.x,r2.y,r2.width,r2.height);
-
- g.drawString( text, r.x+leading, r.y+baseline );
- }
-
- String getDate( int x, int y ) {
- return weekdays[x - 1]+" at "+String.valueOf(min_hour+y-1)+":00";
- }
-
-
- public boolean handleEvent(Event evt) {
- int x = evt.x;
- int y = evt.y;
- evt.target = this;
-
- evt.x = whichRect(x,y).x/2;
- evt.y = whichRect(x,y).y;
-
- // only send the event, if it was inside me (where else??)
- if ((evt.x >= 0) && (evt.x < xs) && (evt.y >= 0) && (evt.y <ys))
- {
- if( getParent() != null )
- getParent().postEvent(evt);
-
- }
-
- return true;
- }
-
- public Dimension preferredSize() {
- if( getGraphics() != null ) {
- // this is just a rough calculation...
-
- FontMetrics f = getGraphics().getFontMetrics();
-
- int h = f.getHeight() * (ys+3);
- int w = f.stringWidth( "Wednesdaym" ) * (xs/2);
-
- return new Dimension( w, h );
- }
- else return super.preferredSize();
- }
- }
-