📄 imgscrollpane.java
字号:
(ImageObserver.WIDTH|ImageObserver.HEIGHT)) { // Image dims not yet available we can't display return; } sx1 = sy1 = 0; sx2 = imgDim.width; sy2 = imgDim.height; dx1 = dy1 = 0; dx2 = dim.width; dy2 = dim.height; sox = soy = 0; // Limit the scaling area according to display size so // that scaling operates only on the area to be displayed if (dx2 > b.width) { // Calculate coordinates of displayed portion dx2 = b.width+ ((zoom>1f) ? (int)Math.ceil(zoom) : 0); if ((int)zoom == zoom) { // For integer zoom make dx2 a multiple of zoom dx2 = (int)(Math.ceil(dx2/zoom)*zoom); } sx1 = (int)(offx/zoom); sx2 = sx1 + (int)(dx2/zoom); // Compensate the scaling on integer coordinates with // an offset sox = (int)(sx1*zoom-offx); } if (dy2 > b.height) { // Calculate coordinates of displayed portion dy2 = b.height + ((zoom>1f) ? (int)Math.ceil(zoom) : 0); if ((int)zoom == zoom) { // For integer zoom make dy2 a multiple of zoom dy2 = (int)(Math.ceil(dy2/zoom)*zoom); } sy1 = (int)(offy/zoom); sy2 = sy1 + (int)(dy2/zoom); // Compensate the scaling on integer coordinates with // an extra offset soy = (int)(sy1*zoom-offy); } // Apply centering offset and scaling compensation offset dx1 += ox + sox; dy1 += oy + soy; dx2 += ox + sox; dy2 += oy + soy; } } // If the image is not yet complete and we are scrolling set to // erase to avoid leftovers of previous scroll on parts of the // image which are not yet ready if ((status & ImageObserver.ALLBITS) == 0 && (loffx != offx || loffy != offy)) { erase = true; } // Now we have the necessary info for display. We do it outside // synchronized to avoid any potential deadlocks with imageUpdate(). if (erase) { // We need to erase the current image. Make sure that we // redraw everything by setting the clipping area to the whole // display one. g.setClip(0,0,b.width,b.height); g.setColor(this.getBackground()); g.fillRect(0,0,b.width,b.height); } // Use copy scrolling if the image has not been erased, we are // scrolling, the image is complete, and copy scrolling is enabled. if (copyScroll && !erase && (loffx != offx || loffy != offy) && (status & ImageObserver.ALLBITS) != 0) { // We might be able to move some part of the displayed area // instead of redrawing everything. // We are just trasnlating the current image, so we can reuse // a part of it. int culx,culy; // Clipping area upper-left corner (inclusive) int cdrx,cdry; // Clipping area down-right corner (exclusive) int vulx,vuly; // Valid area upper-left corner (inclusive) int vdrx,vdry; // Valid area down-right corner (exclusive) culx = clip.x; culy = clip.y; cdrx = clip.x+clip.width; cdry = clip.y+clip.height; // Initialize valid area as the current display area after the // translation. vulx = loffx-offx; vuly = loffy-offy; vdrx = vulx+b.width; vdry = vuly+b.height; // Make new valid area the intersection of the clipping area // and the valid area. if (culx > vulx) vulx = culx; if (culy > vuly) vuly = culy; if (cdrx < vdrx) vdrx = cdrx; if (cdry < vdry) vdry = cdry; // If the new valid area is non-empty then copy current image // data if (vulx < vdrx && vuly < vdry) { // Ok we can move a part instead of repainting g.copyArea(vulx+offx-loffx,vuly+offy-loffy, vdrx-vulx,vdry-vuly, loffx-offx,loffy-offy); // Now we need to redraw the other parts if (culx < vulx) { // Need to draw at left g.setClip(culx,culy,vulx-culx,cdry-culy); if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2, this); } } if (vdrx < cdrx) { // Need to draw at right g.setClip(vdrx,culy,cdrx-vdrx,cdry-culy); if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2, this); } } if (culy < vuly) { // Need to draw at top g.setClip(vulx,culy,vdrx-vulx,vuly-culy); if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2, this); } } if (vdry < cdry) { // Need to draw at bottom g.setClip(vulx,vdry,vdrx-vulx,cdry-vdry); if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2, this); } } } else { // New valid area is empty, we need to draw everything if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,this); } } } else { // We are not translating, so we can't copy if (zoom == 1f) { // No scaling g.drawImage(img,ox,oy,this); } else { // Draw the image using on the fly scaling g.drawImage(img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,this); } } } /** * Calculates the image display dimensions according to the zoom and * image size. The dimensions are stored in 'dim'. * * @return True if the dimensions could be calculated, false if not * (i.e. not enough info is available). * * */ boolean calcDim() { // We need the image dimensions if (dimFlags != (ImageObserver.WIDTH|ImageObserver.HEIGHT)) { // Image dims not yet available we can't do anything return false; } // Calculate dims if (zoom == 1f) { // Natural image dimension dim.width = imgDim.width; dim.height = imgDim.height; } else { // Apply zoom dim.width = (int)(zoom*imgDim.width); dim.height = (int)(zoom*imgDim.height); } return true; } } /** * Scrollbars for the ImgScrollPane container. They are normal AWT * Scrollbars, but with a thickness of * ImgScrollPane.SCROLLBAR_THICKNESS. Also many of the set method of the * Adjustable interface are overriden and throw IllegalArgumentException * since they are not to be used externally. * * */ class ISPScrollbar extends Scrollbar { /** * Constructs a new scroll bar with the specified orientation and * values. * * <P>The orientation argument must take one of the two values * Scrollbar.HORIZONTAL, or Scrollbar.VERTICAL, indicating a * horizontal or vertical scroll bar, respectively. * * @param orientation indicates the orientation of the scroll bar * * @param value the initial value of the scroll bar. * * @param visible the size of the scroll bar's bubble, representing * the visible portion; the scroll bar uses this value when paging up * or down by a page. * * @param min the minimum value of the scroll bar. * * @param max the maximum value of the scroll bar. * * @param svt The scrollbar visible type **/ ISPScrollbar(int orientation, int value, int visible, int min, int max) { super(orientation,value,visible,min,max); } /** * Returns the preferred size of the scrollbar. It is the same as the * preferred size of a normal scrollbar but with a thickness of * ImgScrollPane.SCROLLBAR_THICKNESS. * * @return The Scrollbar preferred size * */ public Dimension getPreferredSize() { Dimension psz = super.getPreferredSize(); if (getOrientation() == HORIZONTAL) { psz.height = ImgScrollPane.SCROLLBAR_THICKNESS; } else { psz.width = ImgScrollPane.SCROLLBAR_THICKNESS; } return psz; } /** * Throws an IllegalArgumentException since the minimum value should * never be set externally. * */ public void setMinimum(int min) { throw new IllegalArgumentException(); } /** * Throws an IllegalArgumentException since the maximum value should * never be set externally. * */ public void setMaximum(int max) { throw new IllegalArgumentException(); } /** * Throws an IllegalArgumentException since the visible amount should * never be set externally. * */ public void setVisibleAmount(int v) { throw new IllegalArgumentException(); } /** * Throws an IllegalArgumentException since the block increment should * never be set externally. * */ public void setBlockIncrement(int b) { throw new IllegalArgumentException(); } /** * Sets the block increment for this scroll bar. * * <P>The block increment is the value that is added (subtracted) when * the user activates the block increment area of the scroll bar, * generally through a mouse or keyboard gesture that the scroll bar * receives as an adjustment event. * * <P>This is a version to be used by The ImgScrollPane class only. * * @param v the amount by which to increment or decrement the scroll * bar's value. * */ void setBlockIncrementI(int v) { super.setBlockIncrement(v); } /** * Sets the value of this scroll bar to the specified value. * * <P>If the value supplied is less than the current minimum or * greater than the current maximum, then one of those values is * substituted, as appropriate. * * <P>This is a version to be used by The ImgScrollPane class only. * * @param newValue he new value of the scroll bar. * */ void setValueI(int newValue) { super.setValue(newValue); } /** * Sets the value of this scroll bar to the specified value and * requests a repaint of the image area. * * <P>If the value supplied is less than the current minimum or * greater than the current maximum, then one of those values is * substituted, as appropriate. * * @param newValue he new value of the scroll bar. * */ public void setValue(int newValue) { // Set the value and check if we need to repaint synchronized (ImgScrollPane.this) { super.setValue(newValue); newValue = getValue(); // get the actual value for check if (imgDisplay.lastUpdateOffset != null) { if (getOrientation() == HORIZONTAL) { if (imgDisplay.lastUpdateOffset.x == newValue) { return; // No change } } else { if (imgDisplay.lastUpdateOffset.y == newValue) { return; // No change } } } } // New value changes from last drawn => repaint imgDisplay.repaint(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -