程序预期效果:当点击鼠标时,画布响应,文本行输出"mouseClicked"字样,当响应键盘时,文本行出现"keyTyped"字样
实际上的效果是:可以键入字符,但文本行无输出.
问题:是哪里出错了导致了预期效果与实际效果的不同呢?请各位指点.import java.awt.*;
import java.awt.event.*; 
import java.util.*;
public class MyCanvas implements MouseListener,KeyListener
{
//变量定义
Canvas c;
String s="";
TextField tf;
 //主函数
public static void main(String args[]) 
{
Frame f = new Frame("Canvas");
MyCanvas mc = new MyCanvas();  //实例化一个画布
mc.c = new Canvas();
mc.tf = new TextField();
TextField tf = new TextField();  //实例化一个单行的文本输入框
f.add("South",tf);
f.add("Center",mc.c);
f.setSize(300,150);
mc.c.addMouseListener(mc);  
mc.c.addKeyListener(mc);
f.addWindowListener(new WinClose());  
f.setVisible(true);
} //响应鼠标
public void mouseClicked(MouseEvent ev)
{
tf.setText("mouseClicked");
c.requestFocus();  //设置焦点
}public void mouseEntered(MouseEvent ev){}
public void mouseExited(MouseEvent ev){}
public void mousePressed(MouseEvent ev){}
public void mouseReleased(MouseEvent ev){}//响应键盘事件
public void keyTyped(KeyEvent ev)
{
tf.setText("keyTyped");
s += ev.getKeyChar();
c.getGraphics().drawString(s,0,20);

}
//重写键盘事件接口里其它没用到的方法(令其为空)
public void keyPressed(KeyEvent ev){}
public void keyReleased(KeyEvent ev){}}
class WinClose extends WindowAdapter
{
public void windowClosing(WindowEvent ev)
{
System.exit(0);  //关闭窗口
}
};

解决方案 »

  1.   

    你填加的那个TextField和接受响应的根本不是一个, 主函数改成:
    Frame f = new Frame("Canvas");
    MyCanvas mc = new MyCanvas(); // 实例化一个画布
    mc.c = new Canvas();
    mc.tf = new TextField();
    // TextField tf = new TextField(); // 实例化一个单行的文本输入框
    //原来这里你创建了两个TextField, 添加的是一个, 下面接受处理的是另一个.
    f.add("South", mc.tf);
    f.add("Center", mc.c);
    f.setSize(300, 150);
    mc.c.addMouseListener(mc);
    mc.c.addKeyListener(mc);
    f.addWindowListener(new WinClose());
    f.setVisible(true);还有, 你编程的习惯有很严重的问题, 先参考一些教科书的程序模仿一下一般程序的结构吧.
      

  2.   

    感谢hemiao_1993(冷血动物) 指出我的错误,现在程序已经运行正常了.
    我是Java初学者,编程习惯基本上是照着书上写的.我很想知道java基本的编程习惯应该是怎样的,请大家指点一下,让我少走一点弯路.
      

  3.   

    晕, 这个程序不会是也按照书上写的吧. 是哪本书?马上扔掉. 哈哈,开个玩笑.就从这个程序来说吧, 首先你是想创建一个MyCanvas类, 这个类应该是相对独立的, 他的业务逻辑应该放在自己的成员函数里来实现, Main函数中来用这个类而已. 而这个程序的逻辑都放在了Main函数中, 这显然是不合适的. 
    还有这两句:mc.c = new Canvas();
               mc.tf = new TextField(); 首先直接存取类的成员进行操作破坏了封装性, 是面向对象程序设计中应该尽量避免的, 而且可读性也不好. 而且初始化的时候一般习惯上可以在定义时就初始化, 或者在构造函数中初始化是比较常见的方式.