Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
a2f14590
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看板
提交
a2f14590
编写于
3月 25, 2011
作者:
M
mrkam
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7027698: /jfc/SampleTree demo needs to be improved
Reviewed-by: rupashka
上级
1080aa8f
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
443 addition
and
417 deletion
+443
-417
src/share/demo/jfc/SampleTree/DynamicTreeNode.java
src/share/demo/jfc/SampleTree/DynamicTreeNode.java
+96
-96
src/share/demo/jfc/SampleTree/SampleData.java
src/share/demo/jfc/SampleTree/SampleData.java
+24
-28
src/share/demo/jfc/SampleTree/SampleTree.java
src/share/demo/jfc/SampleTree/SampleTree.java
+234
-214
src/share/demo/jfc/SampleTree/SampleTreeCellRenderer.java
src/share/demo/jfc/SampleTree/SampleTreeCellRenderer.java
+66
-57
src/share/demo/jfc/SampleTree/SampleTreeModel.java
src/share/demo/jfc/SampleTree/SampleTreeModel.java
+23
-22
未找到文件。
src/share/demo/jfc/SampleTree/DynamicTreeNode.java
浏览文件 @
a2f14590
/*
* Copyright (c) 1997,
1998
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997,
2011
, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -29,154 +29,154 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
import
javax.swing.tree.DefaultMutableTreeNode
;
import
java.awt.Color
;
import
java.awt.Font
;
import
java.awt.
Toolki
t
;
import
java.awt.
GraphicsEnvironmen
t
;
import
java.util.Random
;
import
javax.swing.tree.DefaultMutableTreeNode
;
/**
* DynamicTreeNode illustrates one of the possible ways in which dynamic
* loading can be used in tree. The basic premise behind this is that
* getChildCount() will be messaged from JTreeModel before any children
* are asked for. So, the first time getChildCount() is issued the
* children are loaded.<p>
* It should be noted that isLeaf will also be messaged from the model.
* The default behavior of TreeNode is to message getChildCount to
* determine this. As such, isLeaf is subclassed to always return false.<p>
* There are others ways this could be accomplished as well. Instead of
* subclassing TreeNode you could subclass JTreeModel and do the same
* thing in getChildCount(). Or, if you aren't using TreeNode you could
* write your own TreeModel implementation.
* Another solution would be to listen for TreeNodeExpansion events and
* the first time a node has been expanded post the appropriate insertion
* events. I would not recommend this approach though, the other two
* are much simpler and cleaner (and are faster from the perspective of
* how tree deals with it).
*
* NOTE: getAllowsChildren() can be messaged before getChildCount().
* For this example the nodes always allow children, so it isn't
* a problem, but if you do support true leaf nodes you may want
* to check for loading in getAllowsChildren too.
*
* @author Scott Violet
*/
public
class
DynamicTreeNode
extends
DefaultMutableTreeNode
{
/**
* DynamicTreeNode illustrates one of the possible ways in which dynamic
* loading can be used in tree. The basic premise behind this is that
* getChildCount() will be messaged from JTreeModel before any children
* are asked for. So, the first time getChildCount() is issued the
* children are loaded.<p>
* It should be noted that isLeaf will also be messaged from the model.
* The default behavior of TreeNode is to message getChildCount to
* determine this. As such, isLeaf is subclassed to always return false.<p>
* There are others ways this could be accomplished as well. Instead of
* subclassing TreeNode you could subclass JTreeModel and do the same
* thing in getChildCount(). Or, if you aren't using TreeNode you could
* write your own TreeModel implementation.
* Another solution would be to listen for TreeNodeExpansion events and
* the first time a node has been expanded post the appropriate insertion
* events. I would not recommend this approach though, the other two
* are much simpler and cleaner (and are faster from the perspective of
* how tree deals with it).
*
* NOTE: getAllowsChildren() can be messaged before getChildCount().
* For this example the nodes always allow children, so it isn't
* a problem, but if you do support true leaf nodes you may want
* to check for loading in getAllowsChildren too.
*
* @author Scott Violet
*/
@SuppressWarnings
(
"serial"
)
public
class
DynamicTreeNode
extends
DefaultMutableTreeNode
{
// Class stuff.
/** Number of names. */
static
protected
float
nameCount
;
/** Number of names. */
protected
static
float
nameCount
;
/** Names to use for children. */
static
protected
String
[]
names
;
protected
static
final
String
[]
NAMES
;
/** Potential fonts used to draw with. */
static
protected
Font
[]
fonts
;
protected
static
Font
[]
fonts
;
/** Used to generate the names. */
static
protected
Random
nameGen
;
protected
static
Random
nameGen
;
/** Number of children to create for each node. */
static
protected
final
int
DefaultChildrenCount
=
7
;
protected
static
final
int
DEFAULT_CHILDREN_COUNT
=
7
;
static
{
String
[]
fontNames
;
String
[]
fontNames
;
try
{
fontNames
=
Toolkit
.
getDefaultToolkit
().
getFontList
();
fontNames
=
GraphicsEnvironment
.
getLocalGraphicsEnvironment
().
getAvailableFontFamilyNames
();
}
catch
(
Exception
e
)
{
fontNames
=
null
;
}
if
(
fontNames
==
null
||
fontNames
.
length
==
0
)
{
names
=
new
String
[]
{
"Mark Andrews"
,
"Tom Ball"
,
"Alan Chung"
,
"Rob Davis"
,
"Jeff Dinkins"
,
"Amy Fowler"
,
"James Gosling"
,
"David Karlton"
,
"Dave Kloba"
,
"Dave Moore"
,
"Hans Muller"
,
"Rick Levenson"
,
"Tim Prinzing"
,
"Chester Rose"
,
"Ray Ryan"
,
"Georges Saab"
,
"Scott Violet"
,
"Kathy Walrath"
,
"Arnaud Weber"
};
}
else
{
if
(
fontNames
==
null
||
fontNames
.
length
==
0
)
{
NAMES
=
new
String
[]
{
"Mark Andrews"
,
"Tom Ball"
,
"Alan Chung"
,
"Rob Davis"
,
"Jeff Dinkins"
,
"Amy Fowler"
,
"James Gosling"
,
"David Karlton"
,
"Dave Kloba"
,
"Dave Moore"
,
"Hans Muller"
,
"Rick Levenson"
,
"Tim Prinzing"
,
"Chester Rose"
,
"Ray Ryan"
,
"Georges Saab"
,
"Scott Violet"
,
"Kathy Walrath"
,
"Arnaud Weber"
};
}
else
{
/* Create the Fonts, creating fonts is slow, much better to
do it once. */
int
fontSize
=
12
;
do it once. */
int
fontSize
=
12
;
names
=
fontNames
;
fonts
=
new
Font
[
names
.
length
];
for
(
int
counter
=
0
,
maxCounter
=
names
.
length
;
counter
<
maxCounter
;
counter
++)
{
NAMES
=
fontNames
;
fonts
=
new
Font
[
NAMES
.
length
];
for
(
int
counter
=
0
,
maxCounter
=
NAMES
.
length
;
counter
<
maxCounter
;
counter
++)
{
try
{
fonts
[
counter
]
=
new
Font
(
fontNames
[
counter
],
0
,
fontSize
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
fonts
[
counter
]
=
null
;
}
fontSize
=
((
fontSize
+
2
-
12
)
%
12
)
+
12
;
}
}
nameCount
=
(
float
)
names
.
length
;
nameCount
=
(
float
)
NAMES
.
length
;
nameGen
=
new
Random
(
System
.
currentTimeMillis
());
}
/** Have the children of this node been loaded yet? */
protected
boolean
hasLoaded
;
protected
boolean
hasLoaded
;
/**
* Constructs a new DynamicTreeNode instance with o as the user
* object.
*/
* Constructs a new DynamicTreeNode instance with o as the user
* object.
*/
public
DynamicTreeNode
(
Object
o
)
{
super
(
o
);
}
@Override
public
boolean
isLeaf
()
{
return
false
;
}
/**
* If hasLoaded is false, meaning the children have not yet been
* loaded, loadChildren is messaged and super is messaged for
* the return value.
*/
* If hasLoaded is false, meaning the children have not yet been
* loaded, loadChildren is messaged and super is messaged for
* the return value.
*/
@Override
public
int
getChildCount
()
{
if
(!
hasLoaded
)
{
if
(!
hasLoaded
)
{
loadChildren
();
}
return
super
.
getChildCount
();
}
/**
* Messaged the first time getChildCount is messaged. Creates
* children with random names from names.
*/
* Messaged the first time getChildCount is messaged. Creates
* children with random names from names.
*/
protected
void
loadChildren
()
{
DynamicTreeNode
newNode
;
Font
font
;
int
randomIndex
;
SampleData
data
;
for
(
int
counter
=
0
;
counter
<
DynamicTreeNode
.
DefaultChildrenCount
;
counter
++)
{
randomIndex
=
(
int
)(
nameGen
.
nextFloat
()
*
nameCount
);
if
(
fonts
!=
null
)
font
=
fonts
[
randomIndex
];
else
DynamicTreeNode
newNode
;
Font
font
;
int
randomIndex
;
SampleData
data
;
for
(
int
counter
=
0
;
counter
<
DynamicTreeNode
.
DEFAULT_CHILDREN_COUNT
;
counter
++)
{
randomIndex
=
(
int
)
(
nameGen
.
nextFloat
()
*
nameCount
);
String
displayString
=
NAMES
[
randomIndex
];
if
(
fonts
==
null
||
fonts
[
randomIndex
].
canDisplayUpTo
(
displayString
)
!=
-
1
)
{
font
=
null
;
if
(
counter
%
2
==
0
)
data
=
new
SampleData
(
font
,
Color
.
red
,
names
[
randomIndex
]);
else
data
=
new
SampleData
(
font
,
Color
.
blue
,
names
[
randomIndex
]);
}
else
{
font
=
fonts
[
randomIndex
];
}
if
(
counter
%
2
==
0
)
{
data
=
new
SampleData
(
font
,
Color
.
red
,
displayString
);
}
else
{
data
=
new
SampleData
(
font
,
Color
.
blue
,
displayString
);
}
newNode
=
new
DynamicTreeNode
(
data
);
/* Don't use add() here, add calls insert(newNode, getChildCount())
so if you want to use add, just be sure to set hasLoaded = true
first. */
so if you want to use add, just be sure to set hasLoaded = true
first. */
insert
(
newNode
,
counter
);
}
/* This node has now been loaded, mark it so. */
...
...
src/share/demo/jfc/SampleTree/SampleData.java
浏览文件 @
a2f14590
/*
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997,
2011,
Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -29,32 +29,27 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
import
java.awt.Color
;
import
java.awt.Font
;
/**
* @author Scott Violet
*/
* @author Scott Violet
*/
public
class
SampleData
extends
Object
{
public
class
SampleData
extends
Object
{
/** Font used for drawing. */
protected
Font
font
;
protected
Font
font
;
/** Color used for text. */
protected
Color
color
;
protected
Color
color
;
/** Value to display. */
protected
String
string
;
protected
String
string
;
/**
* Constructs a new instance of SampleData with the passed in
* arguments.
*/
* Constructs a new instance of SampleData with the passed in
* arguments.
*/
public
SampleData
(
Font
newFont
,
Color
newColor
,
String
newString
)
{
font
=
newFont
;
color
=
newColor
;
...
...
@@ -62,47 +57,48 @@ public class SampleData extends Object
}
/**
* Sets the font that is used to represent this object.
*/
* Sets the font that is used to represent this object.
*/
public
void
setFont
(
Font
newFont
)
{
font
=
newFont
;
}
/**
* Returns the Font used to represent this object.
*/
* Returns the Font used to represent this object.
*/
public
Font
getFont
()
{
return
font
;
}
/**
* Sets the color used to draw the text.
*/
* Sets the color used to draw the text.
*/
public
void
setColor
(
Color
newColor
)
{
color
=
newColor
;
}
/**
* Returns the color used to draw the text.
*/
* Returns the color used to draw the text.
*/
public
Color
getColor
()
{
return
color
;
}
/**
* Sets the string to display for this object.
*/
* Sets the string to display for this object.
*/
public
void
setString
(
String
newString
)
{
string
=
newString
;
}
/**
* Returnes the string to display for this object.
*/
* Returnes the string to display for this object.
*/
public
String
string
()
{
return
string
;
}
@Override
public
String
toString
()
{
return
string
;
}
...
...
src/share/demo/jfc/SampleTree/SampleTree.java
浏览文件 @
a2f14590
此差异已折叠。
点击以展开。
src/share/demo/jfc/SampleTree/SampleTreeCellRenderer.java
浏览文件 @
a2f14590
/*
* Copyright (c) 1997, 20
05
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 20
11
, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
import
javax.swing.Icon
;
import
javax.swing.ImageIcon
;
...
...
@@ -42,48 +40,56 @@ import java.awt.Component;
import
java.awt.Color
;
import
java.awt.Font
;
import
java.awt.Graphics
;
import
javax.swing.UIManager
;
@SuppressWarnings
(
"serial"
)
public
class
SampleTreeCellRenderer
extends
JLabel
implements
TreeCellRenderer
{
public
class
SampleTreeCellRenderer
extends
JLabel
implements
TreeCellRenderer
{
/** Font used if the string to be displayed isn't a font. */
static
protected
Font
defaultFont
;
protected
static
Font
defaultFont
;
/** Icon to use when the item is collapsed. */
static
protected
ImageIcon
collapsedIcon
;
protected
static
ImageIcon
collapsedIcon
;
/** Icon to use when the item is expanded. */
static
protected
ImageIcon
expandedIcon
;
protected
static
ImageIcon
expandedIcon
;
/** Color to use for the background when selected. */
static
protected
final
Color
SelectedBackgroundColor
=
Color
.
yellow
;
//new Color(0, 0, 128)
;
protected
static
final
Color
SELECTED_BACKGROUND_COLOR
;
static
{
static
{
if
(
"Nimbus"
.
equals
(
UIManager
.
getLookAndFeel
().
getName
()))
{
SELECTED_BACKGROUND_COLOR
=
new
Color
(
0
,
0
,
0
,
0
);
}
else
{
SELECTED_BACKGROUND_COLOR
=
Color
.
YELLOW
;
}
try
{
defaultFont
=
new
Font
(
"SansSerif"
,
0
,
12
);
}
catch
(
Exception
e
)
{}
}
catch
(
Exception
e
)
{
}
try
{
collapsedIcon
=
new
ImageIcon
(
SampleTreeCellRenderer
.
class
.
getResource
(
"/resources/images/collapsed.gif"
));
expandedIcon
=
new
ImageIcon
(
SampleTreeCellRenderer
.
class
.
getResource
(
"/resources/images/expanded.gif"
));
collapsedIcon
=
new
ImageIcon
(
SampleTreeCellRenderer
.
class
.
getResource
(
"/resources/images/collapsed.gif"
));
expandedIcon
=
new
ImageIcon
(
SampleTreeCellRenderer
.
class
.
getResource
(
"/resources/images/expanded.gif"
));
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Couldn't load images: "
+
e
);
}
}
/** Whether or not the item that was last configured is selected. */
protected
boolean
selected
;
protected
boolean
selected
;
/**
* This is messaged from JTree whenever it needs to get the size
* of the component or it wants to draw it.
* This attempts to set the font based on value, which will be
* a TreeNode.
*/
* This is messaged from JTree whenever it needs to get the size
* of the component or it wants to draw it.
* This attempts to set the font based on value, which will be
* a TreeNode.
*/
public
Component
getTreeCellRendererComponent
(
JTree
tree
,
Object
value
,
boolean
selected
,
boolean
expanded
,
boolean
leaf
,
int
row
,
boolean
hasFocus
)
{
Font
font
;
String
stringValue
=
tree
.
convertValueToText
(
value
,
selected
,
expanded
,
leaf
,
row
,
hasFocus
);
boolean
selected
,
boolean
expanded
,
boolean
leaf
,
int
row
,
boolean
hasFocus
)
{
String
stringValue
=
tree
.
convertValueToText
(
value
,
selected
,
expanded
,
leaf
,
row
,
hasFocus
);
/* Set the text. */
setText
(
stringValue
);
...
...
@@ -91,24 +97,27 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer
setToolTipText
(
stringValue
);
/* Set the image. */
if
(
expanded
)
if
(
expanded
)
{
setIcon
(
expandedIcon
);
else
if
(!
leaf
)
}
else
if
(!
leaf
)
{
setIcon
(
collapsedIcon
);
else
}
else
{
setIcon
(
null
);
}
/* Set the color and the font based on the SampleData userObject. */
SampleData
userObject
=
(
SampleData
)((
DefaultMutableTreeNode
)
value
)
.
getUserObject
();
if
(
hasFocus
)
setForeground
(
Color
.
cyan
);
else
SampleData
userObject
=
(
SampleData
)
((
DefaultMutableTreeNode
)
value
).
getUserObject
();
if
(
hasFocus
)
{
setForeground
(
UIManager
.
getColor
(
"Tree.selectionForeground"
)
);
}
else
{
setForeground
(
userObject
.
getColor
());
if
(
userObject
.
getFont
()
==
null
)
}
if
(
userObject
.
getFont
()
==
null
)
{
setFont
(
defaultFont
);
else
}
else
{
setFont
(
userObject
.
getFont
());
}
/* Update the selected flag for the next paint. */
this
.
selected
=
selected
;
...
...
@@ -117,36 +126,36 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer
}
/**
* paint is subclassed to draw the background correctly. JLabel
* currently does not allow backgrounds other than white, and it
* will also fill behind the icon. Something that isn't desirable.
*/
* paint is subclassed to draw the background correctly. JLabel
* currently does not allow backgrounds other than white, and it
* will also fill behind the icon. Something that isn't desirable.
*/
@Override
public
void
paint
(
Graphics
g
)
{
Color
bColor
;
Icon
currentI
=
getIcon
();
Color
bColor
;
Icon
currentI
=
getIcon
();
if
(
selected
)
bColor
=
SelectedBackgroundColor
;
else
if
(
getParent
()
!=
null
)
/* Pick background color up from parent (which will come from
the JTree we're contained in). */
if
(
selected
)
{
bColor
=
SELECTED_BACKGROUND_COLOR
;
}
else
if
(
getParent
()
!=
null
)
/* Pick background color up from parent (which will come from
the JTree we're contained in). */
{
bColor
=
getParent
().
getBackground
();
else
}
else
{
bColor
=
getBackground
();
}
g
.
setColor
(
bColor
);
if
(
currentI
!=
null
&&
getText
()
!=
null
)
{
int
offset
=
(
currentI
.
getIconWidth
()
+
getIconTextGap
());
if
(
currentI
!=
null
&&
getText
()
!=
null
)
{
int
offset
=
(
currentI
.
getIconWidth
()
+
getIconTextGap
());
if
(
getComponentOrientation
().
isLeftToRight
())
{
g
.
fillRect
(
offset
,
0
,
getWidth
()
-
1
-
offset
,
getHeight
()
-
1
);
}
else
{
getHeight
()
-
1
);
}
else
{
g
.
fillRect
(
0
,
0
,
getWidth
()
-
1
-
offset
,
getHeight
()
-
1
);
}
}
else
{
g
.
fillRect
(
0
,
0
,
getWidth
()
-
1
,
getHeight
()
-
1
);
}
else
g
.
fillRect
(
0
,
0
,
getWidth
()-
1
,
getHeight
()-
1
);
super
.
paint
(
g
);
}
}
src/share/demo/jfc/SampleTree/SampleTreeModel.java
浏览文件 @
a2f14590
/*
* Copyright (c) 1997,
1998
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997,
2011
, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
import
javax.swing.tree.DefaultTreeModel
;
import
javax.swing.tree.TreeNode
;
...
...
@@ -38,40 +36,43 @@ import javax.swing.tree.TreePath;
import
javax.swing.tree.DefaultMutableTreeNode
;
import
java.awt.Color
;
/**
* SampleTreeModel extends JTreeModel to extends valueForPathChanged.
* This method is called as a result of the user editing a value in
* the tree. If you allow editing in your tree, are using TreeNodes
* and the user object of the TreeNodes is not a String, then you're going
* to have to subclass JTreeModel as this example does.
*
* @author Scott Violet
*/
* SampleTreeModel extends JTreeModel to extends valueForPathChanged.
* This method is called as a result of the user editing a value in
* the tree. If you allow editing in your tree, are using TreeNodes
* and the user object of the TreeNodes is not a String, then you're going
* to have to subclass JTreeModel as this example does.
*
* @author Scott Violet
*/
@SuppressWarnings
(
"serial"
)
public
class
SampleTreeModel
extends
DefaultTreeModel
{
public
class
SampleTreeModel
extends
DefaultTreeModel
{
/**
* Creates a new instance of SampleTreeModel with newRoot set
* to the root of this model.
*/
* Creates a new instance of SampleTreeModel with newRoot set
* to the root of this model.
*/
public
SampleTreeModel
(
TreeNode
newRoot
)
{
super
(
newRoot
);
}
/**
* Subclassed to message setString() to the changed path item.
*/
* Subclassed to message setString() to the changed path item.
*/
@Override
public
void
valueForPathChanged
(
TreePath
path
,
Object
newValue
)
{
/* Update the user object. */
DefaultMutableTreeNode
aNode
=
(
DefaultMutableTreeNode
)
path
.
getLastPathComponent
();
SampleData
sampleData
=
(
SampleData
)
aNode
.
getUserObject
();
DefaultMutableTreeNode
aNode
=
(
DefaultMutableTreeNode
)
path
.
getLastPathComponent
();
SampleData
sampleData
=
(
SampleData
)
aNode
.
getUserObject
();
sampleData
.
setString
((
String
)
newValue
);
sampleData
.
setString
((
String
)
newValue
);
/* UUUhhhhh, pretty colors. */
sampleData
.
setColor
(
Color
.
green
);
/* Since we've changed how the data is to be displayed, message
nodeChanged. */
nodeChanged. */
nodeChanged
(
aNode
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录