8033233: [JLightweightFrame] support default JViewport BLIT_SCROLL_MODE
Reviewed-by: alexsch, pchelko
--- 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);
}
}
--- 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 <code>Rectangle</code>
* 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);
--- 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<RepaintListener> 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 <code>endPaint</code>.
--- 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 {
--- 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;
+ }
}
--- 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);
+ }
}