《Java编程思想》读书笔记(11)

本文通过示例探讨了Swing中按钮事件被多个监听器处理时的顺序问题,并介绍了如何通过分离业务逻辑与用户界面来提高代码的复用性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Swing的事件模型的优点就在于它的灵活性。你可以调用方法给组件添加或删除事件。今天再看这一节时,想到了一个以前没想过的小问题,如果一个按钮先后注册了两个监听者Listerner1, Listerner2,那么在单击按钮时,事件处理的顺序到底是如何的哪?真的是我以前一直以为的两者构成了一个监听者链表,Listerner2接在Listerner1后面吗?那就是说Listerner1会先处理接收的事件哪?真的是这样吗?


None.gifpackagecom.vitamin.UI;
None.gif
importjava.awt.BorderLayout;
None.gif
importjava.awt.Container;
None.gif
importjava.awt.event.ActionEvent;
None.gif
importjava.awt.event.ActionListener;
None.gif
None.gif
importcom.vitamin.*;
None.gif
importcom.vitamin.Console.console;
None.gif
importjava.awt.*;
None.gif
importjavax.swing.*;
None.gif
None.gif
publicclassHelloTestextendsJFrame
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
privateJButtonbtnOK=null;
InBlock.gif
privateJLabellbInfo=null;
ExpandedSubBlockStart.gifContractedSubBlock.gif
/***//**
InBlock.gif*
@paramargs
ExpandedSubBlockEnd.gif
*/

InBlock.gif
publicHelloTest()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.btnOK=newJButton("确定");
InBlock.gif
this.lbInfo=newJLabel();
InBlock.gif
this.btnOK.addActionListener(newL1());
InBlock.gif
this.btnOK.addActionListener(newL2());
InBlock.gifContainercon
=this.getContentPane();
InBlock.gifcon.setLayout(
newBorderLayout());
InBlock.gifcon.add(
this.btnOK,BorderLayout.SOUTH);
InBlock.gifcon.add(
this.lbInfo,BorderLayout.NORTH);
InBlock.gifconsole.run(
this,400,400);
ExpandedSubBlockEnd.gif}

InBlock.gif
classL1implementsActionListener
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
publicvoidactionPerformed(ActionEvente)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giflbInfo.setText(
"");
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
classL2implementsActionListener
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
publicvoidactionPerformed(ActionEvente)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifJOptionPane.showMessageDialog(HelloTest.
this,"L2接收到事件");
InBlock.giflbInfo.setText(
"Hello");
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
publicstaticvoidmain(String[]args)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//TODOAuto-generatedmethodstub
InBlock.gif
HelloTestht=newHelloTest();
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif}

InBlock.gif
ExpandedBlockEnd.gif}

None.gif

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


运行后居然发现” L2接收到事件先发生了,因为lbInfoText是空的。汗。。。

将业务逻辑(business logic)与用户界面分离开来

一般情况下,设计类的时候总是强调一个类"只作一件事情"。涉及用户界面的时候更是如此,因为你很可能会把"要作什么"同"要怎样显示"给混在一起了。这种耦合严重妨碍了代码的复用。比较好的做法是将"业务逻辑(business login)"同GUI分离开来。这样不仅方便了业务逻辑代码的复用,也简化了GUI的复用。

还有一种情况,就是多层系统(multitiered systems),也就是说”业务对象(business object)"完全贮存在另一台机器上。业务规则的集中管理能使规则的更新立即对新交易生效,因此这是这类系统所追求的目标。但是很多应用程序都会用到这些业务对象,所以它们绝不能同特定的显示模式连在一起。它们应该只做业务处理,别的什么都不管.

None.gifimportjavax.swing.*;
None.gif
importjava.awt.*;
None.gif
importjavax.swing.event.*;
None.gif
importjava.awt.event.*;
None.gif
importjava.applet.*;
None.gif
importcom.vitamin.Console.*;
ExpandedBlockStart.gifContractedBlock.gif
classBusinessLogicdot.gif{
InBlock.gif
privateintmodifier;
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicBusinessLogic(intmod)dot.gif{modifier=mod;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidsetModifier(intmod)dot.gif{modifier=mod;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicintgetModifier()dot.gif{returnmodifier;}
InBlock.gif
//Somebusinessoperations:
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicintcalculation1(intarg)dot.gif{returnarg*modifier;}
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicintcalculation2(intarg)dot.gif{returnarg+modifier;}
ExpandedBlockEnd.gif}

ExpandedBlockStart.gifContractedBlock.gif
publicclassSeparationextendsJAppletdot.gif{
InBlock.gif
privateJTextField
InBlock.gift
=newJTextField(15),
InBlock.gifmod
=newJTextField(15);
InBlock.gif
privateJButton
InBlock.gifcalc1
=newJButton("Calculation1"),
InBlock.gifcalc2
=newJButton("Calculation2");
InBlock.gif
privateBusinessLogicbl=newBusinessLogic(2);
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicstaticintgetValue(JTextFieldtf)dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
trydot.gif{
InBlock.gif
returnInteger.parseInt(tf.getText());
ExpandedSubBlockStart.gifContractedSubBlock.gif}
catch(NumberFormatExceptione)dot.gif{
InBlock.gif
return0;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockStart.gifContractedSubBlock.gif
classCalc1LimplementsActionListenerdot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidactionPerformed(ActionEvente)dot.gif{
InBlock.gift.setText(Integer.toString(
InBlock.gifbl.calculation1(getValue(t))));
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockStart.gifContractedSubBlock.gif
classCalc2LimplementsActionListenerdot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidactionPerformed(ActionEvente)dot.gif{
InBlock.gift.setText(Integer.toString(
InBlock.gifbl.calculation2(getValue(t))));
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
//Ifyouwantsomethingtohappenwhenever
InBlock.gif
//aJTextFieldchanges,addthislistener:
ExpandedSubBlockStart.gifContractedSubBlock.gif
classModLimplementsDocumentListenerdot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidchangedUpdate(DocumentEvente)dot.gif{}
ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidinsertUpdate(DocumentEvente)dot.gif{
InBlock.gifbl.setModifier(getValue(mod));
ExpandedSubBlockEnd.gif}

ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidremoveUpdate(DocumentEvente)dot.gif{
InBlock.gifbl.setModifier(getValue(mod));
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockStart.gifContractedSubBlock.gif
publicvoidinit()dot.gif{
InBlock.gifContainercp
=getContentPane();
InBlock.gifcp.setLayout(
newFlowLayout());
InBlock.gifcp.add(t);
InBlock.gifcalc1.addActionListener(
newCalc1L());
InBlock.gifcalc2.addActionListener(
newCalc2L());
InBlock.gifJPanelp1
=newJPanel();
InBlock.gifp1.add(calc1);
InBlock.gifp1.add(calc2);
InBlock.gifcp.add(p1);
InBlock.gifmod.getDocument().addDocumentListener(
newModL());
InBlock.gifJPanelp2
=newJPanel();
InBlock.gifp2.add(
newJLabel("Modifier:"));
InBlock.gifp2.add(mod);
InBlock.gifcp.add(p2);
ExpandedSubBlockEnd.gif}

ExpandedSubBlockStart.gifContractedSubBlock.gif
publicstaticvoidmain(String[]args)dot.gif{
InBlock.gifconsole.run(
newSeparation(),250,100);
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值