📄 scrollableobject.java
字号:
/* * (C) 2001 by Argonne National Laboratory * See COPYRIGHT in top-level directory. *//* * @author Anthony Chan */package viewer.zoomable;import java.awt.*;import java.awt.event.*;import javax.swing.*;import base.drawable.TimeBoundingBox;import viewer.common.CustomCursor;public abstract class ScrollableObject extends JComponent implements ScrollableView{ // The least number of images for this class to work is "3" private static final int NumImages = 3; protected static final int NumViewsPerImage = 2; protected static final int NumViewsTotal = NumImages * NumViewsPerImage; private ModelTime model = null; private JViewport src_vport; private Image offscreenImages[ /* NumImages */ ]; // The start and end of the image(s) in the user time coordinates private TimeBoundingBox tImages[ /* NumImages */ ]; private double tImage_extent; private TimeBoundingBox tImages_all; // extremes of tImages[] // shorthand for some convenient constant private int half_NumImages; // There are 2 kinds of indexes to label the image in the array buffer. // Both of the indexes are in the range of {0 : NumImages-1}. // - The 1st kind is called image order. The image order for the // image where viewport is in is always half_NumImages // - The 2nd kind is called image index. The image index for the // image where viewport is in can be any integer in {0 : NumImages-1} // The variable, cur_img_idx, serves to keep track where this image // is in the image array buffer. private int cur_img_idx; // The size of the visible view window in the viewport in pixel coordinates private Dimension visible_size; // The size of an image in pixel coordinates private Dimension image_size; // The size of this JCompoent in pixel coordinates private Dimension component_size; // The following constructor is NOT meant to be called. public ScrollableObject( ModelTime model ) { // Check if the number of images is an ODD number if ( NumImages % 2 == 0 || NumImages < 3 ) { String err_msg = "ScrollableObject(): NumImages = " + NumImages + " which is invalid, " + "i.e. either an EVEN number or < 3."; throw new IllegalStateException( err_msg ); // System.exit( 1 ); } this.model = model; offscreenImages = new Image[ NumImages ]; tImages = new TimeBoundingBox[ NumImages ]; for ( int idx = 0; idx < NumImages; idx++ ) tImages[ idx ] = new TimeBoundingBox(); tImages_all = new TimeBoundingBox(); super.setDoubleBuffered( false ); // Initialize the current image index and each image's time bound half_NumImages = NumImages / 2; setImagesInitTimeBounds(); image_size = new Dimension( 0, 0 ); component_size = super.getSize(); // Enable debugging graphics option setDebugGraphicsOptions( DebugGraphics.LOG_OPTION | DebugGraphics.BUFFERED_OPTION | DebugGraphics.FLASH_OPTION ); } // tImages_all needs to be synchronized with tImages[] private void setImagesInitTimeBounds() { double model_view_extent = model.getTimeViewExtent(); tImage_extent = NumViewsPerImage * model_view_extent; tImages_all.reinitialize(); int img_idx = 0; tImages[ img_idx ].setEarliestTime( model.getTimeViewPosition() - 0.5 * model_view_extent * (NumViewsTotal - 1) ); tImages[ img_idx ].setLatestFromEarliest( tImage_extent ); tImages_all.affectTimeBounds( tImages[ img_idx ] ); for ( img_idx = 1; img_idx < NumImages; img_idx++ ) { tImages[ img_idx ].setEarliestTime( tImages[ img_idx - 1 ].getLatestTime() ); tImages[ img_idx ].setLatestFromEarliest( tImage_extent ); tImages_all.affectTimeBounds( tImages[ img_idx ] ); } // initialize cur_img_idx in offscreenImages[] cur_img_idx = half_NumImages; } public String getStringforTimesOfImages() { StringBuffer rep = new StringBuffer(); for ( int img_idx = 0; img_idx < NumImages; img_idx++ ) rep.append( "tImages[ " + img_idx + " ] = " + tImages[ img_idx ] + "\n" ); return rep.toString(); } /* // tImages[ img_idx ] is guaranteed to be continuous in this class public boolean areImagesContinuousInTime() { double time_min; int curr_img_idx, prev_img_idx, init_img_idx; init_img_idx = 0; time_min = tImages[ init_img_idx ].getEarliestTime(); for ( int img_idx = 1; img_idx < NumImages; img_idx++ ) if ( tImages[ img_idx ].getEarliestTime() < time_min ) { init_img_idx = img_idx; time_min = tImages[ init_img_idx ].getEarliestTime(); } boolean isContinuous = true; for ( int ii = 1; ii < NumImages; ii++ ) { curr_img_idx = getValidImageIndex( init_img_idx + ii ); prev_img_idx = getValidImageIndex( curr_img_idx - 1 ); isContinuous = isContinuous && ( tImages[ curr_img_idx ].getEarliestTime() == tImages[ prev_img_idx ].getLatestTime() ); } return isContinuous; } */ // Using cur_img_idx to compute the extreme times of tImages[] is // NOT reliable when cur_img_idx is updated in checkToScrollView(). // getEarliestTimeOfImages() and getLatestTimeOfImages() // are some of the examples. /* public double getEarliestTimeOfImages() { int head_img_idx; // compute the beginning image index in the image buffer head_img_idx = getValidImageIndex( cur_img_idx - half_NumImages - 1 ); return tImages[ head_img_idx ].getEarliestTime(); } // getLatestTimeOfImages() is NOT reliable in part of checkToScrollView() public double getLatestTimeOfImages() { int tail_img_idx; // compute the last image index in the image buffer tail_img_idx = getValidImageIndex( cur_img_idx + half_NumImages + 1 ); return tImages[ tail_img_idx ].getLatestTime(); } */ public TimeBoundingBox getTimeBoundsOfImages() { return new TimeBoundingBox( tImages_all ); } // getValidImageIndex() convert an index to be // { 0 <= image index < NumImages } // i.e. implements periodic boundary condition private int getValidImageIndex( int img_idx ) { int adj_img_idx; adj_img_idx = img_idx % NumImages; if ( adj_img_idx < 0 ) return adj_img_idx + NumImages; else return adj_img_idx; } // getPrevImageIndex() and getNextImageIndex() implement circular buffer[] private int getNearPastImageIndex( int img_idx ) { if ( img_idx == 0 ) return NumImages - 1; else return img_idx - 1; } private int getNearFutureImageIndex( int img_idx ) { if ( img_idx == NumImages - 1 ) return 0 ; else return img_idx + 1; } private int getNearImageIndex( int img_idx, int dir ) { if ( dir < 0 ) return getNearPastImageIndex( img_idx ); else return getNearFutureImageIndex( img_idx ); } // Given a graphic context, create an offscreen image of specified size. private Image createImage( Dimension image_sz ) { if ( Debug.isActive() ) Debug.println( "ScrollableObject: createImage()'s image_sz = " + image_sz ); if ( image_sz.width > 0 && image_sz.height > 0 ) return super.createImage( image_sz.width, image_sz.height ); else return null; } private int getNumImagesMoved() { double cur_tView_init = model.getTimeViewPosition(); double cur_tView_extent = model.getTimeViewExtent(); double cur_tView_final = cur_tView_init + cur_tView_extent; if ( Debug.isActive() ) { Debug.println( "ScrollableObject: getNumImagesMoved()'s START: " ); Debug.println( "cur_tView_init = " + cur_tView_init + ", " + "cur_tView_final = " + cur_tView_final ); Debug.println( "tImages[ cur ] = " + tImages[ cur_img_idx ] ); } double view_init_in_imgs, view_final_in_imgs; int Nimages_moved_fwd, Nimages_moved_back, Nimages_moved; double tImages_init; // compute the beginning image index in the image buffer tImages_init = tImages_all.getEarliestTime(); if ( Debug.isActive() ) Debug.println( "ScrollableObject: getNumImagesMoved() " + "tImages_init = " + tImages_init ); // the integer part of view_init_in_imgs is the image order of // the image where cur_tView_init is in. Nimages_moved_fwd is // the relative image order w.r.t. center image in the buffer. view_init_in_imgs = ( cur_tView_init - tImages_init ) / tImage_extent; Nimages_moved_fwd = (int) Math.floor( view_init_in_imgs ) - half_NumImages; // the integer part of view_final_in_imgs is the image order of // the image where cur_tView_final is in. Nimages_moved_back is // the relative image order w.r.t. center image in the buffer. view_final_in_imgs = ( cur_tView_final - tImages_init ) / tImage_extent; Nimages_moved_back = (int) Math.floor( view_final_in_imgs ) - half_NumImages; Nimages_moved = 0; if ( Nimages_moved_fwd > 0 ) Nimages_moved = Nimages_moved_fwd; if ( Nimages_moved_back < 0 ) Nimages_moved = Nimages_moved_back; if ( Debug.isActive() ) { Debug.println( "ScrollableObject: getNumImagesMoved() " + "Nmages_moved = " + Nimages_moved ); Debug.println( "ScrollableObject: getNumImagesMoved()'s END: " ); } return Nimages_moved; } // scrollable_image interface when the view is zoomed in or out. public void checkToZoomView() { if ( Debug.isActive() ) Debug.println( "ScrollableObject: checkToZoomView()'s START: " ); double cur_tView_extent = model.getTimeViewExtent(); if ( cur_tView_extent * NumViewsPerImage != tImage_extent ) { setImagesInitTimeBounds(); initializeAllOffImages( tImages_all ); for ( int img_idx = 0; img_idx < NumImages; img_idx++ ) // for ( int img_idx = NumImages-1 ; img_idx >= 0 ; img_idx-- ) drawOneOffImage( offscreenImages[ img_idx ], tImages[ img_idx ] ); finalizeAllOffImages( tImages_all ); } if ( Debug.isActive() ) Debug.println( "ScrollableObject: checkToZoomView()'s END: " ); } // scrollable_image interface when the view is scrolled by the scrollbar. public void checkToScrollView() { int Nimages_moved; int img_mv_dir, img_idx; int past_img_idx, future_img_idx; int start_idx; int idx; if ( Debug.isActive() ) Debug.println( "ScrollableObject: checkToScrollView()'s START: " ); // Using the old cur_img_idx as the center of images to locate // the images needed to be redrawn img_mv_dir = 0; Nimages_moved = getNumImagesMoved(); if ( Nimages_moved != 0 ) { if ( Math.abs( Nimages_moved ) <= NumImages ) { img_mv_dir = Nimages_moved / Math.abs( Nimages_moved ); // locate the end image index in same direction as img_mv_dir start_idx = getValidImageIndex( cur_img_idx + img_mv_dir * half_NumImages); // Determine tImages_all first before invoking // initializeAllOffImages() and finalizeAllOffImages() for ( idx = 1; idx <= Math.abs( Nimages_moved ); idx++ ) { img_idx = getValidImageIndex( start_idx + img_mv_dir * idx ); if ( Debug.isActive() ) Debug.println( "ScrollableObject: checkToScrollView() " + "cur_img_idx = " + cur_img_idx + ", " + "start_idx = " + start_idx + ", " + "img_idx = " + img_idx );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -