From e1dbfd731b79d53ce959af1b2af235bb4dfc3d82 Mon Sep 17 00:00:00 2001 From: ant Date: Tue, 17 Jun 2014 00:41:16 +0400 Subject: [PATCH] 8033233: [JLightweightFrame] support default JViewport BLIT_SCROLL_MODE Reviewed-by: alexsch, pchelko --- .../javax/swing/DefaultDesktopManager.java | 10 ++++- src/share/classes/javax/swing/JViewport.java | 22 ++-------- .../classes/javax/swing/RepaintManager.java | 42 +++++++++++++++++- .../classes/sun/swing/JLightweightFrame.java | 43 ++++++++++++++++--- .../classes/sun/swing/SwingAccessor.java | 36 +++++++++++++++- .../classes/sun/swing/SwingUtilities2.java | 7 +++ 6 files changed, 134 insertions(+), 26 deletions(-) diff --git a/src/share/classes/javax/swing/DefaultDesktopManager.java b/src/share/classes/javax/swing/DefaultDesktopManager.java index 806ec3421..e44c9d939 100644 --- a/src/share/classes/javax/swing/DefaultDesktopManager.java +++ b/src/share/classes/javax/swing/DefaultDesktopManager.java @@ -677,6 +677,11 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab 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 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab // 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 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab 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 --git a/src/share/classes/javax/swing/JViewport.java b/src/share/classes/javax/swing/JViewport.java index f8a97e37a..4e5b7240c 100644 --- a/src/share/classes/javax/swing/JViewport.java +++ b/src/share/classes/javax/swing/JViewport.java @@ -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.event.*; 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 @@ -363,18 +359,6 @@ public class JViewport extends JComponent implements Accessible 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. @@ -1108,13 +1092,15 @@ public class JViewport extends JComponent implements Accessible 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 --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java index 5f103d968..c65c826eb 100644 --- a/src/share/classes/javax/swing/RepaintManager.java +++ b/src/share/classes/javax/swing/RepaintManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, 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.misc.SharedSecrets; 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 @@ public class RepaintManager 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 @@ public class RepaintManager 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 --git a/src/share/classes/sun/swing/JLightweightFrame.java b/src/share/classes/sun/swing/JLightweightFrame.java index dfba20fae..abc701918 100644 --- a/src/share/classes/sun/swing/JLightweightFrame.java +++ b/src/share/classes/sun/swing/JLightweightFrame.java @@ -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.Graphics2D; 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.awt.image.DataBufferInt; 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 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan private int[] copyBuffer; private PropertyChangeListener layoutSizeListener; + private RepaintListener repaintListener; static { SwingAccessor.setJLightweightFrameAccessor(new SwingAccessor.JLightweightFrameAccessor() { @@ -130,6 +135,30 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan } } }; + + 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 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan } } + 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 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan 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 --git a/src/share/classes/sun/swing/SwingAccessor.java b/src/share/classes/sun/swing/SwingAccessor.java index 10d4de62e..797802abd 100644 --- a/src/share/classes/sun/swing/SwingAccessor.java +++ b/src/share/classes/sun/swing/SwingAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, 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 @@ package sun.swing; import sun.misc.Unsafe; import java.awt.Point; +import javax.swing.RepaintManager; import javax.swing.text.JTextComponent; import javax.swing.TransferHandler; @@ -81,6 +82,14 @@ public final class SwingAccessor { void updateCursor(JLightweightFrame frame); } + /** + * 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. */ @@ -120,6 +129,31 @@ public final class SwingAccessor { * 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 --git a/src/share/classes/sun/swing/SwingUtilities2.java b/src/share/classes/sun/swing/SwingUtilities2.java index 87b8fe26a..399a2fccb 100644 --- a/src/share/classes/sun/swing/SwingUtilities2.java +++ b/src/share/classes/sun/swing/SwingUtilities2.java @@ -2041,4 +2041,11 @@ public class SwingUtilities2 { } 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); + } } -- GitLab