Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
b5478b37
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看板
提交
b5478b37
编写于
2月 12, 2010
作者:
D
dcherepanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6705345: Enable multiple file selection in AWT FileDialog
Reviewed-by: art, anthony, alexp
上级
8145b67f
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
639 addition
and
44 deletion
+639
-44
src/share/classes/java/awt/FileDialog.java
src/share/classes/java/awt/FileDialog.java
+116
-1
src/share/classes/sun/awt/AWTAccessor.java
src/share/classes/sun/awt/AWTAccessor.java
+47
-0
src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
+20
-5
src/windows/classes/sun/awt/windows/WFileDialogPeer.java
src/windows/classes/sun/awt/windows/WFileDialogPeer.java
+61
-22
src/windows/native/sun/windows/awt_FileDialog.cpp
src/windows/native/sun/windows/awt_FileDialog.cpp
+82
-16
src/windows/native/sun/windows/awt_FileDialog.h
src/windows/native/sun/windows/awt_FileDialog.h
+4
-0
test/java/awt/FileDialog/MultipleMode/MultipleMode.html
test/java/awt/FileDialog/MultipleMode/MultipleMode.html
+20
-0
test/java/awt/FileDialog/MultipleMode/MultipleMode.java
test/java/awt/FileDialog/MultipleMode/MultipleMode.java
+289
-0
未找到文件。
src/share/classes/java/awt/FileDialog.java
浏览文件 @
b5478b37
...
@@ -28,6 +28,8 @@ import java.awt.peer.FileDialogPeer;
...
@@ -28,6 +28,8 @@ import java.awt.peer.FileDialogPeer;
import
java.io.FilenameFilter
;
import
java.io.FilenameFilter
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.ObjectInputStream
;
import
java.io.ObjectInputStream
;
import
java.io.File
;
import
sun.awt.AWTAccessor
;
/**
/**
* The <code>FileDialog</code> class displays a dialog window
* The <code>FileDialog</code> class displays a dialog window
...
@@ -93,6 +95,25 @@ public class FileDialog extends Dialog {
...
@@ -93,6 +95,25 @@ public class FileDialog extends Dialog {
*/
*/
String
file
;
String
file
;
/**
* Contains the File instances for all the files that the user selects.
*
* @serial
* @see getFiles
* @since 1.7
*/
private
File
[]
files
;
/**
* Represents whether the file dialog allows the multiple file selection.
*
* @serial
* @see #setMultipleMode
* @see #isMultipleMode
* @since 1.7
*/
private
boolean
multipleMode
=
false
;
/*
/*
* The filter used as the file dialog's filename filter.
* The filter used as the file dialog's filename filter.
* The file dialog will only be displaying files whose
* The file dialog will only be displaying files whose
...
@@ -123,6 +144,26 @@ public class FileDialog extends Dialog {
...
@@ -123,6 +144,26 @@ public class FileDialog extends Dialog {
}
}
}
}
static
{
AWTAccessor
.
setFileDialogAccessor
(
new
AWTAccessor
.
FileDialogAccessor
()
{
public
void
setFiles
(
FileDialog
fileDialog
,
String
directory
,
String
files
[])
{
fileDialog
.
setFiles
(
directory
,
files
);
}
public
void
setFile
(
FileDialog
fileDialog
,
String
file
)
{
fileDialog
.
file
=
(
""
.
equals
(
file
))
?
null
:
file
;
}
public
void
setDirectory
(
FileDialog
fileDialog
,
String
directory
)
{
fileDialog
.
dir
=
(
""
.
equals
(
directory
))
?
null
:
directory
;
}
public
boolean
isMultipleMode
(
FileDialog
fileDialog
)
{
synchronized
(
fileDialog
.
getObjectLock
())
{
return
fileDialog
.
multipleMode
;
}
}
});
}
/**
/**
* Initialize JNI field and method IDs for fields that may be
* Initialize JNI field and method IDs for fields that may be
accessed from C.
accessed from C.
...
@@ -370,6 +411,51 @@ public class FileDialog extends Dialog {
...
@@ -370,6 +411,51 @@ public class FileDialog extends Dialog {
return
file
;
return
file
;
}
}
/**
* Returns files that the user selects.
* <p>
* If the user cancels the file dialog,
* then the method returns an empty array.
*
* @return files that the user selects or an empty array
* if the user cancels the file dialog.
* @see #setFile(String)
* @see #getFile
* @since 1.7
*/
public
File
[]
getFiles
()
{
synchronized
(
getObjectLock
())
{
if
(
files
!=
null
)
{
return
files
.
clone
();
}
else
{
return
new
File
[
0
];
}
}
}
/**
* Stores the names of all the files that the user selects.
*
* Note that the method is private and it's intended to be used
* by the peers through the AWTAccessor API.
*
* @param directory the current directory
* @param files the array that contains the short names of
* all the files that the user selects.
*
* @see #getFiles
* @since 1.7
*/
private
void
setFiles
(
String
directory
,
String
files
[])
{
synchronized
(
getObjectLock
())
{
int
filesNumber
=
(
files
!=
null
)
?
files
.
length
:
0
;
this
.
files
=
new
File
[
filesNumber
];
for
(
int
i
=
0
;
i
<
filesNumber
;
i
++)
{
this
.
files
[
i
]
=
new
File
(
directory
,
files
[
i
]);
}
}
}
/**
/**
* Sets the selected file for this file dialog window to be the
* Sets the selected file for this file dialog window to be the
* specified file. This file becomes the default file if it is set
* specified file. This file becomes the default file if it is set
...
@@ -380,7 +466,8 @@ public class FileDialog extends Dialog {
...
@@ -380,7 +466,8 @@ public class FileDialog extends Dialog {
* as the file.
* as the file.
*
*
* @param file the file being set
* @param file the file being set
* @see java.awt.FileDialog#getFile
* @see #getFile
* @see #getFiles
*/
*/
public
void
setFile
(
String
file
)
{
public
void
setFile
(
String
file
)
{
this
.
file
=
(
file
!=
null
&&
file
.
equals
(
""
))
?
null
:
file
;
this
.
file
=
(
file
!=
null
&&
file
.
equals
(
""
))
?
null
:
file
;
...
@@ -390,6 +477,34 @@ public class FileDialog extends Dialog {
...
@@ -390,6 +477,34 @@ public class FileDialog extends Dialog {
}
}
}
}
/**
* Enables or disables multiple file selection for the file dialog.
*
* @param enable if {@code true}, multiple file selection is enabled;
* {@code false} - disabled.
* @see #isMultipleMode
* @since 1.7
*/
public
void
setMultipleMode
(
boolean
enable
)
{
synchronized
(
getObjectLock
())
{
this
.
multipleMode
=
enable
;
}
}
/**
* Returns whether the file dialog allows the multiple file selection.
*
* @return {@code true} if the file dialog allows the multiple
* file selection; {@code false} otherwise.
* @see #setMultipleMode
* @since 1.7
*/
public
boolean
isMultipleMode
()
{
synchronized
(
getObjectLock
())
{
return
multipleMode
;
}
}
/**
/**
* Determines this file dialog's filename filter. A filename filter
* Determines this file dialog's filename filter. A filename filter
* allows the user to specify which files appear in the file dialog
* allows the user to specify which files appear in the file dialog
...
...
src/share/classes/sun/awt/AWTAccessor.java
浏览文件 @
b5478b37
...
@@ -390,6 +390,30 @@ public final class AWTAccessor {
...
@@ -390,6 +390,30 @@ public final class AWTAccessor {
boolean
isTrayIconPopup
(
PopupMenu
popupMenu
);
boolean
isTrayIconPopup
(
PopupMenu
popupMenu
);
}
}
/*
* An accessor for the FileDialog class
*/
public
interface
FileDialogAccessor
{
/*
* Sets the files the user selects
*/
void
setFiles
(
FileDialog
fileDialog
,
String
directory
,
String
files
[]);
/*
* Sets the file the user selects
*/
void
setFile
(
FileDialog
fileDialog
,
String
file
);
/*
* Sets the directory the user selects
*/
void
setDirectory
(
FileDialog
fileDialog
,
String
directory
);
/*
* Returns whether the file dialog allows the multiple file selection.
*/
boolean
isMultipleMode
(
FileDialog
fileDialog
);
}
/*
/*
* The java.awt.Component class accessor object.
* The java.awt.Component class accessor object.
...
@@ -431,6 +455,11 @@ public final class AWTAccessor {
...
@@ -431,6 +455,11 @@ public final class AWTAccessor {
*/
*/
private
static
PopupMenuAccessor
popupMenuAccessor
;
private
static
PopupMenuAccessor
popupMenuAccessor
;
/*
* The java.awt.FileDialog class accessor object.
*/
private
static
FileDialogAccessor
fileDialogAccessor
;
/*
/*
* Set an accessor object for the java.awt.Component class.
* Set an accessor object for the java.awt.Component class.
*/
*/
...
@@ -567,4 +596,22 @@ public final class AWTAccessor {
...
@@ -567,4 +596,22 @@ public final class AWTAccessor {
}
}
return
popupMenuAccessor
;
return
popupMenuAccessor
;
}
}
/*
* Set an accessor object for the java.awt.FileDialog class.
*/
public
static
void
setFileDialogAccessor
(
FileDialogAccessor
fda
)
{
fileDialogAccessor
=
fda
;
}
/*
* Retrieve the accessor object for the java.awt.FileDialog class.
*/
public
static
FileDialogAccessor
getFileDialogAccessor
()
{
if
(
fileDialogAccessor
==
null
)
{
unsafe
.
ensureClassInitialized
(
FileDialog
.
class
);
}
return
fileDialogAccessor
;
}
}
}
src/solaris/classes/sun/awt/X11/XFileDialogPeer.java
浏览文件 @
b5478b37
...
@@ -37,6 +37,7 @@ import javax.swing.plaf.ComponentUI;
...
@@ -37,6 +37,7 @@ import javax.swing.plaf.ComponentUI;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
import
sun.util.logging.PlatformLogger
;
import
sun.util.logging.PlatformLogger
;
import
sun.awt.AWTAccessor
;
class
XFileDialogPeer
extends
XDialogPeer
implements
FileDialogPeer
,
ActionListener
,
ItemListener
,
KeyEventDispatcher
,
XChoicePeerListener
{
class
XFileDialogPeer
extends
XDialogPeer
implements
FileDialogPeer
,
ActionListener
,
ItemListener
,
KeyEventDispatcher
,
XChoicePeerListener
{
private
static
final
PlatformLogger
log
=
PlatformLogger
.
getLogger
(
"sun.awt.X11.XFileDialogPeer"
);
private
static
final
PlatformLogger
log
=
PlatformLogger
.
getLogger
(
"sun.awt.X11.XFileDialogPeer"
);
...
@@ -171,6 +172,10 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
...
@@ -171,6 +172,10 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
filterField
=
new
TextField
();
filterField
=
new
TextField
();
selectionField
=
new
TextField
();
selectionField
=
new
TextField
();
boolean
isMultipleMode
=
AWTAccessor
.
getFileDialogAccessor
().
isMultipleMode
(
target
);
fileList
.
setMultipleMode
(
isMultipleMode
);
// the insets used by the components in the fileDialog
// the insets used by the components in the fileDialog
Insets
noInset
=
new
Insets
(
0
,
0
,
0
,
0
);
Insets
noInset
=
new
Insets
(
0
,
0
,
0
,
0
);
Insets
textFieldInset
=
new
Insets
(
0
,
8
,
0
,
8
);
Insets
textFieldInset
=
new
Insets
(
0
,
8
,
0
,
8
);
...
@@ -380,7 +385,8 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
...
@@ -380,7 +385,8 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
* handle the selection event
* handle the selection event
*/
*/
void
handleSelection
(
String
file
)
{
void
handleSelection
(
String
file
)
{
int
index
=
file
.
lastIndexOf
(
'/'
);
int
index
=
file
.
lastIndexOf
(
java
.
io
.
File
.
separatorChar
);
if
(
index
==
-
1
)
{
if
(
index
==
-
1
)
{
savedDir
=
this
.
dir
;
savedDir
=
this
.
dir
;
...
@@ -389,8 +395,12 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
...
@@ -389,8 +395,12 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
savedDir
=
file
.
substring
(
0
,
index
+
1
);
savedDir
=
file
.
substring
(
0
,
index
+
1
);
savedFile
=
file
.
substring
(
index
+
1
);
savedFile
=
file
.
substring
(
index
+
1
);
}
}
target
.
setDirectory
(
savedDir
);
target
.
setFile
(
savedFile
);
AWTAccessor
.
FileDialogAccessor
fileDialogAccessor
=
AWTAccessor
.
getFileDialogAccessor
();
fileDialogAccessor
.
setDirectory
(
target
,
savedDir
);
fileDialogAccessor
.
setFile
(
target
,
savedFile
);
fileDialogAccessor
.
setFiles
(
target
,
savedDir
,
fileList
.
getSelectedItems
());
}
}
/**
/**
...
@@ -404,8 +414,13 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
...
@@ -404,8 +414,13 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
setFilterField
(
null
);
setFilterField
(
null
);
directoryList
.
clear
();
directoryList
.
clear
();
fileList
.
clear
();
fileList
.
clear
();
target
.
setFile
(
null
);
target
.
setDirectory
(
null
);
AWTAccessor
.
FileDialogAccessor
fileDialogAccessor
=
AWTAccessor
.
getFileDialogAccessor
();
fileDialogAccessor
.
setDirectory
(
target
,
null
);
fileDialogAccessor
.
setFile
(
target
,
null
);
fileDialogAccessor
.
setFiles
(
target
,
null
,
null
);
handleQuitButton
();
handleQuitButton
();
}
}
...
...
src/windows/classes/sun/awt/windows/WFileDialogPeer.java
浏览文件 @
b5478b37
...
@@ -117,26 +117,57 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
...
@@ -117,26 +117,57 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
}
}
}
}
// NOTE: This method is called by privileged threads.
/*
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
* The function converts the file names (the buffer parameter)
void
handleSelected
(
final
String
file
)
{
* in the Windows format into the Java format and saves the results
final
FileDialog
fileDialog
=
(
FileDialog
)
target
;
* into the FileDialog instance.
WToolkit
.
executeOnEventHandlerThread
(
fileDialog
,
new
Runnable
()
{
*
public
void
run
()
{
* If it's the multi-select mode, the buffer contains the current
int
index
=
file
.
lastIndexOf
(
java
.
io
.
File
.
separatorChar
);
/*2509*//*ibm*/
* directory followed by the short names of the files.
String
dir
;
* The directory and file name strings are NULL separated.
* If it's the single-select mode, the buffer doesn't have the NULL
* separator between the path and the file name.
*
* NOTE: This method is called by privileged threads.
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
*/
void
handleSelected
(
final
char
[]
buffer
)
{
String
[]
wFiles
=
(
new
String
(
buffer
)).
split
(
"\0"
);
// NULL is the delimiter
boolean
multiple
=
(
wFiles
.
length
>
1
);
if
(
index
==
-
1
)
{
String
jDirectory
=
null
;
dir
=
"."
+
java
.
io
.
File
.
separator
;
String
jFile
=
null
;
fileDialog
.
setFile
(
file
);
String
jFiles
[]
=
null
;
}
else
{
if
(
multiple
)
{
dir
=
file
.
substring
(
0
,
index
+
1
);
jDirectory
=
wFiles
[
0
];
fileDialog
.
setFile
(
file
.
substring
(
index
+
1
));
jFiles
=
new
String
[
wFiles
.
length
-
1
];
}
System
.
arraycopy
(
wFiles
,
1
,
jFiles
,
0
,
jFiles
.
length
);
fileDialog
.
setDirectory
(
dir
);
jFile
=
jFiles
[
1
];
// choose any file
fileDialog
.
hide
();
}
else
{
int
index
=
wFiles
[
0
].
lastIndexOf
(
java
.
io
.
File
.
separatorChar
);
if
(
index
==
-
1
)
{
jDirectory
=
"."
+
java
.
io
.
File
.
separator
;
jFile
=
wFiles
[
0
];
}
else
{
jDirectory
=
wFiles
[
0
].
substring
(
0
,
index
+
1
);
jFile
=
wFiles
[
0
].
substring
(
index
+
1
);
}
}
jFiles
=
new
String
[]
{
jFile
};
}
final
FileDialog
fileDialog
=
(
FileDialog
)
target
;
AWTAccessor
.
FileDialogAccessor
fileDialogAccessor
=
AWTAccessor
.
getFileDialogAccessor
();
fileDialogAccessor
.
setDirectory
(
fileDialog
,
jDirectory
);
fileDialogAccessor
.
setFile
(
fileDialog
,
jFile
);
fileDialogAccessor
.
setFiles
(
fileDialog
,
jDirectory
,
jFiles
);
WToolkit
.
executeOnEventHandlerThread
(
fileDialog
,
new
Runnable
()
{
public
void
run
()
{
fileDialog
.
hide
();
}
});
});
}
// handleSelected()
}
// handleSelected()
...
@@ -144,11 +175,14 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
...
@@ -144,11 +175,14 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
void
handleCancel
()
{
void
handleCancel
()
{
final
FileDialog
fileDialog
=
(
FileDialog
)
target
;
final
FileDialog
fileDialog
=
(
FileDialog
)
target
;
AWTAccessor
.
getFileDialogAccessor
().
setFile
(
fileDialog
,
null
);
AWTAccessor
.
getFileDialogAccessor
().
setFiles
(
fileDialog
,
null
,
null
);
WToolkit
.
executeOnEventHandlerThread
(
fileDialog
,
new
Runnable
()
{
WToolkit
.
executeOnEventHandlerThread
(
fileDialog
,
new
Runnable
()
{
public
void
run
()
{
public
void
run
()
{
fileDialog
.
setFile
(
null
);
fileDialog
.
hide
();
fileDialog
.
hide
();
}
}
});
});
}
// handleCancel()
}
// handleCancel()
...
@@ -244,4 +278,9 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
...
@@ -244,4 +278,9 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
public
void
createScreenSurface
(
boolean
isResize
)
{}
public
void
createScreenSurface
(
boolean
isResize
)
{}
@Override
@Override
public
void
replaceSurfaceData
()
{}
public
void
replaceSurfaceData
()
{}
public
boolean
isMultipleMode
()
{
FileDialog
fileDialog
=
(
FileDialog
)
target
;
return
AWTAccessor
.
getFileDialogAccessor
().
isMultipleMode
(
fileDialog
);
}
}
}
src/windows/native/sun/windows/awt_FileDialog.cpp
浏览文件 @
b5478b37
...
@@ -44,6 +44,7 @@ jmethodID AwtFileDialog::setHWndMID;
...
@@ -44,6 +44,7 @@ jmethodID AwtFileDialog::setHWndMID;
jmethodID
AwtFileDialog
::
handleSelectedMID
;
jmethodID
AwtFileDialog
::
handleSelectedMID
;
jmethodID
AwtFileDialog
::
handleCancelMID
;
jmethodID
AwtFileDialog
::
handleCancelMID
;
jmethodID
AwtFileDialog
::
checkFilenameFilterMID
;
jmethodID
AwtFileDialog
::
checkFilenameFilterMID
;
jmethodID
AwtFileDialog
::
isMultipleModeMID
;
/* FileDialog ids */
/* FileDialog ids */
jfieldID
AwtFileDialog
::
modeID
;
jfieldID
AwtFileDialog
::
modeID
;
...
@@ -57,6 +58,13 @@ static TCHAR s_fileFilterString[MAX_FILTER_STRING];
...
@@ -57,6 +58,13 @@ static TCHAR s_fileFilterString[MAX_FILTER_STRING];
/* Non-localized suffix of the filter string */
/* Non-localized suffix of the filter string */
static
const
TCHAR
s_additionalString
[]
=
TEXT
(
" (*.*)
\0
*.*
\0
"
);
static
const
TCHAR
s_additionalString
[]
=
TEXT
(
" (*.*)
\0
*.*
\0
"
);
// Default limit of the output buffer.
#define SINGLE_MODE_BUFFER_LIMIT MAX_PATH+1
#define MULTIPLE_MODE_BUFFER_LIMIT 32768
// The name of the property holding the pointer to the OPENFILENAME structure.
static
LPCTSTR
OpenFileNameProp
=
TEXT
(
"AWT_OFN"
);
/***********************************************************************/
/***********************************************************************/
void
void
...
@@ -140,6 +148,8 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
...
@@ -140,6 +148,8 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
FileDialogWndProc
);
FileDialogWndProc
);
::
SetProp
(
parent
,
NativeDialogWndProcProp
,
reinterpret_cast
<
HANDLE
>
(
lpfnWndProc
));
::
SetProp
(
parent
,
NativeDialogWndProcProp
,
reinterpret_cast
<
HANDLE
>
(
lpfnWndProc
));
::
SetProp
(
parent
,
OpenFileNameProp
,
(
void
*
)
lParam
);
break
;
break
;
}
}
case
WM_DESTROY
:
{
case
WM_DESTROY
:
{
...
@@ -149,6 +159,7 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
...
@@ -149,6 +159,7 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
lpfnWndProc
);
lpfnWndProc
);
::
RemoveProp
(
parent
,
ModalDialogPeerProp
);
::
RemoveProp
(
parent
,
ModalDialogPeerProp
);
::
RemoveProp
(
parent
,
NativeDialogWndProcProp
);
::
RemoveProp
(
parent
,
NativeDialogWndProcProp
);
::
RemoveProp
(
parent
,
OpenFileNameProp
);
break
;
break
;
}
}
case
WM_NOTIFY
:
{
case
WM_NOTIFY
:
{
...
@@ -174,6 +185,30 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
...
@@ -174,6 +185,30 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
// to unblock all the windows blocked by this dialog as it will
// to unblock all the windows blocked by this dialog as it will
// be closed soon
// be closed soon
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
setHWndMID
,
(
jlong
)
0
);
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
setHWndMID
,
(
jlong
)
0
);
}
else
if
(
notifyEx
->
hdr
.
code
==
CDN_SELCHANGE
)
{
// reallocate the buffer if the buffer is too small
LPOPENFILENAME
lpofn
=
(
LPOPENFILENAME
)
GetProp
(
parent
,
OpenFileNameProp
);
UINT
nLength
=
CommDlg_OpenSave_GetSpec
(
parent
,
NULL
,
0
)
+
CommDlg_OpenSave_GetFolderPath
(
parent
,
NULL
,
0
);
if
(
lpofn
->
nMaxFile
<
nLength
)
{
// allocate new buffer
LPTSTR
newBuffer
=
new
TCHAR
[
nLength
];
if
(
newBuffer
)
{
memset
(
newBuffer
,
0
,
nLength
*
sizeof
(
TCHAR
));
LPTSTR
oldBuffer
=
lpofn
->
lpstrFile
;
lpofn
->
lpstrFile
=
newBuffer
;
lpofn
->
nMaxFile
=
nLength
;
// free the previously allocated buffer
if
(
oldBuffer
)
{
delete
[]
oldBuffer
;
}
}
}
}
}
}
}
break
;
break
;
...
@@ -193,7 +228,6 @@ AwtFileDialog::Show(void *p)
...
@@ -193,7 +228,6 @@ AwtFileDialog::Show(void *p)
WCHAR
unicodeChar
=
L' '
;
WCHAR
unicodeChar
=
L' '
;
LPTSTR
fileBuffer
=
NULL
;
LPTSTR
fileBuffer
=
NULL
;
LPTSTR
currentDirectory
=
NULL
;
LPTSTR
currentDirectory
=
NULL
;
OPENFILENAME
ofn
;
jint
mode
=
0
;
jint
mode
=
0
;
BOOL
result
=
FALSE
;
BOOL
result
=
FALSE
;
DWORD
dlgerr
;
DWORD
dlgerr
;
...
@@ -204,6 +238,10 @@ AwtFileDialog::Show(void *p)
...
@@ -204,6 +238,10 @@ AwtFileDialog::Show(void *p)
jobject
target
=
NULL
;
jobject
target
=
NULL
;
jobject
parent
=
NULL
;
jobject
parent
=
NULL
;
AwtComponent
*
awtParent
=
NULL
;
AwtComponent
*
awtParent
=
NULL
;
jboolean
multipleMode
=
JNI_FALSE
;
OPENFILENAME
ofn
;
memset
(
&
ofn
,
0
,
sizeof
(
ofn
));
/*
/*
* There's a situation (see bug 4906972) when InvokeFunction (by which this method is called)
* There's a situation (see bug 4906972) when InvokeFunction (by which this method is called)
...
@@ -233,7 +271,16 @@ AwtFileDialog::Show(void *p)
...
@@ -233,7 +271,16 @@ AwtFileDialog::Show(void *p)
(
jstring
)
env
->
GetObjectField
(
target
,
AwtFileDialog
::
dirID
);
(
jstring
)
env
->
GetObjectField
(
target
,
AwtFileDialog
::
dirID
);
JavaStringBuffer
directoryBuffer
(
env
,
directory
);
JavaStringBuffer
directoryBuffer
(
env
,
directory
);
fileBuffer
=
new
TCHAR
[
MAX_PATH
+
1
];
multipleMode
=
env
->
CallBooleanMethod
(
peer
,
AwtFileDialog
::
isMultipleModeMID
);
UINT
bufferLimit
;
if
(
multipleMode
==
JNI_TRUE
)
{
bufferLimit
=
MULTIPLE_MODE_BUFFER_LIMIT
;
}
else
{
bufferLimit
=
SINGLE_MODE_BUFFER_LIMIT
;
}
LPTSTR
fileBuffer
=
new
TCHAR
[
bufferLimit
];
memset
(
fileBuffer
,
0
,
bufferLimit
*
sizeof
(
TCHAR
));
file
=
(
jstring
)
env
->
GetObjectField
(
target
,
AwtFileDialog
::
fileID
);
file
=
(
jstring
)
env
->
GetObjectField
(
target
,
AwtFileDialog
::
fileID
);
if
(
file
!=
NULL
)
{
if
(
file
!=
NULL
)
{
...
@@ -244,8 +291,6 @@ AwtFileDialog::Show(void *p)
...
@@ -244,8 +291,6 @@ AwtFileDialog::Show(void *p)
fileBuffer
[
0
]
=
_T
(
'\0'
);
fileBuffer
[
0
]
=
_T
(
'\0'
);
}
}
memset
(
&
ofn
,
0
,
sizeof
(
ofn
));
ofn
.
lStructSize
=
sizeof
(
ofn
);
ofn
.
lStructSize
=
sizeof
(
ofn
);
ofn
.
lpstrFilter
=
s_fileFilterString
;
ofn
.
lpstrFilter
=
s_fileFilterString
;
ofn
.
nFilterIndex
=
1
;
ofn
.
nFilterIndex
=
1
;
...
@@ -265,19 +310,23 @@ AwtFileDialog::Show(void *p)
...
@@ -265,19 +310,23 @@ AwtFileDialog::Show(void *p)
ofn
.
hwndOwner
=
NULL
;
ofn
.
hwndOwner
=
NULL
;
}
}
ofn
.
lpstrFile
=
fileBuffer
;
ofn
.
lpstrFile
=
fileBuffer
;
ofn
.
nMaxFile
=
MAX_PATH
;
ofn
.
nMaxFile
=
bufferLimit
;
ofn
.
lpstrTitle
=
titleBuffer
;
ofn
.
lpstrTitle
=
titleBuffer
;
ofn
.
lpstrInitialDir
=
directoryBuffer
;
ofn
.
lpstrInitialDir
=
directoryBuffer
;
ofn
.
Flags
=
OFN_LONGNAMES
|
OFN_OVERWRITEPROMPT
|
OFN_HIDEREADONLY
|
ofn
.
Flags
=
OFN_LONGNAMES
|
OFN_OVERWRITEPROMPT
|
OFN_HIDEREADONLY
|
OFN_ENABLEHOOK
|
OFN_EXPLORER
|
OFN_ENABLESIZING
;
OFN_ENABLEHOOK
|
OFN_EXPLORER
|
OFN_ENABLESIZING
;
fileFilter
=
env
->
GetObjectField
(
peer
,
fileFilter
=
env
->
GetObjectField
(
peer
,
AwtFileDialog
::
fileFilterID
);
AwtFileDialog
::
fileFilterID
);
if
(
!
JNU_IsNull
(
env
,
fileFilter
))
{
if
(
!
JNU_IsNull
(
env
,
fileFilter
))
{
ofn
.
Flags
|=
OFN_ENABLEINCLUDENOTIFY
;
ofn
.
Flags
|=
OFN_ENABLEINCLUDENOTIFY
;
}
}
ofn
.
lCustData
=
(
LPARAM
)
peer
;
ofn
.
lCustData
=
(
LPARAM
)
peer
;
ofn
.
lpfnHook
=
(
LPOFNHOOKPROC
)
FileDialogHookProc
;
ofn
.
lpfnHook
=
(
LPOFNHOOKPROC
)
FileDialogHookProc
;
if
(
multipleMode
==
JNI_TRUE
)
{
ofn
.
Flags
|=
OFN_ALLOWMULTISELECT
;
}
// Save current directory, so we can reset if it changes.
// Save current directory, so we can reset if it changes.
currentDirectory
=
new
TCHAR
[
MAX_PATH
+
1
];
currentDirectory
=
new
TCHAR
[
MAX_PATH
+
1
];
...
@@ -318,11 +367,12 @@ AwtFileDialog::Show(void *p)
...
@@ -318,11 +367,12 @@ AwtFileDialog::Show(void *p)
// Report result to peer.
// Report result to peer.
if
(
result
)
{
if
(
result
)
{
jstring
tmpJString
=
(
_tcslen
(
ofn
.
lpstrFile
)
==
0
?
jint
length
=
(
jint
)
GetBufferLength
(
ofn
.
lpstrFile
,
ofn
.
nMaxFile
);
JNU_NewStringPlatform
(
env
,
L""
)
:
jcharArray
jnames
=
env
->
NewCharArray
(
length
);
JNU_NewStringPlatform
(
env
,
ofn
.
lpstrFile
));
env
->
SetCharArrayRegion
(
jnames
,
0
,
length
,
(
jchar
*
)
ofn
.
lpstrFile
);
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
handleSelectedMID
,
tmpJString
);
env
->
DeleteLocalRef
(
tmpJString
);
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
handleSelectedMID
,
jnames
);
env
->
DeleteLocalRef
(
jnames
);
}
else
{
}
else
{
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
handleCancelMID
);
env
->
CallVoidMethod
(
peer
,
AwtFileDialog
::
handleCancelMID
);
}
}
...
@@ -338,7 +388,8 @@ AwtFileDialog::Show(void *p)
...
@@ -338,7 +388,8 @@ AwtFileDialog::Show(void *p)
env
->
DeleteGlobalRef
(
peer
);
env
->
DeleteGlobalRef
(
peer
);
delete
[]
currentDirectory
;
delete
[]
currentDirectory
;
delete
[]
fileBuffer
;
if
(
ofn
.
lpstrFile
)
delete
[]
ofn
.
lpstrFile
;
throw
;
throw
;
}
}
...
@@ -351,7 +402,8 @@ AwtFileDialog::Show(void *p)
...
@@ -351,7 +402,8 @@ AwtFileDialog::Show(void *p)
env
->
DeleteGlobalRef
(
peer
);
env
->
DeleteGlobalRef
(
peer
);
delete
[]
currentDirectory
;
delete
[]
currentDirectory
;
delete
[]
fileBuffer
;
if
(
ofn
.
lpstrFile
)
delete
[]
ofn
.
lpstrFile
;
}
}
BOOL
BOOL
...
@@ -416,6 +468,18 @@ void AwtFileDialog::_ToBack(void *param)
...
@@ -416,6 +468,18 @@ void AwtFileDialog::_ToBack(void *param)
env
->
DeleteGlobalRef
(
self
);
env
->
DeleteGlobalRef
(
self
);
}
}
// Returns the length of the double null terminated output buffer
UINT
AwtFileDialog
::
GetBufferLength
(
LPTSTR
buffer
,
UINT
limit
)
{
UINT
index
=
0
;
while
((
index
<
limit
)
&&
(
buffer
[
index
]
!=
NULL
||
buffer
[
index
+
1
]
!=
NULL
))
{
index
++
;
}
return
index
;
}
/************************************************************************
/************************************************************************
* WFileDialogPeer native methods
* WFileDialogPeer native methods
*/
*/
...
@@ -434,11 +498,12 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
...
@@ -434,11 +498,12 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
AwtFileDialog
::
setHWndMID
=
AwtFileDialog
::
setHWndMID
=
env
->
GetMethodID
(
cls
,
"setHWnd"
,
"(J)V"
);
env
->
GetMethodID
(
cls
,
"setHWnd"
,
"(J)V"
);
AwtFileDialog
::
handleSelectedMID
=
AwtFileDialog
::
handleSelectedMID
=
env
->
GetMethodID
(
cls
,
"handleSelected"
,
"(
Ljava/lang/String;
)V"
);
env
->
GetMethodID
(
cls
,
"handleSelected"
,
"(
[C
)V"
);
AwtFileDialog
::
handleCancelMID
=
AwtFileDialog
::
handleCancelMID
=
env
->
GetMethodID
(
cls
,
"handleCancel"
,
"()V"
);
env
->
GetMethodID
(
cls
,
"handleCancel"
,
"()V"
);
AwtFileDialog
::
checkFilenameFilterMID
=
AwtFileDialog
::
checkFilenameFilterMID
=
env
->
GetMethodID
(
cls
,
"checkFilenameFilter"
,
"(Ljava/lang/String;)Z"
);
env
->
GetMethodID
(
cls
,
"checkFilenameFilter"
,
"(Ljava/lang/String;)Z"
);
AwtFileDialog
::
isMultipleModeMID
=
env
->
GetMethodID
(
cls
,
"isMultipleMode"
,
"()Z"
);
/* java.awt.FileDialog fields */
/* java.awt.FileDialog fields */
cls
=
env
->
FindClass
(
"java/awt/FileDialog"
);
cls
=
env
->
FindClass
(
"java/awt/FileDialog"
);
...
@@ -455,6 +520,7 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
...
@@ -455,6 +520,7 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
DASSERT
(
AwtFileDialog
::
setHWndMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
setHWndMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
handleSelectedMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
handleSelectedMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
handleCancelMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
handleCancelMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
isMultipleModeMID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
modeID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
modeID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
dirID
!=
NULL
);
DASSERT
(
AwtFileDialog
::
dirID
!=
NULL
);
...
...
src/windows/native/sun/windows/awt_FileDialog.h
浏览文件 @
b5478b37
...
@@ -49,6 +49,7 @@ public:
...
@@ -49,6 +49,7 @@ public:
static
jmethodID
handleSelectedMID
;
static
jmethodID
handleSelectedMID
;
static
jmethodID
handleCancelMID
;
static
jmethodID
handleCancelMID
;
static
jmethodID
checkFilenameFilterMID
;
static
jmethodID
checkFilenameFilterMID
;
static
jmethodID
isMultipleModeMID
;
/* java.awt.FileDialog field and method ids */
/* java.awt.FileDialog field and method ids */
static
jfieldID
modeID
;
static
jfieldID
modeID
;
...
@@ -68,6 +69,9 @@ public:
...
@@ -68,6 +69,9 @@ public:
static
void
_DisposeOrHide
(
void
*
param
);
static
void
_DisposeOrHide
(
void
*
param
);
static
void
_ToFront
(
void
*
param
);
static
void
_ToFront
(
void
*
param
);
static
void
_ToBack
(
void
*
param
);
static
void
_ToBack
(
void
*
param
);
private:
static
UINT
GetBufferLength
(
LPTSTR
buffer
,
UINT
limit
);
};
};
#endif
/* FILE_DIALOG_H */
#endif
/* FILE_DIALOG_H */
test/java/awt/FileDialog/MultipleMode/MultipleMode.html
0 → 100644
浏览文件 @
b5478b37
<html>
<!--
@test
@bug 6467204
@summary Need to implement "extended" native FileDialog for JFileChooser
@author dmitry.cherepanov@sun.com area=awt.filedialog
@run applet/manual=yesno MultipleMode.html
-->
<head>
<title>
MultipleMode
</title>
</head>
<body>
<h1>
MultipleMode
<br>
Bug ID: 6467204
</h1>
<p>
See the dialog box (usually in upper left corner) for instructions
</p>
<APPLET
CODE=
"MultipleMode.class"
WIDTH=
200
HEIGHT=
200
></APPLET>
</body>
</html>
test/java/awt/FileDialog/MultipleMode/MultipleMode.java
0 → 100644
浏览文件 @
b5478b37
/*
* Copyright 2010 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 6467204
@summary Need to implement "extended" native FileDialog for JFileChooser
@author dmitry.cherepanov@sun.com area=awt.filedialog
@run applet/manual=yesno MultipleMode.html
*/
// Note there is no @ in front of test above. This is so that the
// harness will not mistake this file as a test file. It should
// only see the html file as a test file. (the harness runs all
// valid test files, so it would run this test twice if this file
// were valid as well as the html file.)
// Also, note the area= after Your Name in the author tag. Here, you
// should put which functional area the test falls in. See the
// AWT-core home page -> test areas and/or -> AWT team for a list of
// areas.
// There are several places where ManualYesNoTest appear. It is
// recommended that these be changed by a global search and replace,
// such as ESC-% in xemacs.
/**
* MultipleMode.java
*
* summary:
*/
import
java.applet.Applet
;
import
java.awt.*
;
import
java.awt.event.*
;
import
java.io.File
;
//Manual tests should run as applet tests if possible because they
// get their environments cleaned up, including AWT threads, any
// test created threads, and any system resources used by the test
// such as file descriptors. (This is normally not a problem as
// main tests usually run in a separate VM, however on some platforms
// such as the Mac, separate VMs are not possible and non-applet
// tests will cause problems). Also, you don't have to worry about
// synchronisation stuff in Applet tests the way you do in main
// tests...
public
class
MultipleMode
extends
Applet
{
//Declare things used in the test, like buttons and labels here
public
void
init
()
{
//Create instructions for the user here, as well as set up
// the environment -- set the layout manager, add buttons,
// etc.
this
.
setLayout
(
new
BorderLayout
());
String
[]
instructions
=
{
" 1. Turn the 'multiple' checkbox off and press the 'open' button "
,
" 2. Verify that the file dialog doesn't allow the multiple file selection "
,
" 3. Select any file and close the file dialog "
,
" 4. The results will be displayed, verify the results "
,
" 5. Turn the 'multiple' checkbox on and press the 'open' button "
,
" 6. Verify that the file dialog allows the multiple file selection "
,
" 7. Select several files and close the file dialog "
,
" 8. The results will be displayed, verify the results "
};
Sysout
.
createDialogWithInstructions
(
instructions
);
}
//End init()
public
void
start
()
{
final
Checkbox
mode
=
new
Checkbox
(
"multiple"
,
true
);
Button
open
=
new
Button
(
"open"
);
open
.
addActionListener
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
FileDialog
d
=
new
FileDialog
((
Frame
)
null
);
d
.
setMultipleMode
(
mode
.
getState
());
d
.
setVisible
(
true
);
// print the results
Sysout
.
println
(
"DIR:"
);
Sysout
.
println
(
d
.
getDirectory
());
Sysout
.
println
(
"FILE:"
);
Sysout
.
println
(
d
.
getFile
());
Sysout
.
println
(
"FILES:"
);
File
files
[]
=
d
.
getFiles
();
for
(
File
f
:
files
)
{
Sysout
.
println
(
String
.
valueOf
(
f
));
}
}
});
setLayout
(
new
FlowLayout
());
add
(
mode
);
add
(
open
);
//Get things going. Request focus, set size, et cetera
setSize
(
200
,
200
);
setVisible
(
true
);
validate
();
}
// start()
//The rest of this class is the actions which perform the test...
//Use Sysout.println to communicate with the user NOT System.out!!
//Sysout.println ("Something Happened!");
}
// class ManualYesNoTest
/* Place other classes related to the test after this line */
/****************************************************
Standard Test Machinery
DO NOT modify anything below -- it's a standard
chunk of code whose purpose is to make user
interaction uniform, and thereby make it simpler
to read and understand someone else's test.
****************************************************/
/**
This is part of the standard test machinery.
It creates a dialog (with the instructions), and is the interface
for sending text messages to the user.
To print the instructions, send an array of strings to Sysout.createDialog
WithInstructions method. Put one line of instructions per array entry.
To display a message for the tester to see, simply call Sysout.println
with the string to be displayed.
This mimics System.out.println but works within the test harness as well
as standalone.
*/
class
Sysout
{
private
static
TestDialog
dialog
;
private
static
boolean
numbering
=
false
;
private
static
int
messageNumber
=
0
;
public
static
void
createDialogWithInstructions
(
String
[]
instructions
)
{
dialog
=
new
TestDialog
(
new
Frame
(),
"Instructions"
);
dialog
.
printInstructions
(
instructions
);
dialog
.
setVisible
(
true
);
println
(
"Any messages for the tester will display here."
);
}
public
static
void
createDialog
(
)
{
dialog
=
new
TestDialog
(
new
Frame
(),
"Instructions"
);
String
[]
defInstr
=
{
"Instructions will appear here. "
,
""
}
;
dialog
.
printInstructions
(
defInstr
);
dialog
.
setVisible
(
true
);
println
(
"Any messages for the tester will display here."
);
}
/* Enables message counting for the tester. */
public
static
void
enableNumbering
(
boolean
enable
){
numbering
=
enable
;
}
public
static
void
printInstructions
(
String
[]
instructions
)
{
dialog
.
printInstructions
(
instructions
);
}
public
static
void
println
(
String
messageIn
)
{
if
(
numbering
)
{
messageIn
=
""
+
messageNumber
+
" "
+
messageIn
;
messageNumber
++;
}
dialog
.
displayMessage
(
messageIn
);
}
}
// Sysout class
/**
This is part of the standard test machinery. It provides a place for the
test instructions to be displayed, and a place for interactive messages
to the user to be displayed.
To have the test instructions displayed, see Sysout.
To have a message to the user be displayed, see Sysout.
Do not call anything in this dialog directly.
*/
class
TestDialog
extends
Dialog
{
TextArea
instructionsText
;
TextArea
messageText
;
int
maxStringLength
=
80
;
//DO NOT call this directly, go through Sysout
public
TestDialog
(
Frame
frame
,
String
name
)
{
super
(
frame
,
name
);
int
scrollBoth
=
TextArea
.
SCROLLBARS_BOTH
;
instructionsText
=
new
TextArea
(
""
,
15
,
maxStringLength
,
scrollBoth
);
add
(
"North"
,
instructionsText
);
messageText
=
new
TextArea
(
""
,
5
,
maxStringLength
,
scrollBoth
);
add
(
"Center"
,
messageText
);
pack
();
setVisible
(
true
);
}
// TestDialog()
//DO NOT call this directly, go through Sysout
public
void
printInstructions
(
String
[]
instructions
)
{
//Clear out any current instructions
instructionsText
.
setText
(
""
);
//Go down array of instruction strings
String
printStr
,
remainingStr
;
for
(
int
i
=
0
;
i
<
instructions
.
length
;
i
++
)
{
//chop up each into pieces maxSringLength long
remainingStr
=
instructions
[
i
];
while
(
remainingStr
.
length
()
>
0
)
{
//if longer than max then chop off first max chars to print
if
(
remainingStr
.
length
()
>=
maxStringLength
)
{
//Try to chop on a word boundary
int
posOfSpace
=
remainingStr
.
lastIndexOf
(
' '
,
maxStringLength
-
1
);
if
(
posOfSpace
<=
0
)
posOfSpace
=
maxStringLength
-
1
;
printStr
=
remainingStr
.
substring
(
0
,
posOfSpace
+
1
);
remainingStr
=
remainingStr
.
substring
(
posOfSpace
+
1
);
}
//else just print
else
{
printStr
=
remainingStr
;
remainingStr
=
""
;
}
instructionsText
.
append
(
printStr
+
"\n"
);
}
// while
}
// for
}
//printInstructions()
//DO NOT call this directly, go through Sysout
public
void
displayMessage
(
String
messageIn
)
{
messageText
.
append
(
messageIn
+
"\n"
);
System
.
out
.
println
(
messageIn
);
}
}
// TestDialog class
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录