超古怪的问题!

wangjie1986 2007-12-15 09:31:30
首先程序如下:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;


public class Exam5_8 extends Applet implements ItemListener
{
Choice cho;
TextField text;

public void init()
{
text=new TextField(10);
cho=new Choice();
cho.add("red");
cho.add("yellow");
cho.add("green");
cho.add("blue");
add(cho);
add(text);
cho.addItemListener(this);
}
public void itemStateChanged(ItemEvent e)
{
if(e.getItemSelectable()==cho)
String str=cho.getSelectedItem();
text.setText(str);


}
}
*这个程序在红色地方会报错:
Syntax error, insert ";" to complete Statement
Syntax error, insert "AssignmentOperator ArrayInitializer" to complete ArrayInitializerAssignement

真是古怪的错误,然后只要把if下面的语句加上{},程序就能正常运行了,这是为什么啊
还有就是,如果去掉if语句,程序也能运行
在就是把String str定义在类的成员变量,而不定义在类方法里面,也可以运行,
太古怪了,实在搞不懂,望高手现身回答下,谢了!
...全文
1540 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangjie1986 2007-12-23
  • 打赏
  • 举报
回复
懂了,谢谢了,可以实现了!想请教下,书上说,AWT和Swing有时可以互换,就是我把用AWT写的菜单栏前面都加上J然后写入IMPORT JAVAX.SWING.*,可以看到效果,也可以写addActionlistener(this),但是用鼠标单击的触发的时候却会报错,这是怎么回事啊,谁能给我个用SWING.编写的菜单栏以及实现吗,谢谢了!我写的是这样的:
public void init()
{JMenuBar myB=new JMenuBar();
setJMenuBar(myB);
JMenu m1=new JMenu("文件(E)");
m1.add(new JMenuItem("打开"));
JMenuItem m11=new JMenuItem("保存");
m1.add(m11);
m1.add("打印");
m1.addSeparator();
//JMenuItem exit=new JMenuItem("退出");

//exit.addActionListener(this);
m1.add(exit);
m1.addActionListener(this);
myB.add(m1);


JMenu m2=new JMenu("编辑(V)");
m2.add("复制");
JMenu m21=new JMenu("颜色");
m21.add("前景色");
m21.add("背景色");
m21.addActionListener(this);
m2.add(m21);
m2.addSeparator();
//JCheckboxMenuItem mycmi=new JCheckboxMenuItem("全选");
//mycmi.addItemListener(this);
//m2.add(mycmi);
m2.addActionListener(this);
myB.add(m2);

JMenu m3=new JMenu("帮助(H)");
m3.add("关于");
m3.addActionListener(this);
myB.add(m3);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{if (e.getActionCommand()=="退出")
System.exit(0);
}
可是当我触发的时候却会报错!
ada100 2007-12-18
  • 打赏
  • 举报
回复
这个问题就是因为变成习惯不好造成的,只要改成
public void itemStateChanged(ItemEvent e)
{
if(e.getItemSelectable()==cho)
{
String str=cho.getSelectedItem();
text.setText(str);
}
}
就可以了,因为if后面如果不加括号的话,就只能与下一行形成条件匹配,这样text.setText(str); 中的str就相当于没有定义了
dracularking 2007-12-16
  • 打赏
  • 举报
回复
好问题 我来试着回答一下吧

ActionEvent在构造的时候有一个参数就是String类型的command
它有它存在的意义 这个串就指定了与此事件相关联的命令名
与组件的名称含义是不同的 至于其如何被使用 则因人而异

getSource和getItemSelectable诸如此类 getSource显然范围更宽泛
我想当一个组件有多个事件源的时候 要想确定具体的事件源getSource在这里就不适用了
比如一个item添加了itemSelect事件监听和鼠标覆盖监听 就必须得用具体的获取事件源方法
如getItemSelectable

wangjie1986 2007-12-16
  • 打赏
  • 举报
回复
呵呵,太感谢,楼上Dan1980的见解了,其实如果你仔细看的话,我说了既然存在就有存在的理由,我并不是怀疑它的正确性与必要性。只是从一个初学者的的角度去考虑与看待它,如果能得出矛盾是好事啊,因为这样才会激发出不断求知的欲望,因为我知道肯定是自己在哪方面没了解(也就是说我还是在怀疑自己),然后在去看别人正确的解释,而后恍然大悟,这样在加深印象的同时,也可以激发自己对这件事的兴趣(原来它是这样进行处理的啊,难怪呢!)
说的有点多了,不过我很同意楼上的见解,怀疑应该首先从自己开始,可能是我在表达方面显得过于强烈(没办法,这些问题苦恼我好半天了,显得急噪了些)才会让楼上兄弟对我产生了误解,这里再次对你表示感谢了,虽然对问题只是在表面上理解了,因为还是没涉及到具体的应用,,,不过我会继续努力的,再次谢谢了!
wangjie1986 2007-12-16
  • 打赏
  • 举报
回复
呵呵,些许明白了点,可我想知道,我们平常设计的时候有谁会将两个按钮标签设置成一样啊,那样在界面上就无法区分了,如果设置成不一样的话,那command还有什么用啊,直接返回标签label不就行了吗,归根结底就是这个command一般用在什么地方,有什么特别的用处啊?
作为一名初学者其实我最搞不清楚的是,既然用e.getsource()可以用在所有的事件类中(因为它们都继承了父类的)那么每个事件类自己的判别事件源的方法不就每什么必要了吗,全用e.getsource()多简洁方便啊!诸如什么e.getItemSelectable(),e.getItemSelectable().equals("")之类的,多麻烦啊!既然存在肯定有它的理由,望高手能给以详细解答了,另外谢谢所有回贴的人,向你们学习中。。。。。。
dracularking 2007-12-16
  • 打赏
  • 举报
回复
各位高手,听你们解释后,我又进行了如下改进,将String str一句提到if之前,也就是说提前于if进行定义,扩大它的作用域,然后再在if 里面写上str=......,发现if 下面的一条语句不会报错了,但是setText(str)中的str又会报错,这是为什么啊,难道if里面就不能又单条赋值语句吗,可我试了将str的定义为类的成员变量就一切解决了,看来还是str的作用域问题,可是我将str在方法中提前定义了啊,应该是将它扩大了,为什么还不行呢,讲的又点罗嗦了,希望哪位能在解释下啊,不甚感激!
///////////////////////////////////////////////////////////////////////////////////////////////////
lz说的报错是这个吧

The local variable str may not have been initialized

局部变量可能未被初始化

初始化一下就好了
String str="";
Dan1980 2007-12-16
  • 打赏
  • 举报
回复
忍不住再罗索几句。
楼主善于提出疑问这一点是很好的,但是在态度上,怀疑他人多于怀疑自己。
实际上,进步往往是从怀疑自己开始的。
JAVA是一门发展非常成熟的语言,是众多业界精英智慧的结晶,如果那么值得怀疑,它还能存在到今天么?
Dan1980 2007-12-16
  • 打赏
  • 举报
回复
楼主问了3个问题。

第一个问题显然是逻辑不清晰造成的。

你将变量定义在条件分支中,却试图在条件分支以外使用它,那如果条件分支没有执行,变量就得不到定义了。这种明显的逻辑错误,显然是编译器不能接受的。
合理的逻辑应该是:
if(e.getItemSelectable()==cho) {
String str=cho.getSelectedItem();
text.setText(str);
}
或者:
String str = "":
f(e.getItemSelectable()==cho)
str=cho.getSelectedItem();
text.setText(str);

还有,局部变量是一定要显式初始化才能用的(哪怕初始化为null),只有成员变量才会自动初始化,这是基本常识。

第二个问题,你的理解也不对。

JAVA把label和command分开设置,这无可厚非呀,本来两者的执行的功能就不一样,label是负责界面显示的,command则是命令标识,两者没有理由一致,更不需要合二为一。同一个界面中,label相同的组件却有不同的行为,这种情况多的是!

第三个问题,getSource()是Event类的,getItemSelectable()是ItemEvent类的,两者返回的是同一个东西,都是事件源对象。但是,getSource()返回的是一个Object,要使用getSource()返回的对象往往要向下转型;而getItemSelectable()则明确返回一个ItemSelectable,这样你就可以直接把它当作ItemSelectable来用,直接调用ItemSelectable接口中的方法而无需向下转型,这样更安全。总之,两者各有所用,不存在多余的情况。
wangjie1986 2007-12-16
  • 打赏
  • 举报
回复
各位,听完你们的解答,深感自己知识的薄弱,其实我自认为看书已经很认真了,但是书上真的对这些东西都没概念啊,好多地方讲的都不深入,要不是我自己乱改程序,也许永远也发现不了这些你们所谓的常识!恳请各位推荐本java方面深入的书籍,把一些事件类以及触发方式讲的在深入些(特别GUI方面),由于我基本上是在自学,所以希望书上能尽可能多的给出些例子!,谢谢了!
DeviLeo 2007-12-16
  • 打赏
  • 举报
回复
LZ不是怀疑JAVA,而是对JAVA的困惑。
怀疑都是高手的作风,困惑都是初学者的作为。
dracularking 2007-12-16
  • 打赏
  • 举报
回复
不好意思 解释失败 貌似没有

getItemSelectable()相当于getSource()方法,一样都是返回触发事件的组件,用来判断是哪个组件产生事件。getSource()方法是EventObject类所提供,而所有事件类都会继承这个类,因此所有的事件均能用getSource()方法来判断到底是哪个组件触发了事件。

无法强力解释其存在必要性 弱弱地说一句 可能是为了增加可读性吧
wangjie1986 2007-12-16
  • 打赏
  • 举报
回复
还是有点不明白,就拿上面拿个程序来讲吧,里面的if(e.getItemSelectable()==cho)如果我写成 if(e.getsource()==cho)不也行,在什么情况下,非要用e.getItemSelectable()==cho它,而用e.getsource()判断不了啊,望能举例说明之,谢谢了!
wangjie1986 2007-12-15
  • 打赏
  • 举报
回复
呵呵,了解!一般情况下,如果我定义一个int i;不给它赋值的话,它会默认为0,我还以为这里能默认为空呢,刚试了下,把String str写成String str=new String ("");就能顺利运行了,这么晚了,得到你的帮助,真是谢谢了!好象加分要隔一天,等到明天,我一定给你加分了,再次谢谢了!
wangjie1986 2007-12-15
  • 打赏
  • 举报
回复
呵呵,些许明白了点,可我想知道,我们平常设计的时候有谁会将两个按钮标签设置成一样啊,那样在界面上就无法区分了,如果设置成不一样的话,那command还有什么用啊,直接返回标签label不就行了吗,归根结底就是这个command一般用在什么地方,有什么特别的用处啊?
作为一名初学者其实我最搞不清楚的是,既然用e.getsource()可以用在所有的事件类中(因为它们都继承了父类的)那么每个事件类自己的判别事件源的方法不就每什么必要了吗,全用e.getsource()多简洁方便啊!诸如什么e.getItemSelectable(),e.getItemSelectable().equals("")之类的,多麻烦啊!既然存在肯定有它的理由,望高手能给以详细解答了,另外谢谢所有回贴的人,向你们学习中。。。。。。
DeviLeo 2007-12-15
  • 打赏
  • 举报
回复

public void itemStateChanged(ItemEvent e)
{
String str; //#1
if(e.getItemSelectable()==cho)
str=cho.getSelectedItem(); //#2
text.setText(str); //#3
}

在#1行中,你声明了变量str,这里要注意,你只是声明,而没有定义,这时候str没有被初始化
在#2行中,你的确赋值了,但是如果if中的表示为false呢?#2行就不做了,这时候str仍然没有被初始化。
在#3行中,由于之前if语句没有做,导致str没有被初始化,这种情况下直接使用是编译器不允许的,所以会报错。

简而言之,在使用一个引用前,必须确保任何一种情况下它都是被初始化过的,即必须创建一个对象让他用或者让他指向null。
DeviLeo 2007-12-15
  • 打赏
  • 举报
回复
getSource()方法返回的是对象,是ActionEvent类从祖父类java.util.EventObject中继承过来的
getActioncommand()方法返回的是字符串。该默认值为事件源所对应组件的标签。
getLabel()方法返回的也是字符串,返回的是组件的标签。

getActioncommand()和getLabel()的区别:

JButton jbutton_1=new JButton("jbutton");
JButton jbutton_2=new JButton("jbutton"); //两个按钮标签一样

jbutton_1.setActionCommand("jbutton_1"); //设置按钮1的ActionCommand值为"jbutton_1"
jbutton_2.setActionCommand("jbutton_2"); //设置按钮2的ActionCommand值为"jbutton_2"

System.out.println(jbutton_1.getLabel()); //输出:jbutton
System.out.println(jbutton_2.getLabel()); //输出:jbutton
System.out.println(jbutton_1.getActionCommand()); //输出:jbutton_1
System.out.println(jbutton_2.getActionCommand()); //输出:jbutton_2

看到这里是不是有点明白了?当两个按钮的标签值一样时,使用getLabel()方法是不能区别事件源的,只有通过事先设置好的ActionCommand才能区别开来,如果懒得设置ActionCommand,就直接用getSource()方法来区别事件源。
wangjie1986 2007-12-15
  • 打赏
  • 举报
回复
各位高手,听你们解释后,我又进行了如下改进,将String str一句提到if之前,也就是说提前于if进行定义,扩大它的作用域,然后再在if 里面写上str=......,发现if 下面的一条语句不会报错了,但是setText(str)中的str又会报错,这是为什么啊,难道if里面就不能又单条赋值语句吗,可我试了将str的定义为类的成员变量就一切解决了,看来还是str的作用域问题,可是我将str在方法中提前定义了啊,应该是将它扩大了,为什么还不行呢,讲的又点罗嗦了,希望哪位能在解释下啊,不甚感激!
wangjie1986 2007-12-15
  • 打赏
  • 举报
回复
呵呵,真是高手啊,听你讲完了之后,不能说彻底明白了,但是和你有同感了,你的解释和现象好象很吻合的
另外我还想问个问题,我是刚学JAVA的,有些内容,怎么翻数都没有,所以只能到这来问了,希望你能在给我回答次


Java的事件类中几乎每个事件类都有返回触发事件源的方法,并且他们还都个公共的getsource()方法可以返回触发事件的事件源,他们之间有什么区别吗,都用getsource()来判断不就行了吗,为什么要那么多啊?好多书上都没给出解释,望高手解释下,谢谢了,另外Button里面的.getActioncommand()与.getLabel()方法什么区别啊,我试了下,觉得返回的都是Button上的字符啊?
这些问题困饶了我好半天了,真诚希望详细的解答,我会尽量给高分的.再次谢谢了!

真心谢谢了,我会尽量加分的,谢谢了!
dracularking 2007-12-15
  • 打赏
  • 举报
回复
感觉ls正解

编译器提示
Syntax error, insert "AssignmentOperator Expression" to complete Assignment
恰恰是认为在单语句作用域情况下的语法错误 即加入了声明的赋值语句不完整
有这种判断暗示着编译器不允许此种情况出现。
DeviLeo 2007-12-15
  • 打赏
  • 举报
回复
我是这么理解的,勉强说的过去。

if(e.getItemSelectable()==cho)
String str=cho.getSelectedItem();

因为if后面没有花括号,所以只会执行一句,那么你的字符串变量str的作用域就只限于当前的这一条定义语句,定义好之后就没用了,就等着被垃圾收集器回收,编译器会认为这是一条没有意义的定义,就好像除数为0一样,一点意义都没有,所以编译器会报错。

但是有了花括号之后就不同了,字符串变量str的作用域被扩大了,只要作用域没有结束,就可以对变量str进行任何操作,虽然你现在只有一条定义语句,但编译器会认为你可能以后会在后面添加对于str的处理。

if(e.getItemSelectable()==cho)
{
String str=cho.getSelectedItem();
str=new String("...");
//可以对str进行任何操作
}

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧