实现一个JAVA Game—— Hang man Game可视化编程
1.游戏截图:
模块设计
2.1 班( class的名词复数 )
这个项目包括三个类别:HangmanL词汇on和HangmanPanel。每一班将详细说明如下:
2.2 HangmanLexicon
创建这个类是为了读取HangmanLDicon.txt文件,并从这个txt文件中随机选择一个单词。
2.2.1公共汉曼词典(String词汇表FileDir)
这个函数是构造函数。它将读取easy.txt、medium.txt和hard.txt文件,将每一行视为给定的Hangman词汇表文件中的一个单词,并将该单词存储到不同的列表中(容易) 单词列表,中间单词列表和硬单词列表)。在easy.txt中,每个单词有4~6个字母,中间单词有7~10个字母,hard.txt中有10个字母。
2.2.2公共字符串随机选择Word(int级)
随机选择一个具有给定级别的单词,其中0表示容易级别,1表示中等级别,2表示硬级别。
2.3 HangmanPanel
这个类用于绘制Hangman,面板是作为游戏GUI的左侧组件创建的。这个类扩展了javax.swing.JPanel
2.3.1私人不法猜测;
用于记录错误猜测计数的私有非静态值,它是用0初始化的。
2.3.2公共无效涂料成分(图形g)
根据错误的估计画绞刑架,如果错误的数字等于0,只画脚手架,如果错误的数字等于1,画脚手架和头,如果错误的数字等于2,画脚手架,头和身体,如果错误的话。 SES等于3,绘制脚手架头、车身和左臂...如果错误猜测等于6,请绘制整个朝鲜人。
2.3.3公共无效增量--WrongGuess()
增加错误值,并重新绘制组件。
2.3.4公空重设()
让错误的数字等于0并重新绘制组件,在重新启动游戏时调用。
Hangman.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
import
java.awt.Container;
import
java.awt.Font;
import
java.awt.event.ActionEvent;
import
java.awt.event.ActionListener;
import
java.awt.event.KeyAdapter;
import
java.awt.event.KeyEvent;
import
java.awt.event.WindowAdapter;
import
java.awt.event.WindowEvent;
import
java.util.HashSet;
import
javax.swing.JFrame;
import
javax.swing.JLabel;
import
javax.swing.JMenu;
import
javax.swing.JMenuBar;
import
javax.swing.JMenuItem;
import
javax.swing.JOptionPane;
import
javax.swing.JPanel;
import
javax.swing.JTextField;
import
javax.swing.border.EmptyBorder;
public
class
Hangman
extends
JFrame{
private
final
int
MAX_WRONG_GUESSES =
6
;
// record the incorrect count
private
int
incorrectCount;
private
Container content;
private
JMenuBar menuBar;
private
JMenu menuStart;
private
JMenuItem menuItemRestart;
// panel containing displayedCharsPanel, inputPanel and missesPanel
private
JPanel rightPanel;
// right guessed chars
private
JLabel displayedCharsLabel;
private
JTextField displayedCharsTextField;
// input field
private
JLabel inputLabel;
private
JTextField inputTextField;
// misses prompt
private
JLabel missesLabel;
private
JTextField missesTextField;
private
HangmanPanel hangmanPanel;
private
HangmanLexicon hangmanLexicon;
// This is the word being guessed
private
String hiddenWord;
// display right letters
private
char
[] displayedLetters;
private
char
[] correctLetters;
//This set keeps track of all the incorrect guessed letters
private
HashSet missedLettersSet =
new
HashSet();
private
String missedLetters =
""
;
public
Hangman() {
super
(
"HangmanGame"
);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// initialize hangmanLexicon used to random select word
hangmanLexicon =
new
HangmanLexicon(
"data"
);
//creates a JMenuBar at the top of the GUI
menuBar =
new
JMenuBar();
menuStart =
new
JMenu(
"start"
);
menuItemRestart =
new
JMenuItem(
"Restart"
);
menuItemRestart.addActionListener(
new
MenuHandler());
menuStart.add(menuItemRestart);
menuBar.add(menuStart);
// set content layout
content = getContentPane();
setLayout(
null
);
setSize(
800
,
500
);
// create hangman panel and right panel
hangmanPanel =
new
HangmanPanel();
setupRightPannel();
content.add(hangmanPanel);
hangmanPanel.setBounds(-
50
,
0
,
400
,
400
);
content.add(rightPanel);
rightPanel.setBounds(
400
,
0
,
400
,
400
);
setJMenuBar(menuBar);
// focus on input textfield when window show on
addWindowListener(
new
WindowAdapter() {
public
void
windowOpened( WindowEvent e ){
inputTextField.requestFocus();
}
});
setLocationRelativeTo(
null
);
// place the window in the center of the screen.
setVisible(
true
);
//makes the JFrame visible
selectDifficultyLevel();
// create a optionPane and select difficulty level
}
private
void
setupRightPannel() {
// create rightPanel
rightPanel =
new
JPanel();
rightPanel.setLayout(
null
);
Font newFont =
new
Font(Font.SANS_SERIF,Font.PLAIN,
20
);
//Creates a new Font
displayedCharsLabel =
new
JLabel(
"Word:"
);
displayedCharsLabel.setFont(newFont);
displayedCharsTextField =
new
JTextField(
20
);
displayedCharsTextField.setEditable(
false
);
displayedCharsTextField.setFont(newFont);
displayedCharsTextField.setBorder(
new
EmptyBorder(
0
,
0
,
0
,
0
));
displayedCharsTextField.setOpaque(
false
);
rightPanel.add(displayedCharsLabel);
rightPanel.add(displayedCharsTextField);
displayedCharsLabel.setBounds(
0
,
50
,
80
,
20
);
displayedCharsTextField.setBounds(
80
,
35
,
250
,
50
);
inputLabel =
new
JLabel(
"Guess:"
);
inputLabel.setFont(newFont);
inputTextField =
new
JTextField(
5
);
inputTextField.setEditable(
true
);
inputTextField.setFont(newFont);
rightPanel.add(inputLabel);
rightPanel.add(inputTextField);
inputLabel.setBounds(
0
,
150
,
80
,
20
);
inputTextField.setBounds(
80
,
130
,
50
,
50
);
inputTextField.addKeyListener(
new
inputKeyListener());
missesLabel =
new
JLabel(
"Misses:"
);
missesLabel.setFont(newFont);
missesTextField =
new
JTextField(
5
);
missesTextField.setEditable(
false
);
missesTextField.setFont(newFont);
missesTextField.setBorder(
new
EmptyBorder(
0
,
0
,
0
,
0
));
missesTextField.setOpaque(
false
);
rightPanel.add(missesLabel);
rightPanel.add(missesTextField);
missesLabel.setBounds(
0
,
250
,
80
,
20
);
missesTextField.setBounds(
80
,
230
,
250
,
50
);
}
private
void
selectDifficultyLevel() {
String[] options = {
"Easy"
,
"Medium"
,
"Hard"
};
int
level = JOptionPane.showOptionDialog(
null
,
"Select difficulty level of words(easy 4-6 letters, Medium 7-10 letters, Hard 10+ letters)"
,
"Difficulty Level"
, JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null
, options, options[
0
]);
System.out.println(
"level: "
+ options[level]);
hiddenWord = hangmanLexicon.randomSelectWord(level).toUpperCase();
System.out.println(hiddenWord +
", length:"
+ hiddenWord.length());
// set displayedChars
displayedLetters =
new
char
[hiddenWord.length() *
2
-
1
];
correctLetters =
new
char
[hiddenWord.length()];
for
(
int
i =
0
; i < displayedLetters.length; i++) {
if
(i %
2
==
0
)
displayedLetters[i] =
'_'
;
else
displayedLetters[i] =
' '
;
}
displayedCharsTextField.setText(String.copyValueOf(displayedLetters));
}
/**
* when enter key is pressed, check letter
*/
private
class
inputKeyListener
extends
KeyAdapter {
@Override
public
void
keyReleased(KeyEvent e) {
if
(e.getKeyCode() == KeyEvent.VK_ENTER){
if
(inputTextField.getText().length() >
1
) {
JOptionPane.showMessageDialog(
new
JFrame(),
"Please guess one letter at a time!"
,
"Warninig"
, JOptionPane.WARNING_MESSAGE);
}
else
if
(inputTextField.getText().length() ==
1
) {
char
letter = inputTextField.getText().toUpperCase().charAt(
0
);
if
(!(letter >=
'A'
&& letter <=
'Z'
))
JOptionPane.showMessageDialog(
new
JFrame(),
"Please input a letter!"
,
"Warninig"
, JOptionPane.WARNING_MESSAGE);
else
checkLetter(letter);
}
inputTextField.setText(
""
);
}
}
}
/**
* check the input letter
* @param letter input letter
*/
private
void
checkLetter(
char
letter) {
int
index = hiddenWord.indexOf(letter);
// hiddenWord doesn't contain the given letter
if
(index <
0
) {
incorrectCount++;
hangmanPanel.incrementWrongGuesses();
// when wrong guess count greater than max wrong guesses, loss
if
(incorrectCount >= MAX_WRONG_GUESSES) {
String[] options = {
"Restart"
,
"Quit"
};
int
level = JOptionPane.showOptionDialog(
null
,
"You lose - the answer was "
+ hiddenWord +
"."
,
"You lose"
, JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null
, options, options[
0
]);
if
(level ==
0
)
restart();
else
System.exit(
0
);
}
else
{
if
(!missedLettersSet.contains(letter)) {
missedLettersSet.add(letter);
if
(missedLetters.isEmpty())
missedLetters = String.valueOf(letter);
else
missedLetters +=
","
+ letter;
// displayed missed letters
missesTextField.setText(missedLetters);
}
}
}
else
{
// if guess right, writes it in all its correct positions.
for
(
int
i =
0
; i < hiddenWord.length(); i++) {
if
(hiddenWord.charAt(i) == letter) {
displayedLetters[i *
2
] = letter;
correctLetters[i] = letter;
}
}
displayedCharsTextField.setText(String.copyValueOf(displayedLetters));
// check whether guess win
if
(String.copyValueOf(correctLetters).equals(hiddenWord)) {
String[] options = {
"Restart"
,
"Quit"
};
int
level = JOptionPane.showOptionDialog(
null
,
"You win - the answer was "
+ hiddenWord +
"."
,
"You win"
, JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null
, options, options[
0
]);
if
(level ==
0
)
restart();
else
System.exit(
0
);
}
}
}
private
class
MenuHandler
implements
ActionListener {
@Override
public
void
actionPerformed (ActionEvent e) {
if
(e.getSource() == menuItemRestart) {
restart();
}
}
}
/**
* restart game
*/
private
void
restart() {
missedLettersSet =
new
HashSet();
incorrectCount =
0
;
missesTextField.setText(
""
);
missedLetters =
""
;
hangmanPanel.reset();
selectDifficultyLevel();
}
public
static
void
main(String[] args) {
Hangman hangman =
new
Hangman();
}
}
|
HangmanLexicon.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import
java.io.BufferedReader;
import
java.io.File;
import
java.io.FileReader;
import
java.io.IOException;
import
java.util.ArrayList;
import
java.util.Random;
public
class
HangmanLexicon {
public
static
final
int
EASY =
0
;
// words with 4~6 letters
public
static
final
int
MEDIUM =
1
;
// words with 7~10 letters
public
static
final
int
HARD =
2
;
// words with 10+ letters
private
ArrayList easyWordList =
new
ArrayList();
private
ArrayList mediumWordList =
new
ArrayList();
private
ArrayList hardWordList =
new
ArrayList();
public
HangmanLexicon(String lexiconFileDir) {
try
{
// read easy.txt
BufferedReader hangmanWords =
new
BufferedReader(
new
FileReader(
new
File(lexiconFileDir,
"easy.txt"
)));
String line;
while
((line = hangmanWords.readLine()) !=
null
) {
line = line.toUpperCase();
easyWordList.add(line);
}
hangmanWords.close();
// read medium.txt
hangmanWords =
new
BufferedReader(
new
FileReader(
new
File(lexiconFileDir,
"medium.txt"
)));
while
((line = hangmanWords.readLine()) !=
null
) {
line = line.toUpperCase();
mediumWordList.add(line);
}
hangmanWords.close();
// read hard.txt
hangmanWords =
new
BufferedReader(
new
FileReader(
new
File(lexiconFileDir,
"hard.txt"
)));
while
((line = hangmanWords.readLine()) !=
null
) {
line = line.toUpperCase();
hardWordList.add(line);
}
hangmanWords.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
/** Returns the word at the specified index. */
public
String randomSelectWord(
int
level) {
ArrayList wordList =
null
;
switch
(level) {
case
0
:
wordList = easyWordList;
break
;
case
1
:
wordList = mediumWordList;
break
;
case
2
:
wordList = hardWordList;
break
;
default
:
wordList = easyWordList;
}
int
size = wordList.size();
Random rand =
new
Random();
int
index = rand.nextInt(size);
return
wordList.get(index);
}
}
|
HangmanPanel.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
import
java.awt.BasicStroke;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
javax.swing.JPanel;
public
class
HangmanPanel
extends
JPanel {
// wrong guessed count
private
int
wrongGuesses;
/* Constants for the simple version of the picture (in pixels) */
private static final int SCAFFOLD_WIFTH = 20;
private static final int BEAM_WIDTH = 12;
private static final int HANGMAN_WIDTH = 5;
private static final int SCAFFOLD_HEIGHT = 300;
private static final int BEAM_LENGTH = 120;
private static final int ROPE_LENGTH = 20;
private static final int BASE_LENGTH = 200;
private static final int HEAD_RADIUS = 36;
private static final int BODY_LENGTH = 110;
private static final int ARM_LENGTH = 70;
private static final int ARM_ANGLE = 30;
private static final int LEG_LENGTH = 85;
private static final int LEG_ANGLE = 45;
/**
* This method should never be directly invoked, but is invoked by the repaint() method.
* Depending on the number of wrongGuesses, it knows which body parts to draw. It also
* sets the stroke of the lines so they are thicker than the default setting.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// paint scaffold
drawScaffold(g2d);
// paint hangman
if (wrongGuesses == 1) {
drawHead(g2d);
} else if (wrongGuesses == 2) {
drawHead(g2d);
drawBody(g2d);
} else if (wrongGuesses == 3) {
drawHead(g2d);
drawBody(g2d);
drawLeftArm(g2d);
} else if (wrongGuesses == 4) {
drawHead(g2d);
drawBody(g2d);
drawLeftArm(g2d);
drawRightArm(g2d);
} else if (wrongGuesses == 5) {
drawHead(g2d);
drawBody(g2d);
drawLeftArm(g2d);
drawRightArm(g2d);
drawLeftLeg(g2d);
} else if (wrongGuesses == 6) {
drawHead(g2d);
drawBody(g2d);
drawLeftArm(g2d);
drawRightArm(g2d);
drawLeftLeg(g2d);
drawRightLeg(g2d);
}
}
/**
* Increments wrongGuesses, then repaints the man
*/
public void incrementWrongGuesses(){
wrongGuesses++;
repaint();
}
/**
* Resets wrongGuesses back to zero and repaints the pain
*/
public
void
reset() {
wrongGuesses =
0
;
repaint();
}
private
void
drawScaffold(Graphics2D g2d) {
// draw scaffold
g2d.setStroke(
new
BasicStroke((
float
)SCAFFOLD_WIFTH));
int
scaffoldX = getWidth()/
2
+ BEAM_LENGTH;
int
scaffoldTopY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
;
int
scaffoldBottomY = getHeight()/
2
+ SCAFFOLD_HEIGHT/
2
;
g2d.drawLine(scaffoldX, scaffoldTopY, scaffoldX, scaffoldBottomY);
// draw base
int
baseRightX = (BASE_LENGTH - BEAM_LENGTH)/
2
+ scaffoldX;
int
baseLeftX = baseRightX - BASE_LENGTH;
int
baseY = scaffoldBottomY;
g2d.drawLine(baseLeftX, baseY, baseRightX, baseY);
// draw beam
g2d.setStroke(
new
BasicStroke((
float
)BEAM_WIDTH));
int
beamLeftX = scaffoldX - BEAM_LENGTH;
int
beamRightX = scaffoldX;
int
beamY = scaffoldTopY - (SCAFFOLD_WIFTH - BEAM_WIDTH)/
2
;
g2d.drawLine(beamLeftX, beamY, beamRightX, beamY);
// draw rope
int
ropeTopY = beamY;
int
ropeBottomY = ropeTopY + ROPE_LENGTH;
int
ropeX = beamLeftX;
g2d.drawLine(ropeX, ropeTopY, ropeX, ropeBottomY);
}
private
void
drawHead(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
x = getWidth()/
2
- HEAD_RADIUS/
2
;
int
y = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH;
g2d.drawOval(x, y, HEAD_RADIUS, HEAD_RADIUS);
}
private
void
drawBody(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
x = getWidth()/
2
+ BEAM_LENGTH - BEAM_LENGTH;
int
topY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS;
int
bottomY = topY + BODY_LENGTH;
g2d.drawLine(x, topY, x, bottomY);
}
private
void
drawLeftArm(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
rightX = getWidth()/
2
+ BEAM_LENGTH - BEAM_LENGTH;
int
rightY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH /
3
;
int
leftX = (
int
) (rightX - ARM_LENGTH * Math.cos((
double
)ARM_ANGLE /
180
* Math.PI));
int
leftY = (
int
) (rightY - ARM_LENGTH * Math.sin((
double
)ARM_ANGLE /
180
* Math.PI));
g2d.drawLine(leftX, leftY, rightX, rightY);
}
private
void
drawRightArm(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
leftX = getWidth()/
2
+ BEAM_LENGTH - BEAM_LENGTH;
int
leftY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH /
3
;
int
rightX = (
int
) (leftX + ARM_LENGTH * Math.cos((
double
)ARM_ANGLE /
180
* Math.PI));
int
rightY = (
int
) (leftY - ARM_LENGTH * Math.sin((
double
)ARM_ANGLE /
180
* Math.PI));
g2d.drawLine(leftX, leftY, rightX, rightY);
}
private
void
drawLeftLeg(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
rightX = getWidth()/
2
+ BEAM_LENGTH - BEAM_LENGTH;
int
rightY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH;
int
leftX = (
int
) (rightX - LEG_LENGTH * Math.sin((
double
)LEG_ANGLE /
180
* Math.PI));
int
leftY = (
int
) (rightY + LEG_LENGTH * Math.cos((
double
)LEG_ANGLE /
180
* Math.PI));
g2d.drawLine(leftX, leftY, rightX, rightY);
}
private
void
drawRightLeg(Graphics2D g2d) {
g2d.setStroke(
new
BasicStroke((
float
)HANGMAN_WIDTH));
int
leftX = getWidth()/
2
+ BEAM_LENGTH - BEAM_LENGTH;
int
leftY = getHeight()/
2
- SCAFFOLD_HEIGHT/
2
- SCAFFOLD_WIFTH/
2
+ BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH;
int
rightX = (
int
) (leftX + LEG_LENGTH * Math.cos((
double
)LEG_ANGLE /
180
* Math.PI));
int
rightY = (
int
) (leftY + LEG_LENGTH * Math.sin((
double
)LEG_ANGLE /
180
* Math.PI));
g2d.drawLine(leftX, leftY, rightX, rightY);
}
}
|
代写CS&Finance|建模|代码|系统|报告|考试|
编程类:C++,JAVA ,数据库,WEB,Linux,Nodejs,JSP,Html,Prolog,Python,Haskell,hadoop算法,系统 机器学习
金融类:统计,计量,数据科学,风险投资,金融工程,R语言,Python语言,Matlab,建立模型,数据分析,数据处理
服务类:Lab/Assignment/Project/Course/Qzui/Midterm/Final/Exam/Test帮助代写代考辅导/原创只
E-mail:850190831@qq.com 微信:BadGeniuscs 工作时间:无休息工作日-早上8点到凌晨3点
如果您用的手机请先保存二维码到手机里面,识别图中二维码。如果用电脑,直接掏出手机果断扫描。
转载:https://uhomework.com/a/JAVA/20180423/10181.html 天才写手 代写CS 代写JAVA