1.用一个主窗体,在主窗体上放置两个子窗体,一个是文本面板,一个是模拟键盘面板。
2.文本面板分两个子面板,一个是已有文本,一个是输入文本,在带输入文本面板上添加文件监听器,动态改变下一个带输入的key,从而改变面板上的提示输入key。
3.通过java swing绘制好模拟键盘面板,加深键盘颜色动态提示下一个正确的key,并改变当前下压键盘键的颜色,通过paintcomponent方法实现。
4.启动线程记录游戏时间,匹配正确、错误输入字数,动态显示在面板上。
5.PublicData存放所有类共享的数据:key、text、curkey、texttag。
MainFrame.java(主窗体)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.*;
public class MainFrame extends JDesktopPane implements ActionListener{
public static void main(String args[]) {
try {
System.out.println("Test MainFrame.");
MainFrame mainframe = new MainFrame();
mainframe.setVisible(true);
}catch(Exception e) {
e.printStackTrace();
}
}
/**
*
*/
private static final long serialVersionUID = 1L;
Dimension screen;
Toolkit toolkit=Toolkit.getDefaultToolkit();
private JMenuBar fMenu;
private JMenu fMenuSys;//系统
private JMenu fMenuLx;//练习
private JMenuItem fMenuKey;//键盘练习
private JMenuItem fMenuExit;//退出
private JMenuItem fMenuLoad;//导入文本
private JMenuItem fMenuRefresh;//刷新文本
private JMenuItem fMenuCoverkb;//隐藏提示键盘
private JMenuItem fMenuOpenkb;//打开提示键盘
//住窗体有两个子窗体,作为主窗体的属性调用时更加方便
JInternalFrame jianpan;
Editor edit;
boolean isInit=false;
JFrame frame;
public MainFrame(){
JFrame.setDefaultLookAndFeelDecorated(true);//加上一个边框
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置点击关闭退出程序
Container container = frame.getContentPane();
container.add(this, BorderLayout.CENTER); //居中排布,JDesktopPane 放在JFrame上
this.setPreferredSize(new java.awt.Dimension(657, 550));
frame.setTitle("疯狂打字通 XXX 2.0 pro max plus");//设置标题
Image ico=Toolkit.getDefaultToolkit().getImage("Image/f.gif");
frame.setIconImage(ico);//设置窗体上的图片,image和icon的方法不同
frame.setResizable(false);//设置窗体不可以被手动修改大小
//设置窗体显示位置
screen=toolkit.getScreenSize();
frame.setLocation((screen.width-800)/2,screen.height/2-600/2);//窗口定位
//添加菜单
fMenu = new JMenuBar();
frame.setJMenuBar(fMenu);
fMenu.setPreferredSize(new java.awt.Dimension(392, 23));
{
fMenuSys = new JMenu();
fMenu.add(fMenuSys);
fMenuSys.setText("系统(S)");
fMenuSys.setFont(new Font("x",Font.PLAIN,12));
fMenuSys.setMnemonic(java.awt.event.KeyEvent.VK_S);//键盘助记符alt组合时激活
fMenuSys.setRolloverEnabled(true);//点击后颜色加深,反转效果
{
fMenuExit = new JMenuItem();
fMenuSys.add(fMenuExit);
fMenuExit.setText("退出");
fMenuExit.addActionListener(this);
fMenuExit.setFont(new Font("x",Font.PLAIN,12));
fMenuExit.setIcon(new ImageIcon(getClass().getClassLoader().getResource("leave.gif")));//放置标志
fMenuLoad = new JMenuItem();
fMenuSys.add(fMenuLoad);
fMenuLoad.setText("导入文本");
fMenuLoad.addActionListener(this);//导入文本按添加监听器
fMenuLoad.setFont(new Font("x",Font.PLAIN,12));
fMenuLoad.setIcon(new ImageIcon(getClass().getClassLoader().getResource("lx_2.gif")));
fMenuCoverkb = new JMenuItem();
fMenuSys.add(fMenuCoverkb);
fMenuCoverkb.setText("隐藏提示键盘");
fMenuCoverkb.addActionListener(this);//按添加监听器
fMenuCoverkb.setFont(new Font("x",Font.PLAIN,12));
fMenuCoverkb.setIcon(new ImageIcon(getClass().getClassLoader().getResource("exit.gif")));
fMenuOpenkb = new JMenuItem();
fMenuSys.add(fMenuOpenkb);
fMenuOpenkb.setText("打开提示键盘");
fMenuOpenkb.addActionListener(this);//按添加监听器
fMenuOpenkb.setFont(new Font("x",Font.PLAIN,12));
fMenuOpenkb.setIcon(new ImageIcon(getClass().getClassLoader().getResource("Local.gif")));
}
}
{
fMenuLx = new JMenu();
fMenu.add(fMenuLx);
fMenuLx.setText("练习(E)");
fMenuLx.setFont(new Font("x",Font.PLAIN,12));
fMenuLx.setMnemonic(java.awt.event.KeyEvent.VK_E);
fMenuLx.setRolloverEnabled(true);
{
fMenuKey = new JMenuItem();
fMenuLx.add(fMenuKey);
fMenuKey.setText("键盘练习");
fMenuKey.addActionListener(this);//键盘练习按钮添加监听器
fMenuKey.setFont(new Font("x",Font.PLAIN,12));
fMenuKey.setIcon(new ImageIcon(getClass().getClassLoader().getResource("lx_1.gif")));
fMenuRefresh = new JMenuItem();
fMenuLx.add(fMenuRefresh);
fMenuRefresh.setText("更换文本");
fMenuRefresh.addActionListener(this);//键盘练习按钮添加监听器
fMenuRefresh.setFont(new Font("x",Font.PLAIN,12));
fMenuRefresh.setIcon(new ImageIcon(getClass().getClassLoader().getResource("xx.gif")));
}
frame.pack(); //和前面用的setPreferredSize搭配才有用
frame.setVisible(true);
}
}
// 实现ActionListener接口的方法
public void actionPerformed(ActionEvent e){
if(e.getSource()==fMenuLoad){//导入文件
try {
JFileChooser fd = new JFileChooser();
fd.setFileSelectionMode(JFileChooser.OPEN_DIALOG);
fd.showOpenDialog(null);
File f = fd.getSelectedFile();
if (f != null) {
String filepath = f.getPath().trim();
//读取本地txt
StringBuffer buffer = new StringBuffer();
BufferedReader bf= new BufferedReader(new FileReader(filepath));
String s = null;
while((s = bf.readLine())!=null){//使用readLine方法,一次读一行
buffer.append(s.trim());
}
String xml = buffer.toString();
PublicData.Text= xml;
if(isInit==false)
{
showFrame();
isInit=true;
}
else
{
this.edit.txtOriginal.setText(PublicData.Text);
}
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
if(e.getSource()==fMenuExit){//退出按钮
int i=JOptionPane.showConfirmDialog(this,"你真的要退出吗?","疯狂打字",
JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);
if(i==0){
System.exit(0);
}
}
if(e.getSource()==fMenuCoverkb){//隐藏提示键盘
if(jianpan!=null)
{
this.jianpan.setVisible(false);
}
}
if(e.getSource()==fMenuOpenkb){//打开提示键盘
if(jianpan!=null)
{
this.jianpan.setVisible(true);
}
}
if(e.getSource()==fMenuKey){//键盘练习按钮
PublicData.Text=PublicData.getText((int)(Math.random()*5+1));
if(isInit==false)
{
showFrame();
isInit=true;
}
else
{
JOptionPane.showMessageDialog(new JPanel(),"请先点击刷新文本","提示",JOptionPane.WARNING_MESSAGE);
}
}
if(e.getSource()==fMenuRefresh){//刷新文本按钮
if(isInit==false)
{
JOptionPane.showMessageDialog(new JPanel(),"请先点击键盘练习","提示",JOptionPane.WARNING_MESSAGE);
}
else
{
PublicData.Text=PublicData.getText((int)(Math.random()*5+1));
this.edit.txtOriginal.setText(PublicData.Text);
this.edit.txtNewText.setText("");
}
}
}
//显示游戏界面
private void showFrame(){
//显示键盘
jianpan=new JInternalFrame();//keyset是jpanel,需要放到JInternalFrame上才能显示
jianpan.setBounds(0,326,0,0);
jianpan.setPreferredSize(new java.awt.Dimension(800, 223));
((javax.swing.plaf.basic.BasicInternalFrameUI) jianpan.getUI()).setNorthPane(null);//隐藏窗体的顶部title bar
jianpan.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);//putClientProperty用来为组件设置注释,后面的true意味取消掉窗体边框,不同的组件含义不同
jianpan.setVisible(true);
jianpan.pack();//搭配setPreferredSize使用,setPreferredSize设置为合适的大小,pack为之分配大小。如果不pack则大小为0
Keyset ks=new Keyset();
// keylistener kl=new keylistener();
// ks.add(kl);
jianpan.add(ks);
this.add(jianpan,2);
// //显示文本和输入文本窗体
edit=new Editor(this);
this.add(edit,2);
}
}
Editor.java(文本框)
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.text.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
public class Editor extends JInternalFrame implements DocumentListener,Runnable{
/**
*
*/
private static final long serialVersionUID = 1L;
Runtime r=Runtime.getRuntime();
MainFrame parent;
Document doc;//The Document is a container for text that servesas the model for swing text components.
StyledDocument styledDoc = new DefaultStyledDocument();//Interface for a generic styled document.
Thread th;
private int hour=0;//时
private int minute=0;//分
private int second=0;//秒
//标签
private JLabel lblTime;//用时
private JLabel lblError;//错误字数
private JLabel lblWord; //总字数
private JLabel lblM;
private JLabel lblRight;//正确字数
private JLabel lblCount;//
//面板
private JPanel pShowData;//显示文本面板
private JPanel pAttrib;//参数显示面板
JTextPane txtOriginal;//原始文本
JTextPane txtNewText;//输入文本
//信息条区域
private JTextField txtMW;//每分钟多少字
private JTextField txtError;//错误字数显示条
private JTextField txtRight;//正确字数显示条
private JTextField txtTime;//时间计数显示条
private JTextField txtCount;//总输入字数
//记录输入的正确和错误的个数据
private int rightWord=0;
private int errorWord=0;
private int rightCount=0;
private int errorCount=0;
private int wordCount=0;
//临时
@SuppressWarnings("unused")
private boolean temp=true;
public Editor(MainFrame parent ){
this.parent=parent;
th=new Thread(this);
//组建Editor用户界面....
setBounds(0,0,0,0);
this.setPreferredSize(new java.awt.Dimension(657, 325));//内部窗体大小657,325
((javax.swing.plaf.basic.BasicInternalFrameUI) this.getUI()).setNorthPane(null);
this.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
getContentPane().setLayout(null);
this.setVisible(true);
{
pAttrib = new JPanel();
getContentPane().add(pAttrib, new GridBagConstraints(1, 0, 12, 3, 0.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
FlowLayout pAttribLayout = new FlowLayout();
pAttrib.setBorder(BorderFactory.createTitledBorder(""));
pAttrib.setLayout(pAttribLayout);
pAttrib.setBounds(-2, 33, 658, 42);
{
lblTime = new JLabel();
pAttrib.add(lblTime);
lblTime.setText("用时:");
lblTime.setFont(new java.awt.Font("新宋体", 0, 12));
}
{
txtTime = new JTextField(8);
pAttrib.add(txtTime);
txtTime.setText("00:00:00");
txtTime.setEditable(false);
txtTime.setHorizontalAlignment(SwingConstants.CENTER);
}
{
lblCount = new JLabel();
pAttrib.add(lblCount);
lblCount.setText("总字数:");
lblCount.setFont(new java.awt.Font("新宋体", 0, 12));
}
{
txtCount = new JTextField();
pAttrib.add(txtCount);
txtCount.setColumns(6);
txtCount.setText("0");
txtCount.setEditable(false);
txtCount.setHorizontalAlignment(SwingConstants.CENTER);
}
{
lblRight = new JLabel();
pAttrib.add(lblRight);
lblRight.setText("正确:");
lblRight.setFont(new java.awt.Font("新宋体", 0, 12));
}
{
txtRight = new JTextField();
pAttrib.add(txtRight);
txtRight.setColumns(4);
txtRight.setText("0");
txtRight.setEditable(false);
txtRight.setHorizontalAlignment(SwingConstants.CENTER);
}
{
lblError = new JLabel();
pAttrib.add(lblError);
lblError.setText("错误:");
lblError.setFont(new java.awt.Font("新宋体", 0, 12));
}
{
txtError = new JTextField();
pAttrib.add(txtError);
txtError.setColumns(4);
txtError.setText("0");
txtError.setEditable(false);
txtError.setHorizontalAlignment(SwingConstants.CENTER);
}
{
lblM = new JLabel();
pAttrib.add(lblM);
lblM.setText("每分钟");
lblM.setFont(new java.awt.Font("新宋体", 0, 12));
}
{
txtMW = new JTextField();
pAttrib.add(txtMW);
txtMW.setColumns(4);
txtMW.setText("0");
txtMW.setEditable(false);
txtMW.setHorizontalAlignment(SwingConstants.CENTER);
}
{
lblWord = new JLabel();
pAttrib.add(lblWord);
lblWord.setText("个字");
lblWord.setFont(new java.awt.Font("新宋体", 0, 12));
}
}
{
pShowData = new JPanel();//建一个面板来装两个jtextpane
getContentPane().add(pShowData,new GridBagConstraints(1,1,12,10,0.0,0.0,
GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0, 0, 0, 0),0,0));
GridLayout pShowDataLayout = new GridLayout(2, 1);
pShowDataLayout.setHgap(5);
pShowDataLayout.setVgap(5);
pShowDataLayout.setColumns(1);
pShowDataLayout.setRows(2);
pShowData.setLayout(pShowDataLayout);
pShowData.setBounds(5, 82, 644, 231);
{
txtOriginal = new JTextPane(styledDoc);//导入文本
pShowData.add(txtOriginal);//把pane放到Jpanel上
txtOriginal.setPreferredSize(new java.awt.Dimension(600, 0));
txtOriginal.setEditable(false);//设置为不可修改
}
{
txtNewText = new JTextPane();
pShowData.add(txtNewText);
txtNewText.setPreferredSize(new java.awt.Dimension(600, 0));
Document doc=txtNewText.getDocument();
doc.addDocumentListener(this);//给文本添加监听器
//给输入文本框添加键盘监听器
txtNewText.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
PublicData.curkey=String.valueOf(e.getKeyChar());//转换成string
}
public void keyTyped(KeyEvent e) {
// PublicData.curkey=String.valueOf(e.getKeyChar());
}
public void keyReleased(KeyEvent e)
{
PublicData.curkey="";//转换成string
parent.repaint();
}
});
}
}
{
txtOriginal.setText(PublicData.Text);
PublicData.key=txtOriginal.getText().substring(0,1);
//启动线程,文本输入满时清空
Empty empty=new Empty();
empty.start();
}
this.pack();
//启动线程
th.start();
}
//判断正确和错误的字.并改变它们的颜色
public void chDocs(int xLen,int yLen,String xStr,String yStr)
{
SimpleAttributeSet attrSet=new SimpleAttributeSet();
rightWord=0;
errorWord=0;
for(int i=1;i<=xLen;i++)
{
if(i<=yLen){//数据验证
if(xStr.substring(i-1,i).equals(yStr.substring(i-1,i))){
rightWord++;
StyleConstants.setForeground(attrSet,Color.BLUE);
}
else{
errorWord++;
StyleConstants.setForeground(attrSet,Color.RED);
}
StyleConstants.setUnderline(attrSet,true);
}
else{
StyleConstants.setForeground(attrSet,Color.BLACK);
StyleConstants.setUnderline(attrSet,false);
}
styledDoc.setCharacterAttributes(i-1,1,attrSet,true);
}
//设置正确、错误字数
txtRight.setText((rightWord+rightCount)+"");
txtError.setText((errorWord+errorCount)+"");
//计算和设置每分钟正确打字数
int c=0;
for(int i=0;itxtNewText.getText().length()){
PublicData.key=txtOriginal.getText().substring(txtNewText.getText().length(),
txtNewText.getText().length()+1);
txtCount.setText((txtNewText.getText().length()+wordCount)+"");
}
}
//计时器
public void run(){
try{
while(true){
Thread.sleep(1000);
second++;
if(second==60){
second=0;
minute++;
if(minute==60){
minute=0;
hour++;
if(hour==1000){
second=0;
minute=0;
hour=0;
}
}
}
txtTime.setText(((hour<=9)?"0":"")+hour+":"+((minute<=9)?"0":"")
+minute+":"+((second<=9)?"0":"")+second);
}
}
catch (InterruptedException e){}
}
//清空文本框的线程
class Empty extends Thread{
public void run(){
while(true){
try{
Thread.sleep(100);
dataValidate();
//当文本打完时清空输入框,更新初始文本
if(txtNewText.getText().length()>=txtOriginal.getText().length()){
txtNewText.setText("");
PublicData.Text=PublicData.getText((int)(Math.random()*5+1));
txtOriginal.setText(PublicData.Text);
parent.repaint();
}
}
catch(InterruptedException e){}
}
}
}
}
Keyset.java(虚拟键盘)
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Keyset extends JPanel implements KeyListener {
/**
*
*/
private static final long serialVersionUID = 1L;
//创建类的时候自动调用paintComponent方法
public void paintComponent(Graphics g){
super.paintComponent(g);
String str=new String(PublicData.key);//下一个正确的键盘键
String cur=(PublicData.curkey);//当前按下的键盘键
int curkt=0;//当前按下的键的纵坐标
int curkl=0;//当前按下的键的横坐标
int keyTop=0;//字符在键盘上的纵坐标
int keyLeft=0;//字符在键盘上的横坐标
boolean leftShift=false;//是否是左边的Shift
boolean rightShift=false;//是否是右边的Shift
@SuppressWarnings("unused")
boolean yShift=false;//是否要用Shift
boolean ySpace=false;//是否是空格
String shift=new String("~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?");//需要搭配shift使用的
String noShift=new String("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./");//不需要搭配shift
int LEFT=52;//键盘横坐标
int TOP=20;//键盘纵坐标
int lTemp=LEFT;
int tTemp=TOP;
if(shift.lastIndexOf(str)<=46){//计算是不是要用上Shift
if((shift.lastIndexOf(str)>=0 && shift.lastIndexOf(str)<=5) ||
(shift.lastIndexOf(str)>=13 && shift.lastIndexOf(str)<=17) ||
(shift.lastIndexOf(str)>=26 && shift.lastIndexOf(str)<=30) ||
(shift.lastIndexOf(str)>=37 && shift.lastIndexOf(str)<=41)){//计算字符在不在左手区
yShift=true;
rightShift=true;//提示使用右shift键
if(shift.lastIndexOf(str)>=0 && shift.lastIndexOf(str)<=5){//计算字符在该区的位置
keyTop=1;
for(int i=0;i<=5;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
System.out.println(shift.substring(i, i+1));
}
}
}
if(shift.lastIndexOf(str)>=13 && shift.lastIndexOf(str)<=17){//计算字符在该区的位置
keyTop=2;
for(int i=13;i<=17;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
if(shift.lastIndexOf(str)>=26 && shift.lastIndexOf(str)<=30){//计算字符在该区的位置
keyTop=3;
for(int i=26;i<=30;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
if(shift.lastIndexOf(str)>=37 && shift.lastIndexOf(str)<=41){//计算字符在该区的位置
keyTop=4;
for(int i=37;i<=41;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
}
if((shift.lastIndexOf(str)>=6 && shift.lastIndexOf(str)<=12) ||
(shift.lastIndexOf(str)>=18 && shift.lastIndexOf(str)<=25) ||
(shift.lastIndexOf(str)>=31 && shift.lastIndexOf(str)<=36) ||
(shift.lastIndexOf(str)>=42 && shift.lastIndexOf(str)<=46)){//计算字符在不在右手区
yShift=true;
leftShift=true;//提示使用左shift键
if(shift.lastIndexOf(str)>=6 && shift.lastIndexOf(str)<=12){
keyTop=1;
for(int i=6;i<=12;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
if(shift.lastIndexOf(str)>=18 && shift.lastIndexOf(str)<=25){
keyTop=2;
for(int i=18;i<=25;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
if(shift.lastIndexOf(str)>=31 && shift.lastIndexOf(str)<=36){
keyTop=3;
for(int i=31;i<=36;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
if(shift.lastIndexOf(str)>=42 && shift.lastIndexOf(str)<=46){
keyTop=4;
for(int i=42;i<=46;i++){
if(str.equals(shift.substring(i, i+1))){
keyLeft=i;
}
}
}
}
}
if(noShift.lastIndexOf(str)<=46){
if(noShift.lastIndexOf(str)>=0 && noShift.lastIndexOf(str)<=12){
keyTop=1;
for(int i=0;i<=12;i++){
if(str.equals(noShift.substring(i,i+1))){
keyLeft=i;
}
}
}
if(noShift.lastIndexOf(str)>=13 && noShift.lastIndexOf(str)<=25){
keyTop=2;
for(int i=13;i<=25;i++){
if(str.equals(noShift.substring(i,i+1))){
keyLeft=i;
}
}
}
if(noShift.lastIndexOf(str)>=26 && noShift.lastIndexOf(str)<=36){
keyTop=3;
for(int i=26;i<=36;i++){
if(str.equals(noShift.substring(i,i+1))){
keyLeft=i;
}
}
}
if(noShift.lastIndexOf(str)>=37 && noShift.lastIndexOf(str)<=46){
keyTop=4;
for(int i=37;i<=46;i++){
if(str.equals(noShift.substring(i,i+1))){
keyLeft=i;
}
}
}
}
//输入字符为空格
if(str.equals(" ")){
ySpace=true;
}
//设置当前按下键的位置
if(cur!=null&&shift.lastIndexOf(cur)>=0 && shift.lastIndexOf(cur)<=5){//计算字符在该区的位置
curkt=1;
for(int i=0;i<=12;i++){
if(cur.equals(shift.substring(i, i+1))){
curkl=i;
System.out.println(shift.substring(i, i+1));
}
}
}
if(cur!=null&&shift.lastIndexOf(cur)>=13 && shift.lastIndexOf(cur)<=17){//计算字符在该区的位置
curkt=2;
for(int i=13;i<=25;i++){
if(cur.equals(shift.substring(i, i+1))){
curkl=i;
}
}
}
if(cur!=null&&shift.lastIndexOf(cur)>=26 && shift.lastIndexOf(cur)<=36){//计算字符在该区的位置
curkt=3;
for(int i=26;i<=30;i++){
if(cur.equals(shift.substring(i, i+1))){
curkl=i;
}
}
}
if(cur!=null&&shift.lastIndexOf(cur)>=37 && shift.lastIndexOf(cur)<=46){//计算字符在该区的位置
curkt=4;
for(int i=37;i<=41;i++){
if(cur.equals(shift.substring(i, i+1))){
curkl=i;
}
}
}
//noshift的按键
if(cur!=null&&noShift.lastIndexOf(cur)>=0 && noShift.lastIndexOf(cur)<=12){
curkt=1;
for(int i=0;i<=12;i++){
if(cur.equals(noShift.substring(i,i+1))){
curkl=i;
}
}
}
if(cur!=null&&noShift.lastIndexOf(cur)>=13 && noShift.lastIndexOf(cur)<=25){
curkt=2;
for(int i=13;i<=25;i++){
if(cur.equals(noShift.substring(i,i+1))){
curkl=i;
}
}
}
if(cur!=null&&noShift.lastIndexOf(cur)>=26 && noShift.lastIndexOf(cur)<=36){
curkt=3;
for(int i=26;i<=36;i++){
if(cur.equals(noShift.substring(i,i+1))){
curkl=i;
}
}
}
if(cur!=null&&noShift.lastIndexOf(cur)>=37 && noShift.lastIndexOf(cur)<=46){
curkt=4;
for(int i=37;i<=46;i++){
if(cur.equals(noShift.substring(i,i+1))){
curkl=i;
}
}
}
//绘制编辑键区图形,每个按键之间相隔两个横坐标
g.setColor(Color.black);
for(int i=0;i<=12;i++){
if(keyTop==1 && keyLeft==i){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,35,35);//填充矩形颜色
}
if(curkt==1 && curkl==i){
g.setColor(Color.pink);
g.fillRect(LEFT,TOP,35,35);//填充矩形颜色
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,35,35,true);//画出矩形的边框
LEFT=LEFT+37;
}
//画←键
g.draw3DRect(LEFT,TOP,70,35,true);
int sum=12;
LEFT=lTemp;
TOP=TOP+37;
//Tab键
g.draw3DRect(LEFT,TOP,54,35,true);
LEFT=LEFT+56;
//画键盘的第二排
for(int i=1;i<=12;i++)
{
if(keyTop==2 && keyLeft==i+sum){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,35,35);
}
if(curkt==2 && curkl==i+sum){
g.setColor(Color.pink);
g.fillRect(LEFT,TOP,35,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,35,35,true);
LEFT=LEFT+37;
}
//画|\键
sum=sum+12;
if(keyTop==2 && keyLeft==sum+1){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,51,35);
}
if(curkt==2 && curkl==sum+1){
g.setColor(Color.pink);
g.fillRect(LEFT,TOP,51,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,51,35,true);
sum=sum+1;
LEFT=lTemp;
TOP=TOP+37;
//Caps Lock键
g.draw3DRect(LEFT,TOP,65,35,true);
LEFT=LEFT+67;
for(int i=1;i<=11;i++){
if(keyTop==3 && keyLeft==sum+i){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,35,35);
}
if(curkt==3 && curkl==sum+i){
g.setColor(Color.pink);
g.fillRect(LEFT,TOP,35,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,35,35,true);
LEFT=LEFT+37;
}
//Enter键
g.draw3DRect(LEFT,TOP,77,35,true);
sum=sum+11;
LEFT=lTemp;
TOP=TOP+37;
//左Shift键
if(leftShift==true){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,82,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,82,35,true);
LEFT=LEFT+84;
for(int i=1;i<=10;i++){
if(keyTop==4 && keyLeft==sum+i){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,35,35);
}
if(curkt==4 && curkl==sum+i){
g.setColor(Color.pink);
g.fillRect(LEFT,TOP,35,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,35,35,true);
LEFT=LEFT+37;
}
//右Shift键
if(rightShift==true){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,97,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,97,35,true);
//左Ctrl键
LEFT=lTemp;
TOP=TOP+37;
g.draw3DRect(LEFT,TOP,53,35,true);
LEFT=LEFT+55;
//win键
g.draw3DRect(LEFT,TOP,44,35,true);
LEFT=LEFT+46;
//左Alt键
g.draw3DRect(LEFT,TOP,44,35,true);
LEFT=LEFT+46;
//Space键
if(ySpace==true){
g.setColor(Color.gray);
g.fillRect(LEFT,TOP,211,35);
}
g.setColor(Color.black);
g.draw3DRect(LEFT,TOP,211,35,true);
//右Alt键
LEFT=LEFT+213;
g.draw3DRect(LEFT,TOP,44,35,true);
LEFT=LEFT+46;
//win键
g.draw3DRect(LEFT,TOP,46,35,true);
LEFT=LEFT+48;
//快捷键
g.draw3DRect(LEFT,TOP,42,35,true);
LEFT=LEFT+44;
//右Ctrl键
g.draw3DRect(LEFT,TOP,53,35,true);
//编辑键区图形绘制完成
//绘制字母、符号-------
LEFT=lTemp;
TOP=tTemp;
g.setColor(Color.lightGray);
Font f=new Font("x",Font.BOLD,13);
g.setFont(f);
LEFT=LEFT+7;
TOP=TOP+14;
for(int i=1;i<=13;i++){
g.drawString(shift.substring(i-1,i),LEFT,TOP);
g.drawString(noShift.substring(i-1,i),LEFT,TOP+18);
LEFT=LEFT+37;
}
f=new Font("x",Font.BOLD,12);
g.setFont(f);
g.drawString("BackSpace",LEFT-4,TOP+8);
LEFT=lTemp+7;
TOP=TOP+37;
g.drawString("Tab",LEFT,TOP+8);
f=new Font("x",Font.BOLD,14);
g.setFont(f);
LEFT=lTemp+63;
for(int i=13;i<=25;i++){
g.drawString(shift.substring(i,i+1),LEFT,TOP);
if(i>=23)
g.drawString(noShift.substring(i,i+1),LEFT,TOP+16);
LEFT=LEFT+37;
}
f=new Font("x",Font.BOLD,12);
g.setFont(f);
LEFT=lTemp;
TOP=TOP+37;
g.drawString("CapsLock",LEFT+7,TOP+8);
f=new Font("x",Font.BOLD,14);
g.setFont(f);
LEFT=lTemp+74;
for(int i=26;i<=36;i++){
g.drawString(shift.substring(i,i+1),LEFT,TOP);
if(i>=35)
g.drawString(noShift.substring(i,i+1),LEFT,TOP+16);
if("F".equals(shift.substring(i,i+1)) || "J".equals(shift.substring(i,i+1)))
g.drawString("_",LEFT+5,TOP+15);
LEFT=LEFT+37;
}
f=new Font("x",Font.BOLD,12);
g.setFont(f);
g.drawString("Enter←┘",LEFT+15,TOP+8);
LEFT=lTemp+7;
TOP=TOP+37;
g.drawString("↑Shift",LEFT,TOP+8);
f=new Font("x",Font.BOLD,14);
g.setFont(f);
LEFT=lTemp+91;
for(int i=37;i<=46;i++){
g.drawString(shift.substring(i,i+1),LEFT,TOP);
if(i>=44)
g.drawString(noShift.substring(i,i+1),LEFT,TOP+16);
LEFT=LEFT+37;
}
f=new Font("x",Font.BOLD,12);
g.setFont(f);
g.drawString("↑Shift",LEFT,TOP+8);
LEFT=lTemp+7;
TOP=TOP+37;
g.drawString("Ctrl",LEFT,TOP+8);
LEFT=LEFT+55;
g.drawString("Win",LEFT,TOP+8);
LEFT=LEFT+46;
g.drawString("Alt",LEFT,TOP+8);
LEFT=LEFT+46;
g.drawString("Space",LEFT+90,TOP+8);
LEFT=LEFT+213;
g.drawString("Alt",LEFT,TOP+8);
LEFT=LEFT+46;
g.drawString("Win",LEFT,TOP+8);
LEFT=LEFT+50;
g.drawString("SM",LEFT,TOP+8);
LEFT=LEFT+44;
g.drawString("Ctrl",LEFT,TOP+8);
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
System.out.print(e.getKeyChar());
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
System.out.print(e.getKeyChar());
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
System.out.print(e.getKeyChar());
}
}
PublicData.java(共享数据)
public class PublicData {//共享数据、用static动态变化
public static String key=" ";
public static String curkey;
public static String Text;
public static int textTag=1;
//预设好五段文字
public static String getText(int i)
{
switch(i)
{
case 1:
return "The Java programming language is robust and versatile, enabling developers to:Write software on one platform and run it on another.Create programs to run within a web browser.Develop server-side applications for online forums, stores, polls, processing HTML forms, and more.Write applications for cell phones, two-way pagers, and other consumer devices.It's no wonder the Java platform attracts so many new developers.";
case 2:
return "Review What You've Learned Test your Java programming knowledge with these online interactive quizzes and puzzles.Learning Paths Get a short, customized learning path, based on your programming experience.References & Resources A collection of references and resources to use for Java development.";
case 3:
return "Certification and Courses Links to information on taking Sun's courses and getting certified as a Java programmer, developer, or architect.The New to Java Programming Center provides instructional articles and tutorials for developing on the Java platform. ";
case 4:
return "Read through materials listed in the four easy-to-follow steps, or use the interactive Learning Path for a customized path, based on your programming experience. ";
case 5:
return "There were a sensitivity and a beauty to her that have nothing to do with looks. She was one to be listened to, whose words were so easy to take to heart.It is said that the true nature of being is veiled.";
}
return Text;
}
}
这个程序很好的练习学习了java swing,收获最大应该是这个虚拟键盘的设计,以前对于实现这个虚拟键盘完全不知道从何做起。如果是完全没有接触过java swing的同学直接下手做项目是非常困难的,我在已经做过项目的情况下还发现Java swing有许许多多陌生和的类和方法,好的办法是先有了对基础类大致的了解下,找一个做好的项目来进行修改,不会的再单独学习某个类的使用方法,变成自己的东西。有了这些基本的框架后就可以个性化的设计自己的作品了。