小弟刚学java几天,想请教大虾们,怎样用java现有的图形部件构造一个密码确认对话框?
具体要求如下:
________________________________________
| |
| 对话框标题栏 |
|----------------------------------------|
| Please input the password: |
| ________________________ |
| | | |
| |****** | |
| |________________________| |
| |
| _______ _________ |
| | | | | |
| | Ok | |Cancel | |
| |_______| |_________| |
|________________________________________| 当输入密码后,如果按下'Ok'按钮:
如果密码正确则做某个动作(在我这里的关机了,呵呵);
如果密码错误,则弹出对话框提示密码错误,然后返回密码输入界面,清空输入的密码,继续等待用户输入;
如果选择'Cancel'按钮,则退出密码输入对话框,继续其他操作(在我这里是回到一个菜单了,事实上这个密码对话框是由菜单
里的一个关机选项触发的).如能指教,感激不尽啊,呵呵!
具体要求如下:
________________________________________
| |
| 对话框标题栏 |
|----------------------------------------|
| Please input the password: |
| ________________________ |
| | | |
| |****** | |
| |________________________| |
| |
| _______ _________ |
| | | | | |
| | Ok | |Cancel | |
| |_______| |_________| |
|________________________________________| 当输入密码后,如果按下'Ok'按钮:
如果密码正确则做某个动作(在我这里的关机了,呵呵);
如果密码错误,则弹出对话框提示密码错误,然后返回密码输入界面,清空输入的密码,继续等待用户输入;
如果选择'Cancel'按钮,则退出密码输入对话框,继续其他操作(在我这里是回到一个菜单了,事实上这个密码对话框是由菜单
里的一个关机选项触发的).如能指教,感激不尽啊,呵呵!
JDialog
JTextFiled
JPasswordField
JButtonswt中
Dialog
TextField
Button
用swing.继承JDialog?
然后放入:
JTextFiled: "Please input the password"
JPasswordField: password
JButton: okButton, cancelButton
???
JLabel: "Please input the password"
JTextFile:用户名(需要的话)
怎样处理JPasswordField的输入事件?
怎样处理JButton的输入事件?
是可以直接注册JDialog的事件回调来统一处理JPasswordField和JButton的输入事件?
还是应该单独为每个JPasswordField和JButton的对象注册事件处理函数?又改实现什么接口? ActionLisener? 还是什么其他的?
一大堆这样的接口,对于我这个初学者,还真是有点晕,呵呵!
实现ActionListener接口,在该事件处理中获取密码验证。
public void actionPerformed(ActionEcent e){
//////判断用户名、密码是否输入正确
}
});
package net.atgames.gamemenu;import javax.swing.JDialog;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Frame;
import javax.swing.JLabel;
//import javax.swing.JButton;
import javax.swing.JTextField;
//import javax.swing.JPasswordField;
import javax.swing.JOptionPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import net.atgames.gamemenu.joystick.Joystick;
import net.atgames.gamemenu.joystick.AtGamesJoystick;public class PowerOffDialog extends JDialog {
private static final int MAX_PSW_LEN = 10; // password max length
private short[] defPsw = { AtGamesJoystick.DIGITAL_KEY_UP,
AtGamesJoystick.DIGITAL_KEY_DOWN,
AtGamesJoystick.DIGITAL_KEY_X,
AtGamesJoystick.DIGITAL_KEY_Y };
private short[] pswBuf = new short[MAX_PSW_LEN];
private int pswBufIdx = 0;
private JLabel pswTxtLabel = new JLabel("Please input the password: " +
"(Press key 'A' to confirm, " +
"and Press key 'B' to go back to menu).");
private JTextField pswField = new JTextField(MAX_PSW_LEN);
private Joystick joystick;
PowerOffDialog() {
super((Frame)null, new String("Power Off"), true);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(pswTxtLabel);
cp.add(pswField);
setSize(540, 100);
// Set up the joystick.
joystick = AtGamesJoystick.createJoystick();
//joystick = JInputJoystick.createLogitechJoystick();
if (joystick != null) {
joystick.setListener(new JoystickListener());
joystick.startToPullStates();
} else {
System.err.println("Create joystick failed!\n");
System.exit(1);
}
}
private void updatePswField() {
String pswEchos = "";
for (int i=0; i < pswBufIdx; i++)
pswEchos += '*';
pswField.setText(pswEchos);
}
// check if user input equal the default password
private boolean pswOk() {
if (defPsw.length != pswBufIdx)
return false;
for (int i=0; i<defPsw.length; i++)
if (pswBuf[i] != defPsw[i])
return false;
return true;
}
private class JoystickListener implements Joystick.Listener {
public void notifyUpPressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_UP;
pswBufIdx++;
updatePswField();
}
}
public void notifyDownPressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_DOWN;
pswBufIdx++;
}
updatePswField();
}
public void notifyLeftPressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_LEFT;
pswBufIdx++;
}
updatePswField();
}
public void notifyRightPressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_RIGHT;
pswBufIdx++;
}
updatePswField();
}
public void notifyPreviousPagePressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_Y;
pswBufIdx++;
}
updatePswField();
}
public void notifyNextPagePressed() {
if (pswBufIdx < MAX_PSW_LEN) {
pswBuf[pswBufIdx] = AtGamesJoystick.DIGITAL_KEY_X;
pswBufIdx++;
}
updatePswField();
}
// press key 'START' to complete password input
public void notifyOkPressed() {
if (pswOk()) {
String powerOffCmd = new String("C:\\Windows\\system32\\shutdown.exe -s -f -t 0");
try {
Process p = Runtime.getRuntime().exec(powerOffCmd);
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
JOptionPane.showMessageDialog(null, "Password is error!");
pswBufIdx = 0; // clear all inputs
updatePswField();
}
}
// press key 'B' to go back to menu
public void notifyCancelPressed() {
dispose(); // close the dialog
}
// do nothing: actually we don't have 'Coin-Insert' key
public void notifyCoinInserted() {
}
}
}
对代码做点简单说明,因为在最终的应用中,不在具备PC上键盘,鼠标输入设备,而是使用我们自定义的一个
usb输入设备(下位机).有鉴于此,所以我放弃了使用JPasswordField,转而
用JTextField代替.
另外因为输入设备按键编码的特殊,已不能用一个byte来表示,所以不管是缺省密码defPsw,还是用户密码输入缓冲pswBuf都使用short.密码的最大长度为MAX_PSW_LEN.最后要说的是,程序还存在几个问题:
1. 弹出的密码对话框总是在屏幕左上角,我期望弹出的时候总在屏幕中央;
2. 输入密码的时候,输入框的光标没有随着输入移动;
3. 当用户按'A'确认输入密码时,当密码错误时,弹出的对话框(JOptionPane)还不能响应我们自定义的按键;
我正在尝试修正这几个问题,如果大家有什么建议,也请不吝赐教.由于初学(有5天了,呵呵),代码肯定粗糙,难免贻笑大方.如果大虾们觉得有什么地方要改进的,也请赐教.先谢谢了!
this.setLocationRelativeTo(null);由于没有net.atgames.gamemenu.joystick包调试不能...
// Joystick.javapackage net.atgames.gamemenu.joystick;public abstract class Joystick {
// Those are the data exposed to the rest of the menu.
protected int xAxis; // Values should be -1, 0, or 1 (left, center, right).
protected int yAxis; // Values should be -1, 0, or 1 (up, center, down).
protected boolean cancelButton;
protected boolean okButton;
protected boolean previousPageButton;
protected boolean nextPageButton;
protected boolean insertCoinButton;
protected boolean confirmButton;
public static interface Listener {
public void notifyUpPressed();
public void notifyDownPressed();
public void notifyLeftPressed();
public void notifyRightPressed();
public void notifyCancelPressed();
public void notifyOkPressed();
public void notifyPreviousPagePressed();
public void notifyNextPagePressed();
public void notifyCoinInserted();
public void notifyConfirmPressed();
}
private Listener listener;
public void setListener(Listener listener) {
this.listener = listener;
}
public abstract void startToPullStates();
public abstract void stopToPullStates();
// This should be called by the subclass.
protected void updateState(
int xAxis, // Values should be -1, 0, or 1 (left, center, right).
int yAxis, // Values should be -1, 0, or 1 (up, center, down).
boolean cancelButton,
boolean okButton,
boolean previousPageButton,
boolean nextPageButton,
boolean insertCoinButton,
boolean confirmButton) {
if (this.xAxis != -1 && xAxis == -1)
listener.notifyLeftPressed();
if (this.xAxis != 1 && xAxis == 1)
listener.notifyRightPressed();
if (this.yAxis != -1 && yAxis == -1)
listener.notifyUpPressed();
if (this.yAxis != 1 && yAxis == 1)
listener.notifyDownPressed();
if (!this.cancelButton && cancelButton)
listener.notifyCancelPressed();
if (!this.okButton && okButton)
listener.notifyOkPressed();
if (!this.previousPageButton && previousPageButton)
listener.notifyPreviousPagePressed();
if (!this.nextPageButton && nextPageButton)
listener.notifyNextPagePressed();
if (!this.insertCoinButton && insertCoinButton)
listener.notifyCoinInserted();
if (!this.confirmButton && confirmButton)
listener.notifyConfirmPressed();
this.xAxis = xAxis;
this.yAxis = yAxis;
this.cancelButton = cancelButton;
this.okButton = okButton;
this.previousPageButton = previousPageButton;
this.nextPageButton = nextPageButton;
this.insertCoinButton = insertCoinButton;
this.confirmButton = confirmButton;
}
}
package net.atgames.gamemenu.joystick;public class AtGamesJoystick extends Joystick {
public static final byte PORT_NUM = 4; // joystick input port number
public static final byte PORT_DATA_SZ = 5; // data size for each joystick port
// digital keys definition.
public static final short DIGITAL_KEY_UP = (short)(1<<0);
public static final short DIGITAL_KEY_DOWN = (short)(1<<1);
public static final short DIGITAL_KEY_LEFT = (short)(1<<2);
public static final short DIGITAL_KEY_RIGHT = (short)(1<<3);
public static final short DIGITAL_KEY_A = (short)(1<<4);
public static final short DIGITAL_KEY_B = (short)(1<<5);
public static final short DIGITAL_KEY_X = (short)(1<<6);
public static final short DIGITAL_KEY_Y = (short)(1<<7);
public static final short DIGITAL_KEY_START = (short)(1<<8);
private short[] recvBuf; // joystick receive buffer
private StatePuller statePuller;
// import native interface.
private native boolean open();
private native void close();
private native int read(short[] buf);
private native int write(short[] buf);
// load native joystick library STM32Joystick.dll.
static {
System.loadLibrary("STM32Joystick");
}
public static AtGamesJoystick createJoystick() {
return new AtGamesJoystick();
}
//@Override
public void startToPullStates() {
// Launch the update loop.
statePuller = new StatePuller();
new Thread(statePuller).start();
} //@Override
public void stopToPullStates() {
statePuller.requestStop();
}
private class StatePuller implements Runnable {
private boolean stopRequested;
private int currXAxis, currYAxis;
private boolean currCancelBtn, currOkBtn;
private boolean prevPageBtn, nextPageBtn;
private boolean coinInserted;
private boolean confirmBtn;
public void requestStop() {
stopRequested = true;
}
public void transInput() {
/*
* recvBuf[] map:
* recvBuf[0]: coin insert signal status;
* recvBuf[1]: player 1's digital keys(Arrows, A, B, X, Y, START);
* recvBuf[2~5]: player 1's anolog keys(x-axis, y-axis, L, R);
* recvBuf[6]: player 2's digital keys(Arrows, A, B, X, Y, START);
* recvBuf[7~10]: player 2's anolog keys(x-axis, y-axis, L, R);
* recvBuf[11]: player 3's digital keys(Arrows, A, B, X, Y, START);
* recvBuf[12~15]: player 3's anolog keys(x-axis, y-axis, L, R);
* recvBuf[16]: player 4's digital keys(Arrows, A, B, X, Y, START);
* recvBuf[17~20]: player 4's anolog keys(x-axis, y-axis, L, R).
*/
currXAxis = currYAxis = 0;
currCancelBtn = currOkBtn = false;
prevPageBtn = nextPageBtn = false;
coinInserted = false;
confirmBtn = false;
if ((recvBuf[1] & DIGITAL_KEY_LEFT) != 0) currXAxis = -1;
else if ((recvBuf[1] & DIGITAL_KEY_RIGHT) != 0) currXAxis = 1;
if ((recvBuf[1] & DIGITAL_KEY_UP) != 0) currYAxis = -1;
else if ((recvBuf[1] & DIGITAL_KEY_DOWN) != 0) currYAxis = 1;
if ((recvBuf[1] & DIGITAL_KEY_B) != 0) currCancelBtn = true;
//if ((recvBuf[1] & DIGITAL_KEY_X) != 0) currOkBtn = true;
if ((recvBuf[1] & DIGITAL_KEY_START) != 0) currOkBtn = true;
if ((recvBuf[1] & DIGITAL_KEY_Y) != 0) prevPageBtn = true;
if ((recvBuf[1] & DIGITAL_KEY_X) != 0) nextPageBtn = true;
if (recvBuf[0] != 0) coinInserted = true;
if ((recvBuf[1] & DIGITAL_KEY_A) != 0) confirmBtn = true;
}
public void run() {
// You can initialize native stuffs here, if needed.
if (!open()) {
System.err.println("AtGamesJoystick: open device failure!");
System.exit(1);
}
// create input buffer
recvBuf = new short[1 + PORT_NUM*PORT_DATA_SZ];
while (!stopRequested) {
// Pull the state of AtGames's joystick.
// <TODO: implement me>
if (read(recvBuf) == 0) {
System.err.println("AtGamesJoystick: read failure!");
}
// translate input
transInput();
// Then send the states to the game menu's program.
// JInputJoystick.this.updateState(<TODO: place the values here>);
updateState(currXAxis, currYAxis, currCancelBtn, currOkBtn,
prevPageBtn, nextPageBtn, coinInserted, confirmBtn);
// We wait a little bit.
try {Thread.sleep(20);}
catch (InterruptedException ex) {}
}
// You can release native stuffs here, if needed.
//close();
}
}
}
谢谢楼上兄弟 'friskyliu' 的指教.
public void setCaretPosition(int position)
试试~~~
每输入一个将光标设置到末尾。JOptionPane是一个弹出组件,可控比较的少。
建议不用弹出错误框,直接在PowerOffDialog上打印一行提示密码错误的方式来实现。