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

import com.vitamin.*;
import com.vitamin.Console.console;
import java.awt.*;
import javax.swing.*;

public class HelloTest extends JFrame


{
private JButton btnOK = null;
private JLabel lbInfo = null;

/** *//**
* @param args
*/
public HelloTest()

{
this.btnOK = new JButton("确定");
this.lbInfo = new JLabel();
this.btnOK.addActionListener(new L1());
this.btnOK.addActionListener(new L2());
Container con = this.getContentPane();
con.setLayout(new BorderLayout());
con.add(this.btnOK,BorderLayout.SOUTH);
con.add(this.lbInfo,BorderLayout.NORTH);
console.run(this,400,400);
}
class L1 implements ActionListener

{
public void actionPerformed(ActionEvent e)

{
lbInfo.setText("");
}
}
class L2 implements ActionListener

{
public void actionPerformed(ActionEvent e)

{
JOptionPane.showMessageDialog(HelloTest.this,"L2接收到事件");
lbInfo.setText("Hello");
}
}
public static void main(String[] args)

{
// TODO Auto-generated method stub
HelloTest ht = new HelloTest();

}

}

运行后居然发现” L2接收到事件”先发生了,因为lbInfo的Text是空的。汗。。。
一般情况下,设计类的时候总是强调一个类"只作一件事情"。涉及用户界面的时候更是如此,因为你很可能会把"要作什么"同"要怎样显示"给混在一起了。这种耦合严重妨碍了代码的复用。比较好的做法是将"业务逻辑(business login)"同GUI分离开来。这样不仅方便了业务逻辑代码的复用,也简化了GUI的复用。
还有一种情况,就是多层系统(multitiered systems),也就是说”业务对象(business object)"完全贮存在另一台机器上。业务规则的集中管理能使规则的更新立即对新交易生效,因此这是这类系统所追求的目标。但是很多应用程序都会用到这些业务对象,所以它们绝不能同特定的显示模式连在一起。它们应该只做业务处理,别的什么都不管.
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.applet.*;
import com.vitamin.Console.*;

class BusinessLogic
{
private int modifier;

public BusinessLogic(int mod)
{ modifier = mod; }

public void setModifier(int mod)
{ modifier = mod; }

public int getModifier()
{ return modifier; }
// Some business operations:

public int calculation1(int arg)
{ return arg * modifier;}

public int calculation2(int arg)
{ return arg + modifier;}
}

public class Separation extends JApplet
{
private JTextField
t = new JTextField(15),
mod = new JTextField(15);
private JButton
calc1 = new JButton("Calculation 1"),
calc2 = new JButton("Calculation 2");
private BusinessLogic bl = new BusinessLogic(2);

public static int getValue(JTextField tf)
{

try
{
return Integer.parseInt(tf.getText());

} catch(NumberFormatException e)
{
return 0;
}
}

class Calc1L implements ActionListener
{

public void actionPerformed(ActionEvent e)
{
t.setText(Integer.toString(
bl.calculation1(getValue(t))));
}
}

class Calc2L implements ActionListener
{

public void actionPerformed(ActionEvent e)
{
t.setText(Integer.toString(
bl.calculation2(getValue(t))));
}
}
// If you want something to happen whenever
// a JTextField changes, add this listener:

class ModL implements DocumentListener
{

public void changedUpdate(DocumentEvent e)
{}

public void insertUpdate(DocumentEvent e)
{
bl.setModifier(getValue(mod));
}

public void removeUpdate(DocumentEvent e)
{
bl.setModifier(getValue(mod));
}
}

public void init()
{
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(t);
calc1.addActionListener(new Calc1L());
calc2.addActionListener(new Calc2L());
JPanel p1 = new JPanel();
p1.add(calc1);
p1.add(calc2);
cp.add(p1);
mod.getDocument().addDocumentListener(new ModL());
JPanel p2 = new JPanel();
p2.add(new JLabel("Modifier:"));
p2.add(mod);
cp.add(p2);
}

public static void main(String[] args)
{
console.run(new Separation(), 250, 100);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述