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

📄 hiercanvas.java

📁 java编程的一些Applets例子。值得深入研究一下。
💻 JAVA
字号:
/* Attempt at hierarchy representation with expand/contract display
 * 12/22 - split NodeMem out to NodeMem.java
 * 12/23, 24 - adding goodies
 * 12/25 - separate HierCanvas out as HierCanvas.java
 * 01/05/96 - debug why Netscape doesn't show first time
 * 01/18 - suggestion by Ian Leicht <ivl@cs.hmc.edu> speeds up hideNChild()
*/

/*  Public Notice
 *  Hier.java, HierCanvas.java and NodeMem.java are copyright (c) 1996
 *  by William B. Brogden - wbrogden@bga.com
 *  130 Woodland Trail, Leander, TX  78641
 *  These classes can be used for private or commercial applications
 *  without restriction, but I would appreciate it if you let me know
 *  what you are using them for & if you make improvements.
 */

import java.applet.Applet;
import java.awt.*;
import java.io.StreamTokenizer;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Vector ;


//  a class to contain java.util.Vector of elements and display it
//  based on Canvas as simplest class
class HierCanvas extends Canvas {
    int state ;  // 0 = no vector resident

    Vector nodelist ;  // which we get from applet
    int    nodect ;
    int    topnode ;  // displayed on first line
    int    selnode ;  // always a visible selection
    int    level ;
    int     depth ; // number of layers in hierarchy
  // display related
  boolean gotFocus ;
  int insets[]  ; // x position for starting display - may chg w size
  int hCheight ; // canvas height as initialized
  Dimension   sizeC ;  // canvas size.height, size.width - as seen by paint
          // which could be affected by resize
  int nLines ;         // desired number of lines in the canvas
  int c_height, c_ascent ; // reset every paint
  int fontsize ;           // point size, smaller than height
  FontMetrics fmtr ;
  Font     curFont ;
  // TextArea  xtraText ; // display in right panel which we update
  Hier      parent ; // so we can inform of text change
  Scrollbar scB ;  // on left edge which we update

  public Dimension minimumSize() {
     return new Dimension( 100,100 ) ; // room for improvement
  }

  void updateTx() {
    NodeMem thisN = (NodeMem) nodelist.elementAt( selnode );
    if( parent != null ) {
      parent.TextChange( thisN.desc );
    }
  }

 // selnode may have changed, recalculate topnode to ensure display
  void calcTop() {
    int i, nlines, posct ;
    NodeMem thisN ;
    if( state == 0 ) return ;
    int poss[] = new int[ nodect ] ;
    nlines = sizeC.height / c_height ;  // need to handle small nlines?
    if( nlines < 2 ) nlines = 2 ;
    if( selnode <= topnode ) { topnode = selnode ; return ; }
    if( selnode <  topnode + nlines ) return ;
    // make list of possibles (exposed lines) until we hit selnode
    posct = 0 ;
    for( i = 0 ; i < nodect ; i++ ) {
      thisN = (NodeMem) nodelist.elementAt( i );
      if( thisN.exposed ) poss[ posct++ ] = i ; 
      if( i >= selnode ) break ;
    }
    i = 1 + (posct - nlines ) ;
    if( i < 0 ) i = 0 ;
    if( topnode < poss[i] ) topnode = poss[ i ] ; 
  }

 // action items
  public boolean mouseDown( Event evt, int x, int y ) {
    NodeMem thisN ;
    int i ;
    // System.out.println("Hier m " + evt.toString() ) ;
    for( i = topnode ; i < nodect ; i++ ) {
      thisN = (NodeMem) nodelist.elementAt( i );
      if( thisN.visible ) {
        if( thisN.sRect.inside( x, y ) ) {
          if( selnode == i ) { toggle();
          }
          else selnode = i ;
          repaint();
          return true ;
        }
      }
    }
    return false ;
  }

  public void absSel( int n ) {  // from scrollbar move
    int target, del, prev ;
    target = n ;
    if( n >= nodect ) target = nodect - 1 ;
    if( n < 0 ) target = 0 ;  // don't know if thats possible,chk anyway
    del = target - selnode ;  // neg means up, pos down
    if( del == 0 ) return ;
    if( del < 0 ) {
       while( target < selnode ) upSel( 1 ) ;
    }
    else {  // target may not be exposed
      prev = selnode ;
      while( target > selnode ) {        
         dnSel( 1 ) ;
         if( prev == selnode ) break ;  // unable to go further down
         prev = selnode ; // try for another
       }
    }
  }

  public void upSel( int n ) {
    int ct ;
    NodeMem thisN ;
    ct = n ;
    while( ct > 0 )
    { if( --selnode <= 0 ) { selnode = 0 ; break ;} // at top already
      thisN = (NodeMem) nodelist.elementAt( selnode );
      if( selnode < topnode ) topnode = selnode ;
      if( thisN.exposed ) ct-- ;  // found another exposed 
    }
    calcTop();
  }

  public void dnSel( int n ) {
    int i, ct ;
    NodeMem thisN ;
    ct = n ;
    while( ct > 0 )
    { if( selnode + 1 == nodect ) break ;  // at bottom
      for( i = selnode + 1 ; i < nodect ; i++ ) {
        thisN = (NodeMem) nodelist.elementAt( i );
        if( thisN.exposed ) {
          ct-- ; selnode = i ; break ;
        }
      }
      // System.out.println("dnSel " + selnode + " i " + i + " ct " + ct ) ;
      // i == nodect if we got to end w no more exposed
      if( i >= nodect ) break ;
    }
    calcTop();
  }

  // toggle state of selnode, if children exposed, contract, etc
  public void toggle() {
    NodeMem thisN = (NodeMem) nodelist.elementAt( selnode );
    int n ;
    n = thisN.child ;
    if( n == 0 ) return ;
    thisN = (NodeMem) nodelist.elementAt( n ) ;
    if( thisN.exposed ) contract() ; // already expanded
    else expand();
   }

  public void expand() {
    NodeMem thisN = (NodeMem) nodelist.elementAt( selnode );
    int n ;
    n = thisN.child ;
    // System.out.print("Expand " + selnode + " Child = " + n ) ;
    if( n <= 0 ) return ; // no child, cant expand
    thisN = (NodeMem) nodelist.elementAt( n ) ;
    if( thisN.exposed ) return ; // already expanded
    thisN.exposed = true ;
    selnode = n ;
    while( thisN.nxsib > 0 ) { // do all the sibs
      thisN = (NodeMem) nodelist.elementAt( thisN.nxsib ) ;
      thisN.exposed = true ;
    }
    calcTop();
  }

  // hide any children of this n - then itself & sibs - recursive - I hope
  void hideNChild( int n ) {
    int chn ;
    NodeMem thisN = (NodeMem) nodelist.elementAt( n );
    chn = thisN.child ;
    if( chn > 0 ) hideNChild( chn ) ;
    thisN.exposed = false ;
    // this suggestion by Ian Leicht eliminated much excess looping
    if( thisN.nxsib > 0 ) {
        hideNChild( thisN.nxsib ) ;
    }
/*  this is what I had before - while un-needed because of recursion
    while( thisN.nxsib > 0 ) {
      hideNChild( thisN.nxsib ) ;
      thisN = (NodeMem) nodelist.elementAt( thisN.nxsib ) ;      
    } */
  }

  // contract is tricky because we may be at a node with exposed children
  // or on a node without any, but with a parent
  public void contract() {
    int n ;
    NodeMem thisN = (NodeMem) nodelist.elementAt( selnode );
    n = thisN.child ;
    if( n <= 0 ) return ;
    if( ((NodeMem) nodelist.elementAt( n )).exposed ) {
        hideNChild( n ) ;
    }
  /*  else {
      System.out.println("No exposed children");
     } */
    calcTop();
  }

 // constructor
   public HierCanvas(   int hi ) {
      state   = 0 ;
      nodect  = 0 ;
      topnode = 0 ;
      selnode = 0 ;
      level  = 1 ;
      hCheight = hi ;
      gotFocus = false ;
     } // end constructor

   public void SetVector(  Vector nlist, int nc, int dp, int nln ) {
      int prevS, tmpN ;
      nodelist = nlist ;
      nodect  = nc ;
      topnode = 0 ;
      selnode = 0 ;
      state  = 1 ;
      level  = 1 ;
      nLines = nln ;
      depth  = dp ;
      gotFocus = false ;
      insets = new int[ depth ] ;
      for( int i = 1 ; i <= depth ; i++ ) {
        insets[ i - 1 ] = i * 15 ;
      }
      curFont = getFont();
      fmtr = getFontMetrics( getFont() ) ;
      fontsize = curFont.getSize() ;
      prevS = fontsize ;
      tmpN = hCheight / fmtr.getHeight() ;
      if( tmpN != nLines ) { 
        if( tmpN < nLines )while( decrFont());
        else while( incrFont());
       }
      } // end constructor

   public void AddParent( Hier p ) { parent = p ; }
   public void setFocus( boolean flg ) { gotFocus = flg ; } 
   public void AddScrollbar( Scrollbar s ) { scB = s ; } 

    // decrease font size to meet nLines target, min size is 8 point
    // return true if latest decr fails to meet target
   boolean decrFont() {
     int tmpN, prevS ;
     if( fontsize <= 8 ) return false ;
     setFont( new Font( curFont.getName(), Font.PLAIN, fontsize - 1 ));
     curFont = getFont();
     fontsize = curFont.getSize() ;
     fmtr = getFontMetrics( getFont() ) ;
     // System.out.println("Resized Font = " + fmtr.toString() ) ;
     tmpN = hCheight/ fmtr.getHeight() ;
     return ( tmpN < nLines ) ;
   }

   // similar to increase font size - max 40
   boolean incrFont() {
     int tmpN ;
     if( fontsize >= 40 ) return false ;
     setFont( new Font( curFont.getName(), Font.PLAIN, fontsize + 1 ));
     curFont = getFont();
     fontsize = curFont.getSize() ;
     fmtr = getFontMetrics( getFont() ) ;
     // System.out.println("Resized Font = " + fmtr.toString() ) ;
     tmpN = hCheight/ fmtr.getHeight() ;
     return ( tmpN > nLines ) ;
   }

   public void paint(Graphics g) {
     NodeMem  thisN ;
     int i, x, y, txwid, pluswid ;
     x = 1 ; 
     if( state == 0 ) {
       g.drawString("Working", 10,10 ); return ;
     }
     if( state == 1 ) 
     { g.drawString("Read " + nodect, 10, 10 ) ; state = 2 ; return ; 
     } // NOTE: this means we have to repaint twice I think
     sizeC = size() ; // current size of canvas 
     fmtr = getFontMetrics( getFont() ) ;
     c_height = fmtr.getHeight() ;
     c_ascent = fmtr.getAscent() ;
     pluswid = fmtr.stringWidth( " + " ) ; // indicator of more
     // calculate visibility & layout
     calculateVis() ;
     // update text area in right panel from selnode 
     updateTx() ;
     if( gotFocus ) g.setColor( Color.red ) ; // so I can see what it does
     else g.setColor( Color.black ) ;
     sizeC.width -= 4 ; sizeC.height -= 4 ;
     g.draw3DRect( 1,1, sizeC.width ,sizeC.height, true ) ;
     scB.setValue( selnode ) ;
     // prepare to show
     i = 0 ; y = c_height + 1 ;
     while(( y < sizeC.height) && ( i < nodect )) {
       thisN = (NodeMem) nodelist.elementAt( i );
       if( thisN == null ) {
         System.out.println("null thisN from list") ; break ;
       }
       // thisN.dump();
       if( thisN.visible ) {
         x = insets[ thisN.level - 1 ] ; // level 1 - depth 
         if( i == selnode )
         { g.setColor( Color.darkGray ) ;
           txwid = fmtr.stringWidth( thisN.tags[ thisN.level - 1] ) ;
           g.fillRect( x, y - c_ascent , txwid + pluswid, c_height ); 
           g.setColor( Color.white ) ;
         }
         else { g.setColor( Color.black ) ; }
         if( thisN.child > 0 ) {
          g.drawString( thisN.tags[ thisN.level - 1 ] + " +", x, y ) ;
         } 
         else {
          g.drawString( thisN.tags[ thisN.level - 1 ], x, y ) ;
         }
         thisN.sRect.reshape( x,y - c_ascent,sizeC.width ,c_height );
         y += c_height ; 
       } // from visible test
       i++ ;
     }
   }
  
  // enter with n = possible parent node, 0 based, check for children
  // NOTE: any child would be following immediately and have next level
  // as well as matching tags - print errors
  // IF there is a child, fill in child slot in element n,
  //   fill in parent slot in element n + 1,  return true 
  boolean childCheck( int n ) {
    int i ;
    if( n >= nodect ) return false ;
    NodeMem thisN = (NodeMem) nodelist.elementAt( n );
    thisN.child = 0 ;    // default 
    if( (n+ 1) >= nodect ) return false ; // at end of list  
    NodeMem nextN = (NodeMem) nodelist.elementAt( n + 1 );
    nextN.parent = 0 ;
    if( nextN.level <= thisN.level ) return false ;  // child not possible
    // probably a child but check tags in case of error
    for( i = 0 ; i < thisN.level ; i++ ) {
      if( thisN.tags[i].compareTo( nextN.tags[i] ) != 0 ) {
        System.out.println("Err in tag order " + n + thisN.tags[i] + nextN.tags[i] );
        return false ;
      }  
    }
    thisN.child  = n + 1 ;
    nextN.parent = n ;
    return true ;
  }

  // link siblings with n - known to be a first child
  // return count of sibs found
  int sibCheck( int n ) {
    int i, j,ps, ct, mtch ;
    NodeMem nextN ;
    if( n + 1 >= nodect ) return 0 ; // no sibs possible
    NodeMem thisN = (NodeMem) nodelist.elementAt( n );
    if( thisN.prevsib > 0 ) {
     // System.out.println("sibCheck of node " + n +" already set" ) ;
      return 1 ;
    }
    ps = n ;  // use for prevsib pointer 
    i = n + 1 ; ct = 0 ;
    // a sib could occur anywhere in remainder of the list
    while( i < nodect ) {
      nextN = (NodeMem) nodelist.elementAt( i );
      if( thisN.level == nextN.level ) {      // level must match
        if( thisN.level == 1 ) mtch = 0 ; // all level 1s are sibs
        else {
          mtch = 1 ;
          for( j = 1; j < thisN.level ; j++ ) { // tags must match
             mtch = thisN.tags[j - 1].compareTo( nextN.tags[j - 1] ) ;
             if( mtch != 0 ) break ;
          }
        }
        if( mtch == 0 ) {  // i is sib to n and ps
          thisN.nxsib = i ;
          nextN.parent = thisN.parent ;
          nextN.prevsib = ps ;
          ps = i ;
          thisN = nextN ;
          // System.out.print("found sib "+ i ) ; nextN.dump();
          ct++ ;
        }
        else break ;  // tested tags[], no match
      }
      i++ ;
    } 
    return ct ;
  } 
                                                                      
 public void calculateHier()
  // calculate hierarchy structure                                 
  { int i  ;
    NodeMem thisN ;
    i = 0 ;
    while( i < nodect )
    { thisN = (NodeMem) nodelist.elementAt( i );
      if( childCheck( i ) ) {   // childCheck sets Child in n, Parent in n + 1
        // System.out.print("has child ") ; thisN.dump();
      }
      sibCheck( i ) ; // set sib pointers
      i++ ;
    }
  }

  // calculate visibility based on current top, etc.
  void calculateVis()
  { int i, j, y  ;
    NodeMem thisN ;
    i = 0 ;
    while(i < topnode)((NodeMem)nodelist.elementAt(i++ )).visible = false ;
    y = c_height + 1 ;  // first line painted here
    for( i = topnode ; i < nodect ; i++ ) {
      thisN = (NodeMem) nodelist.elementAt( i );
      if( thisN == null ) break ;
      if( thisN.exposed ) {
       // System.out.print("Exposed " + i ); thisN.dump() ;
       thisN.visible = true ;
       y += c_height ;
      }
      else thisN.visible = false ;
      if( y >= sizeC.height ) break ;
    }
  }

}


//******************** end HierCanvas

⌨️ 快捷键说明

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