# HG changeset patch # User ant # Date 1391179798 -14400 # Node ID df31f522531faef92babc88f590d5b1ac558e993 # Parent 16c1ddb7b66af933bb921d57e98e30c4c5062fc3 8033233: [JLightweightFrame] support default JViewport BLIT_SCROLL_MODE Reviewed-by: alexsch, pchelko diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/javax/swing/DefaultDesktopManager.java --- a/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Fri Jan 31 18:49:58 2014 +0400 @@ -677,6 +677,11 @@ f.setBounds(currentBounds); + if (!floaterCollision) { + Rectangle r = currentBounds; + currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height); + } + if(floaterCollision) { // since we couldn't blit we just redraw as fast as possible // the isDragging mucking is to avoid activating emergency @@ -706,6 +711,8 @@ // Fix the damage for (int i = 0; i < dirtyRects.length; i++) { parent.paintImmediately(dirtyRects[i]); + Rectangle r = dirtyRects[i]; + currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height); } // new areas of blit were exposed @@ -716,9 +723,10 @@ dirtyRects[i].x += newX - previousBounds.x; dirtyRects[i].y += newY - previousBounds.y; ((JInternalFrame)f).isDragging = false; - parent.paintImmediately(dirtyRects[i]); ((JInternalFrame)f).isDragging = true; + Rectangle r = dirtyRects[i]; + currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height); } } diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/javax/swing/JViewport.java --- a/jdk/src/share/classes/javax/swing/JViewport.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/javax/swing/JViewport.java Fri Jan 31 18:49:58 2014 +0400 @@ -25,8 +25,6 @@ package javax.swing; -import sun.swing.JLightweightFrame; - import java.awt.*; import java.awt.event.*; import java.awt.peer.ComponentPeer; @@ -37,10 +35,8 @@ import javax.swing.border.*; import javax.accessibility.*; - import java.io.Serializable; - /** * The "viewport" or "porthole" through which you see the underlying * information. When you scroll, what moves is the viewport. It is like @@ -364,18 +360,6 @@ super.remove(child); } - @Override - public void addNotify() { - super.addNotify(); - // JLightweightFrame does not support BLIT_SCROLL_MODE, so it should be replaced - Window rootWindow = SwingUtilities.getWindowAncestor(this); - if (rootWindow instanceof JLightweightFrame - && getScrollMode() == BLIT_SCROLL_MODE) { - setScrollMode(BACKINGSTORE_SCROLL_MODE); - } - } - - /** * Scrolls the view so that Rectangle * within the view becomes visible. @@ -1109,13 +1093,15 @@ Graphics g = JComponent.safelyGetGraphics(this); flushViewDirtyRegion(g, dirty); view.setLocation(newX, newY); - g.setClip(0,0,getWidth(), Math.min(getHeight(), - jview.getHeight())); + Rectangle r = new Rectangle( + 0, 0, getWidth(), Math.min(getHeight(), jview.getHeight())); + g.setClip(r); // Repaint the complete component if the blit succeeded // and needsRepaintAfterBlit returns true. repaintAll = (windowBlitPaint(g) && needsRepaintAfterBlit()); g.dispose(); + rm.notifyRepaintPerformed(this, r.x, r.y, r.width, r.height); rm.markCompletelyClean((JComponent)getParent()); rm.markCompletelyClean(this); rm.markCompletelyClean(jview); diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/javax/swing/RepaintManager.java --- a/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Jan 31 18:49:58 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ import sun.security.action.GetPropertyAction; import com.sun.java.swing.SwingUtilities3; +import sun.swing.SwingAccessor; +import sun.swing.SwingUtilities2.RepaintListener; /** * This class manages repaint requests, allowing the number @@ -184,6 +186,17 @@ static { + SwingAccessor.setRepaintManagerAccessor(new SwingAccessor.RepaintManagerAccessor() { + @Override + public void addRepaintListener(RepaintManager rm, RepaintListener l) { + rm.addRepaintListener(l); + } + @Override + public void removeRepaintListener(RepaintManager rm, RepaintListener l) { + rm.removeRepaintListener(l); + } + }); + volatileImageBufferEnabled = "true".equals(AccessController. doPrivileged(new GetPropertyAction( "swing.volatileImageBufferEnabled", "true"))); @@ -1267,6 +1280,33 @@ getPaintManager().copyArea(c, g, x, y, w, h, deltaX, deltaY, clip); } + private java.util.List repaintListeners = new ArrayList<>(1); + + private void addRepaintListener(RepaintListener l) { + repaintListeners.add(l); + } + + private void removeRepaintListener(RepaintListener l) { + repaintListeners.remove(l); + } + + /** + * Notify the attached repaint listeners that an area of the {@code c} component + * has been immediately repainted, that is without scheduling a repaint runnable, + * due to performing a "blit" (via calling the {@code copyArea} method). + * + * @param c the component + * @param x the x coordinate of the area + * @param y the y coordinate of the area + * @param w the width of the area + * @param h the height of the area + */ + void notifyRepaintPerformed(JComponent c, int x, int y, int w, int h) { + for (RepaintListener l : repaintListeners) { + l.repaintPerformed(c, x, y, w, h); + } + } + /** * Invoked prior to any paint/copyArea method calls. This will * be followed by an invocation of endPaint. diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/sun/swing/JLightweightFrame.java --- a/jdk/src/share/classes/sun/swing/JLightweightFrame.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/sun/swing/JLightweightFrame.java Fri Jan 31 18:49:58 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.awt.MouseInfo; import java.awt.Point; import java.awt.Rectangle; +import java.awt.Window; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.image.BufferedImage; @@ -43,16 +44,19 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.security.AccessController; +import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.LayoutFocusTraversalPolicy; +import javax.swing.RepaintManager; import javax.swing.RootPaneContainer; import javax.swing.SwingUtilities; import sun.awt.LightweightFrame; import sun.security.action.GetPropertyAction; +import sun.swing.SwingUtilities2.RepaintListener; /** * The frame serves as a lightweight container which paints its content @@ -89,6 +93,7 @@ private int[] copyBuffer; private PropertyChangeListener layoutSizeListener; + private RepaintListener repaintListener; static { SwingAccessor.setJLightweightFrameAccessor(new SwingAccessor.JLightweightFrameAccessor() { @@ -130,6 +135,30 @@ } } }; + + repaintListener = (JComponent c, int x, int y, int w, int h) -> { + Window jlf = SwingUtilities.getWindowAncestor(c); + if (jlf != JLightweightFrame.this) { + return; + } + Point p = SwingUtilities.convertPoint(c, x, y, jlf); + Rectangle r = new Rectangle(p.x, p.y, w, h).intersection( + new Rectangle(0, 0, bbImage.getWidth(), bbImage.getHeight())); + + if (!r.isEmpty()) { + notifyImageUpdated(r.x, r.y, r.width, r.height); + } + }; + + SwingAccessor.getRepaintManagerAccessor().addRepaintListener( + RepaintManager.currentManager(this), repaintListener); + } + + @Override + public void dispose() { + SwingAccessor.getRepaintManagerAccessor().removeRepaintListener( + RepaintManager.currentManager(this), repaintListener); + super.dispose(); } /** @@ -209,6 +238,13 @@ } } + private void notifyImageUpdated(int x, int y, int width, int height) { + if (copyBufferEnabled) { + syncCopyBuffer(false, x, y, width, height); + } + content.imageUpdated(x, y, width, height); + } + private void initInterior() { contentPane = new JPanel() { @Override @@ -231,10 +267,7 @@ EventQueue.invokeLater(new Runnable() { @Override public void run() { - if (copyBufferEnabled) { - syncCopyBuffer(false, clip.x, clip.y, clip.width, clip.height); - } - content.imageUpdated(clip.x, clip.y, clip.width, clip.height); + notifyImageUpdated(clip.x, clip.y, clip.width, clip.height); } }); } finally { diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/sun/swing/SwingAccessor.java --- a/jdk/src/share/classes/sun/swing/SwingAccessor.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/sun/swing/SwingAccessor.java Fri Jan 31 18:49:58 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import sun.misc.Unsafe; import java.awt.Point; +import javax.swing.RepaintManager; import javax.swing.text.JTextComponent; import javax.swing.TransferHandler; @@ -82,6 +83,14 @@ } /** + * An accessor for the RepaintManager class. + */ + public interface RepaintManagerAccessor { + void addRepaintListener(RepaintManager rm, SwingUtilities2.RepaintListener l); + void removeRepaintListener(RepaintManager rm, SwingUtilities2.RepaintListener l); + } + + /** * The javax.swing.text.JTextComponent class accessor object. */ private static JTextComponentAccessor jtextComponentAccessor; @@ -120,6 +129,31 @@ * Retrieve the accessor object for the JLightweightFrame class */ public static JLightweightFrameAccessor getJLightweightFrameAccessor() { + if (jLightweightFrameAccessor == null) { + unsafe.ensureClassInitialized(JLightweightFrame.class); + } return jLightweightFrameAccessor; } + + /** + * The RepaintManager class accessor object. + */ + private static RepaintManagerAccessor repaintManagerAccessor; + + /** + * Set an accessor object for the RepaintManager class. + */ + public static void setRepaintManagerAccessor(RepaintManagerAccessor accessor) { + repaintManagerAccessor = accessor; + } + + /** + * Retrieve the accessor object for the RepaintManager class. + */ + public static RepaintManagerAccessor getRepaintManagerAccessor() { + if (repaintManagerAccessor == null) { + unsafe.ensureClassInitialized(RepaintManager.class); + } + return repaintManagerAccessor; + } } diff -r 16c1ddb7b66a -r df31f522531f jdk/src/share/classes/sun/swing/SwingUtilities2.java --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java Fri Jan 31 14:20:40 2014 +0400 +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java Fri Jan 31 18:49:58 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1966,4 +1966,11 @@ } return path; } + + /** + * Used to listen to "blit" repaints in RepaintManager. + */ + public interface RepaintListener { + void repaintPerformed(JComponent c, int x, int y, int w, int h); + } }