Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
1c202c45
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
1c202c45
编写于
10月 21, 2009
作者:
A
anthony
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6852592: invalidate() must be smarter
Summary: Introduce validate roots in AWT Reviewed-by: alexp, art, dcherepanov
上级
354840fa
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
355 addition
and
114 deletion
+355
-114
src/share/classes/java/applet/Applet.java
src/share/classes/java/applet/Applet.java
+15
-0
src/share/classes/java/awt/Component.java
src/share/classes/java/awt/Component.java
+32
-8
src/share/classes/java/awt/Container.java
src/share/classes/java/awt/Container.java
+114
-30
src/share/classes/java/awt/Window.java
src/share/classes/java/awt/Window.java
+17
-2
src/share/classes/javax/swing/JComponent.java
src/share/classes/javax/swing/JComponent.java
+2
-0
src/share/classes/javax/swing/JRootPane.java
src/share/classes/javax/swing/JRootPane.java
+2
-0
src/share/classes/javax/swing/JScrollPane.java
src/share/classes/javax/swing/JScrollPane.java
+2
-0
src/share/classes/javax/swing/JSplitPane.java
src/share/classes/javax/swing/JSplitPane.java
+2
-0
src/share/classes/javax/swing/JTextField.java
src/share/classes/javax/swing/JTextField.java
+2
-0
src/share/classes/javax/swing/JViewport.java
src/share/classes/javax/swing/JViewport.java
+1
-38
src/share/classes/javax/swing/RepaintManager.java
src/share/classes/javax/swing/RepaintManager.java
+2
-36
src/share/classes/javax/swing/SwingUtilities.java
src/share/classes/javax/swing/SwingUtilities.java
+50
-0
test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java
...iner/ValidateRoot/InvalidateMustRespectValidateRoots.java
+114
-0
未找到文件。
src/share/classes/java/applet/Applet.java
浏览文件 @
1c202c45
...
...
@@ -229,6 +229,21 @@ public class Applet extends Panel {
resize
(
d
.
width
,
d
.
height
);
}
/**
* Indicates if this container is a validate root.
* <p>
* {@code Applet} objects are the validate roots, and, therefore, they
* override this method to return {@code true}.
*
* @return {@code true}
* @since 1.7
* @see java.awt.Container#isValidateRoot
*/
@Override
public
boolean
isValidateRoot
()
{
return
true
;
}
/**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
...
...
src/share/classes/java/awt/Component.java
浏览文件 @
1c202c45
...
...
@@ -2764,8 +2764,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
/**
* Ensures that this component has a valid layout. This method is
* primarily intended to operate on instances of <code>Container</code>.
* Validates this component.
* <p>
* The meaning of the term <i>validating</i> is defined by the ancestors of
* this class. See {@link Container#validate} for more details.
*
* @see #invalidate
* @see #doLayout()
* @see LayoutManager
...
...
@@ -2794,12 +2797,24 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
/**
* Invalidates this component. This component and all parents
* above it are marked as needing to be laid out. This method can
* be called often, so it needs to execute quickly.
* Invalidates this component and its ancestors.
* <p>
* All the ancestors of this component up to the nearest validate root are
* marked invalid also. If there is no a validate root container for this
* component, all of its ancestors up to the root of the hierarchy are
* marked invalid as well. Marking a container <i>invalid</i> indicates
* that the container needs to be laid out.
* <p>
* This method is called automatically when any layout-related information
* changes (e.g. setting the bounds of the component, or adding the
* component to a container).
* <p>
* This method might be called often, so it should work fast.
*
* @see #validate
* @see #doLayout
* @see LayoutManager
* @see java.awt.Container#isValidateRoot
* @since JDK1.0
*/
public
void
invalidate
()
{
...
...
@@ -2818,9 +2833,18 @@ public abstract class Component implements ImageObserver, MenuContainer,
if
(!
isMaximumSizeSet
())
{
maxSize
=
null
;
}
if
(
parent
!=
null
)
{
parent
.
invalidateIfValid
();
}
invalidateParent
();
}
}
/**
* Invalidates the parent of this component if any.
*
* This method MUST BE invoked under the TreeLock.
*/
void
invalidateParent
()
{
if
(
parent
!=
null
)
{
parent
.
invalidateIfValid
();
}
}
...
...
src/share/classes/java/awt/Container.java
浏览文件 @
1c202c45
...
...
@@ -1492,20 +1492,59 @@ public class Container extends Component {
}
/**
* Invalidates the container. The container and all parents
* above it are marked as needing to be laid out. This method can
* be called often, so it needs to execute quickly.
* Indicates if this container is a <i>validate root</i>.
* <p>
* Layout-related changes, such as bounds of the validate root descendants,
* do not affect the layout of the validate root parent. This peculiarity
* enables the {@code invalidate()} method to stop invalidating the
* component hierarchy when the method encounters a validate root.
* <p>
* If a component hierarchy contains validate roots, the {@code validate()}
* method must be invoked on the validate root of a previously invalidated
* component, rather than on the top-level container (such as a {@code
* Frame} object) to restore the validity of the hierarchy later.
* <p>
* The {@code Window} class and the {@code Applet} class are the validate
* roots in AWT. Swing introduces more validate roots.
*
* <p> If the {@code LayoutManager} installed on this container is
* an instance of {@code LayoutManager2}, then
* {@link LayoutManager2#invalidateLayout(Container)} is invoked on
* it supplying this {@code Container} as the argument.
* @return whether this container is a validate root
* @see #invalidate
* @see java.awt.Component#invalidate
* @see javax.swing.JComponent#isValidateRoot
* @see javax.swing.JComponent#revalidate
* @since 1.7
*/
public
boolean
isValidateRoot
()
{
return
false
;
}
/**
* Invalidates the parent of the container unless the container
* is a validate root.
*/
@Override
void
invalidateParent
()
{
if
(!
isValidateRoot
())
{
super
.
invalidateParent
();
}
}
/**
* Invalidates the container.
* <p>
* If the {@code LayoutManager} installed on this container is an instance
* of the {@code LayoutManager2} interface, then
* the {@link LayoutManager2#invalidateLayout(Container)} method is invoked
* on it supplying this {@code Container} as the argument.
* <p>
* Afterwards this method marks this container invalid, and invalidates its
* ancestors. See the {@link Component#invalidate} method for more details.
*
* @see #validate
* @see #layout
* @see LayoutManager
* @see LayoutManager2#invalidateLayout(Container)
* @see LayoutManager2
*/
@Override
public
void
invalidate
()
{
LayoutManager
layoutMgr
=
this
.
layoutMgr
;
if
(
layoutMgr
instanceof
LayoutManager2
)
{
...
...
@@ -1518,35 +1557,39 @@ public class Container extends Component {
/**
* Validates this container and all of its subcomponents.
* <p>
* The <code>validate</code> method is used to cause a container
* to lay out its subcomponents again. It should be invoked when
* this container's subcomponents are modified (added to or
* removed from the container, or layout-related information
* changed) after the container has been displayed.
*
* <p>If this {@code Container} is not valid, this method invokes
* Validating a container means laying out its subcomponents.
* Layout-related changes, such as setting the bounds of a component, or
* adding a component to the container, invalidate the container
* automatically. Note that the ancestors of the container may be
* invalidated also (see {@link Component#invalidate} for details.)
* Therefore, to restore the validity of the hierarchy, the {@code
* validate()} method should be invoked on a validate root of an
* invalidated component, or on the top-most container if the hierarchy
* does not contain validate roots.
* <p>
* Validating the container may be a quite time-consuming operation. For
* performance reasons a developer may postpone the validation of the
* hierarchy till a set of layout-related operations completes, e.g. after
* adding all the children to the container.
* <p>
* If this {@code Container} is not valid, this method invokes
* the {@code validateTree} method and marks this {@code Container}
* as valid. Otherwise, no action is performed.
* <p>
* Note that the {@code invalidate()} method may invalidate not only the
* component it is called upon, but also the parents of the component.
* Therefore, to restore the validity of the hierarchy, the {@code
* validate()} method must be invoked on the top-most invalid container of
* the hierarchy. For performance reasons a developer may postpone the
* validation of the hierarchy till a bunch of layout-related operations
* completes, e.g. after adding all the children to the container.
*
* @see #add(java.awt.Component)
* @see #invalidate
* @see Container#isValidateRoot
* @see javax.swing.JComponent#revalidate()
* @see #validateTree
*/
public
void
validate
()
{
/* Avoid grabbing lock unless really necessary. */
if
(!
isValid
())
{
if
(!
isValid
()
||
descendUnconditionallyWhenValidating
)
{
boolean
updateCur
=
false
;
synchronized
(
getTreeLock
())
{
if
(!
isValid
()
&&
peer
!=
null
)
{
if
((!
isValid
()
||
descendUnconditionallyWhenValidating
)
&&
peer
!=
null
)
{
ContainerPeer
p
=
null
;
if
(
peer
instanceof
ContainerPeer
)
{
p
=
(
ContainerPeer
)
peer
;
...
...
@@ -1557,7 +1600,11 @@ public class Container extends Component {
validateTree
();
if
(
p
!=
null
)
{
p
.
endValidate
();
updateCur
=
isVisible
();
// Avoid updating cursor if this is an internal call.
// See validateUnconditionally() for details.
if
(!
descendUnconditionallyWhenValidating
)
{
updateCur
=
isVisible
();
}
}
}
}
...
...
@@ -1567,6 +1614,39 @@ public class Container extends Component {
}
}
/**
* Indicates whether valid containers should also traverse their
* children and call the validateTree() method on them.
*
* Synchronization: TreeLock.
*
* The field is allowed to be static as long as the TreeLock itself is
* static.
*
* @see #validateUnconditionally()
*/
private
static
boolean
descendUnconditionallyWhenValidating
=
false
;
/**
* Unconditionally validate the component hierarchy.
*/
final
void
validateUnconditionally
()
{
boolean
updateCur
=
false
;
synchronized
(
getTreeLock
())
{
descendUnconditionallyWhenValidating
=
true
;
validate
();
if
(
peer
instanceof
ContainerPeer
)
{
updateCur
=
isVisible
();
}
descendUnconditionallyWhenValidating
=
false
;
}
if
(
updateCur
)
{
updateCursorImmediately
();
}
}
/**
* Recursively descends the container tree and recomputes the
* layout for any subtrees marked as needing it (those marked as
...
...
@@ -1578,16 +1658,20 @@ public class Container extends Component {
*/
protected
void
validateTree
()
{
checkTreeLock
();
if
(!
isValid
())
{
if
(!
isValid
()
||
descendUnconditionallyWhenValidating
)
{
if
(
peer
instanceof
ContainerPeer
)
{
((
ContainerPeer
)
peer
).
beginLayout
();
}
doLayout
();
if
(!
isValid
())
{
doLayout
();
}
for
(
int
i
=
0
;
i
<
component
.
size
();
i
++)
{
Component
comp
=
component
.
get
(
i
);
if
(
(
comp
instanceof
Container
)
&&
!(
comp
instanceof
Window
)
&&
!
comp
.
isValid
())
{
&&
(!
comp
.
isValid
()
||
descendUnconditionallyWhenValidating
))
{
((
Container
)
comp
).
validateTree
();
}
else
{
comp
.
validate
();
...
...
src/share/classes/java/awt/Window.java
浏览文件 @
1c202c45
...
...
@@ -767,7 +767,7 @@ public class Window extends Container implements Accessible {
isPacked
=
true
;
}
validate
();
validate
Unconditionally
();
}
/**
...
...
@@ -943,7 +943,7 @@ public class Window extends Container implements Accessible {
if
(
peer
==
null
)
{
addNotify
();
}
validate
();
validate
Unconditionally
();
isInShow
=
true
;
if
(
visible
)
{
...
...
@@ -2599,6 +2599,21 @@ public class Window extends Container implements Accessible {
super
.
addPropertyChangeListener
(
propertyName
,
listener
);
}
/**
* Indicates if this container is a validate root.
* <p>
* {@code Window} objects are the validate roots, and, therefore, they
* override this method to return {@code true}.
*
* @return {@code true}
* @since 1.7
* @see java.awt.Container#isValidateRoot
*/
@Override
public
boolean
isValidateRoot
()
{
return
true
;
}
/**
* Dispatches an event to this window or one of its sub components.
* @param e the event
...
...
src/share/classes/javax/swing/JComponent.java
浏览文件 @
1c202c45
...
...
@@ -4878,7 +4878,9 @@ public abstract class JComponent extends Container implements Serializable,
* @see #revalidate
* @see java.awt.Component#invalidate
* @see java.awt.Container#validate
* @see java.awt.Container#isValidateRoot
*/
@Override
public
boolean
isValidateRoot
()
{
return
false
;
}
...
...
src/share/classes/javax/swing/JRootPane.java
浏览文件 @
1c202c45
...
...
@@ -725,8 +725,10 @@ public class JRootPane extends JComponent implements Accessible {
* because both classes override <code>isValidateRoot</code> to return true.
*
* @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
* @return true
*/
@Override
public
boolean
isValidateRoot
()
{
return
true
;
}
...
...
src/share/classes/javax/swing/JScrollPane.java
浏览文件 @
1c202c45
...
...
@@ -453,10 +453,12 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce
* @see java.awt.Container#validate
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
@Override
public
boolean
isValidateRoot
()
{
return
true
;
}
...
...
src/share/classes/javax/swing/JSplitPane.java
浏览文件 @
1c202c45
...
...
@@ -947,10 +947,12 @@ public class JSplitPane extends JComponent implements Accessible
*
* @return true
* @see JComponent#revalidate
* @see java.awt.Container#isValidateRoot
*
* @beaninfo
* hidden: true
*/
@Override
public
boolean
isValidateRoot
()
{
return
true
;
}
...
...
src/share/classes/javax/swing/JTextField.java
浏览文件 @
1c202c45
...
...
@@ -288,7 +288,9 @@ public class JTextField extends JTextComponent implements SwingConstants {
*
* @see JComponent#revalidate
* @see JComponent#isValidateRoot
* @see java.awt.Container#isValidateRoot
*/
@Override
public
boolean
isValidateRoot
()
{
return
SwingUtilities2
.
getViewport
(
this
)
==
null
;
}
...
...
src/share/classes/javax/swing/JViewport.java
浏览文件 @
1c202c45
...
...
@@ -469,49 +469,12 @@ public class JViewport extends JComponent implements Accessible
* is the synchronous version of a <code>revalidate</code>.
*/
private
void
validateView
()
{
Component
validateRoot
=
null
;
Component
validateRoot
=
SwingUtilities
.
getValidateRoot
(
this
,
false
)
;
/* Find the first JComponent ancestor of this component whose
* isValidateRoot() method returns true.
*/
for
(
Component
c
=
this
;
c
!=
null
;
c
=
c
.
getParent
())
{
if
((
c
instanceof
CellRendererPane
)
||
(
c
.
getPeer
()
==
null
))
{
return
;
}
if
((
c
instanceof
JComponent
)
&&
(((
JComponent
)
c
).
isValidateRoot
()))
{
validateRoot
=
c
;
break
;
}
}
// If no validateRoot, nothing to validate from.
if
(
validateRoot
==
null
)
{
return
;
}
// Make sure all ancestors are visible.
Component
root
=
null
;
for
(
Component
c
=
validateRoot
;
c
!=
null
;
c
=
c
.
getParent
())
{
// We don't check isVisible here, otherwise if the component
// is contained in something like a JTabbedPane when the
// component is made visible again it won't have scrolled
// to the correct location.
if
(
c
.
getPeer
()
==
null
)
{
return
;
}
if
((
c
instanceof
Window
)
||
(
c
instanceof
Applet
))
{
root
=
c
;
break
;
}
}
// Make sure there is a Window ancestor.
if
(
root
==
null
)
{
return
;
}
// Validate the root.
validateRoot
.
validate
();
...
...
src/share/classes/javax/swing/RepaintManager.java
浏览文件 @
1c202c45
...
...
@@ -310,47 +310,13 @@ public class RepaintManager
delegate
.
addInvalidComponent
(
invalidComponent
);
return
;
}
Component
validateRoot
=
null
;
Component
validateRoot
=
SwingUtilities
.
getValidateRoot
(
invalidComponent
,
true
);
/* Find the first JComponent ancestor of this component whose
* isValidateRoot() method returns true.
*/
for
(
Component
c
=
invalidComponent
;
c
!=
null
;
c
=
c
.
getParent
())
{
if
((
c
instanceof
CellRendererPane
)
||
(
c
.
getPeer
()
==
null
))
{
return
;
}
if
((
c
instanceof
JComponent
)
&&
(((
JComponent
)
c
).
isValidateRoot
()))
{
validateRoot
=
c
;
break
;
}
}
/* There's no validateRoot to apply validate to, so we're done.
*/
if
(
validateRoot
==
null
)
{
return
;
}
/* If the validateRoot and all of its ancestors aren't visible
* then we don't do anything. While we're walking up the tree
* we find the root Window or Applet.
*/
Component
root
=
null
;
for
(
Component
c
=
validateRoot
;
c
!=
null
;
c
=
c
.
getParent
())
{
if
(!
c
.
isVisible
()
||
(
c
.
getPeer
()
==
null
))
{
return
;
}
if
((
c
instanceof
Window
)
||
(
c
instanceof
Applet
))
{
root
=
c
;
break
;
}
}
if
(
root
==
null
)
{
return
;
}
/* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done.
...
...
src/share/classes/javax/swing/SwingUtilities.java
浏览文件 @
1c202c45
...
...
@@ -1967,4 +1967,54 @@ public class SwingUtilities implements SwingConstants
SwingUtilities
.
updateComponentTreeUI
(
component
);
}
}
/**
* Retrieves the validate root of a given container.
*
* If the container is contained within a {@code CellRendererPane}, this
* method returns {@code null} due to the synthetic nature of the {@code
* CellRendererPane}.
* <p>
* The component hierarchy must be displayable up to the toplevel component
* (either a {@code Frame} or an {@code Applet} object.) Otherwise this
* method returns {@code null}.
* <p>
* If the {@code visibleOnly} argument is {@code true}, the found validate
* root and all its parents up to the toplevel component must also be
* visible. Otherwise this method returns {@code null}.
*
* @return the validate root of the given container or null
* @see java.awt.Component#isDisplayable()
* @see java.awt.Component#isVisible()
* @since 1.7
*/
static
Container
getValidateRoot
(
Container
c
,
boolean
visibleOnly
)
{
Container
root
=
null
;
for
(;
c
!=
null
;
c
=
c
.
getParent
())
{
if
(!
c
.
isDisplayable
()
||
c
instanceof
CellRendererPane
)
{
return
null
;
}
if
(
c
.
isValidateRoot
())
{
root
=
c
;
break
;
}
}
if
(
root
==
null
)
{
return
null
;
}
for
(;
c
!=
null
;
c
=
c
.
getParent
())
{
if
(!
c
.
isDisplayable
()
||
(
visibleOnly
&&
!
c
.
isVisible
()))
{
return
null
;
}
if
(
c
instanceof
Window
||
c
instanceof
Applet
)
{
return
root
;
}
}
return
null
;
}
}
test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java
0 → 100644
浏览文件 @
1c202c45
/*
* Copyright 2009 Sun Microsystems, Inc. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
@test
@bug 6852592
@summary invalidate() must stop when it encounters a validate root
@author anthony.petrov@sun.com
@run main InvalidateMustRespectValidateRoots
*/
import
javax.swing.*
;
import
java.awt.event.*
;
public
class
InvalidateMustRespectValidateRoots
{
private
static
volatile
JRootPane
rootPane
;
public
static
void
main
(
String
args
[])
throws
Exception
{
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
// The JRootPane is a validate root. We'll check if
// invalidate() stops on the root pane, or goes further
// up to the frame.
JFrame
frame
=
new
JFrame
();
final
JButton
button
=
new
JButton
();
frame
.
add
(
button
);
// To enable running the test manually: use the Ctrl-Shift-F1
// to print the component hierarchy to the console
button
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
ev
)
{
if
(
button
.
isValid
())
{
button
.
invalidate
();
}
else
{
button
.
revalidate
();
}
}
});
rootPane
=
frame
.
getRootPane
();
// Now the component hierarchy looks like:
// frame
// --> rootPane
// --> layered pane
// --> content pane
// --> button
// Make all components valid first via showing the frame
// We have to make the frame visible. Otherwise revalidate() is
// useless (see RepaintManager.addInvalidComponent()).
frame
.
pack
();
// To enable running this test manually
frame
.
setVisible
(
true
);
if
(!
frame
.
isValid
())
{
throw
new
RuntimeException
(
"setVisible(true) failed to validate the frame"
);
}
// Now invalidate the button
button
.
invalidate
();
// Check if the 'valid' status is what we expect it to be
if
(
rootPane
.
isValid
())
{
throw
new
RuntimeException
(
"invalidate() failed to invalidate the root pane"
);
}
if
(!
frame
.
isValid
())
{
throw
new
RuntimeException
(
"invalidate() invalidated the frame"
);
}
// Now validate the hierarchy again
button
.
revalidate
();
// Now let the validation happen on the EDT
}
});
Thread
.
sleep
(
1000
);
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
// Check if the root pane finally became valid
if
(!
rootPane
.
isValid
())
{
throw
new
RuntimeException
(
"revalidate() failed to validate the hierarchy"
);
}
}
});
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录