event source => listener

本文介绍了一个简单的Java Swing GUI应用程序的创建过程。通过实例演示了如何使用按钮组件,并为按钮注册监听器来响应点击事件,实现按钮文本的动态改变。

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

package HeadFirstJava;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleGui {
    JButton button;
    
    public static void main(String[] args) {
        SimpleGui gui = new SimpleGui();
        gui.go();
    }
    public void go() {
        JFrame frame = new JFrame();
        button = new JButton("click me");
        // event registration
        // button is 'event source'
        button.addActionListener(new ButtonListener()); 
        frame.getContentPane().add(BorderLayout.EAST, button);
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
    // listener class
    class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            // TODO Auto-generated method stub
            button.setText("Ouch");
        }
        
    }
}


这是我CloseEventClass.ts的代码: import { Event2 } from './Event'; export class CloseEvent2 extends Event2 implements CloseEvent { readonly code: number; readonly reason: string; readonly wasClean: boolean; constructor(type: string, { code, reason }: CloseEventInit = {}) { super(type); this.code = code || 0; this.reason = reason || ''; this.wasClean = this.code === 0; } } export const CloseEventClass = typeof CloseEvent !== 'undefined' ? CloseEvent : CloseEvent2; 这是我ErrorEventClass.ts的代码: import { Event2 } from './Event'; export class ErrorEvent2 extends Event2 implements ErrorEvent { readonly colno: number; readonly error: any; readonly filename: string; readonly lineno: number; readonly message: string; constructor(type: string, { colno, error, filename, lineno, message }: ErrorEventInit = {}) { super(type); this.error = error; this.colno = colno || 0; this.filename = filename || ''; this.lineno = lineno || 0; this.message = message || ''; } } export const ErrorEventClass = typeof ErrorEvent !== 'undefined' ? ErrorEvent : ErrorEvent2; 这是我MessageEventClass.ts的代码: import { Event2 } from './Event'; export class MessageEvent2 extends Event2 implements MessageEvent { public readonly data: any; public readonly origin: string; public readonly lastEventId: string; public readonly source: any; public readonly ports: ReadonlyArray<any>; constructor( type: string, { data = null, origin = '', lastEventId = '', source = null, ports = [] }: MessageEventInit = {}, ) { super(type); this.data = data; this.origin = `${origin}`; this.lastEventId = `${lastEventId}`; this.source = source; this.ports = [...ports]; } initMessageEvent(): void { throw Error('Deprecated method'); } } export const MessageEventClass = typeof MessageEvent !== 'undefined' ? MessageEvent : MessageEvent2; 这是我Multiplexer.ts的代码: import { TypedEmitter } from '../../common/TypedEmitter'; import { Message } from './Message'; import { MessageType } from './MessageType'; import { EventClass } from './Event'; import { CloseEventClass } from './CloseEventClass'; import { ErrorEventClass } from './ErrorEventClass'; import { MessageEventClass } from './MessageEventClass'; import Util from '../../app/Util'; interface MultiplexerEvents extends WebSocketEventMap { empty: Multiplexer; channel: { channel: Multiplexer; data: ArrayBuffer }; open: Event; close: CloseEvent; message: MessageEvent; } export interface WebsocketEventEmitter { dispatchEvent(event: Event): boolean; addEventListener<K extends keyof WebSocketEventMap>( type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions, ): void; removeEventListener<K extends keyof WebSocketEventMap>( type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions, ): void; } export class Multiplexer extends TypedEmitter<MultiplexerEvents> implements WebSocket { readonly CONNECTING = 0; readonly OPEN = 1; readonly CLOSING = 2; readonly CLOSED = 3; public binaryType: BinaryType = 'blob'; public readyState: number; private channels: Map<number, { channel: Multiplexer; emitter: WebsocketEventEmitter }> = new Map(); private nextId = 0; private maxId = 4294967296; private storage: Array<string | ArrayBufferLike | Blob | ArrayBufferView> = []; private readonly messageEmitter: WebsocketEventEmitter; private emptyTimerScheduled = false; public onclose: ((this: WebSocket, ev: CloseEvent) => any) | null = null; public onerror: ((this: WebSocket, ev: Event) => any) | null = null; public onmessage: ((this: WebSocket, ev: MessageEvent) => any) | null = null; public onopen: ((this: WebSocket, ev: Event) => any) | null = null; public url = ''; public static wrap(ws: WebSocket): Multiplexer { return new Multiplexer(ws); } protected constructor(public readonly ws: WebSocket, private _id = 0, emitter?: WebsocketEventEmitter) { super(); this.readyState = this.CONNECTING; if (this._id === 0) { ws.binaryType = 'arraybuffer'; this.readyState = this.ws.readyState; } this.messageEmitter = emitter || ws; const onOpenHandler = (event: Event) => { this.readyState = this.ws.readyState; this.dispatchEvent(event); }; const onCloseHandler = (event: CloseEvent) => { this.readyState = this.ws.readyState; this.dispatchEvent(event); this.channels.clear(); }; const onErrorHandler = (event: Event) => { this.readyState = this.ws.readyState; this.dispatchEvent(event); this.channels.clear(); }; const onMessageHandler = (event: MessageEvent) => { const { data } = event; const message = Message.parse(data); switch (message.type) { case MessageType.CreateChannel: { const { channelId, data } = message; if (this.nextId < channelId) { this.nextId = channelId; } const channel = this._createChannel(channelId, false); this.emit('channel', { channel, data }); break; } case MessageType.RawStringData: { const data = this.channels.get(message.channelId); if (data) { const { channel } = data; const msg = new MessageEventClass('message', { data: Util.utf8ByteArrayToString(Buffer.from(message.data)), lastEventId: event.lastEventId, origin: event.origin, source: event.source, }); channel.dispatchEvent(msg); } else { console.error(`Channel with id (${message.channelId}) not found`); } break; } case MessageType.RawBinaryData: { const data = this.channels.get(message.channelId); if (data) { const { channel } = data; const msg = new MessageEventClass('message', { data: message.data, lastEventId: event.lastEventId, origin: event.origin, source: event.source, }); channel.dispatchEvent(msg); } else { console.error(`Channel with id (${message.channelId}) not found`); } break; } case MessageType.Data: { const data = this.channels.get(message.channelId); if (data) { const { emitter } = data; const msg = new MessageEventClass('message', { data: message.data, lastEventId: event.lastEventId, origin: event.origin, source: event.source, }); emitter.dispatchEvent(msg); } else { console.error(`Channel with id (${message.channelId}) not found`); } break; } case MessageType.CloseChannel: { const data = this.channels.get(message.channelId); if (data) { const { channel } = data; channel.readyState = channel.CLOSING; try { channel.dispatchEvent(message.toCloseEvent()); } finally { channel.readyState = channel.CLOSED; } } else { console.error(`Channel with id (${message.channelId}) not found`); } break; } default: const error = new Error(`Unsupported message type: ${message.type}`); this.dispatchEvent(new ErrorEventClass('error', { error })); } }; const onThisOpenHandler = () => { if (!this.storage.length) { return; } const ws = this.ws; if (ws instanceof Multiplexer) { this.storage.forEach((data) => ws.sendData(data)); } else { this.storage.forEach((data) => ws.send(data)); } this.storage.length = 0; }; const onThisCloseHandler = () => { ws.removeEventListener('open', onOpenHandler); ws.removeEventListener('error', onErrorHandler); ws.removeEventListener('close', onCloseHandler); this.messageEmitter.removeEventListener('message', onMessageHandler); this.off('close', onThisCloseHandler); this.off('open', onThisOpenHandler); }; ws.addEventListener('open', onOpenHandler); ws.addEventListener('error', onErrorHandler); ws.addEventListener('close', onCloseHandler); this.messageEmitter.addEventListener('message', onMessageHandler); this.on('close', onThisCloseHandler); this.on('open', onThisOpenHandler); this.scheduleEmptyEvent(); } public get bufferedAmount(): number { return 0; } public get extensions(): string { return ''; } public get protocol(): string { return ''; } public get id(): number { return this._id; } private scheduleEmptyEvent(): void { if (this.emptyTimerScheduled) { return; } this.emptyTimerScheduled = true; Promise.resolve().then(() => { if (this.emptyTimerScheduled) { this.emptyTimerScheduled = false; this.emit('empty', this); } }); } private clearEmptyEvent(): void { if (this.emptyTimerScheduled) { this.emptyTimerScheduled = false; } } public close(code = 1000, reason?: string): void { if (this.readyState === this.CLOSED || this.readyState === this.CLOSING) { return; } if (this._id) { this.readyState = this.CLOSING; try { const message = Message.fromCloseEvent(this._id, code, reason).toBuffer(); if (this.ws instanceof Multiplexer) { this.ws.sendData(message); } else { this.ws.send(message); } this.emit('close', new CloseEventClass('close', { code, reason })); } finally { this.readyState = this.CLOSED; } } else { this.ws.close(code, reason); } } // public send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void { // if (this.ws instanceof Multiplexer) { // if (typeof data === 'string') { // data = Message.createBuffer(MessageType.RawStringData, this._id, Buffer.from(data)); // } else { // data = Message.createBuffer(MessageType.RawBinaryData, this._id, Buffer.from(data)); // } // } // this._send(data); // } public send(data: string | ArrayBuffer | Blob | ArrayBufferView): void { let out: string | ArrayBuffer | Blob | ArrayBufferView; if (typeof data === 'string') { out = data; } else if (data instanceof ArrayBuffer) { out = data; } else if (ArrayBuffer.isView(data)) { // 修改此处不要转换为 Buffer out = (data as ArrayBufferView); } else { out = data; // Blob 或其他合法类型 } this.ws.send(out); } // public sendData(data: string | ArrayBufferLike | Blob | ArrayBufferView): void { // if (this.ws instanceof Multiplexer) { // data = Message.createBuffer(MessageType.Data, this._id, Buffer.from(data)); // } // this._send(data); // } public sendData(data: string | ArrayBufferLike | Blob | ArrayBufferView): void { if (this.ws instanceof Multiplexer) { let buf: Buffer; if (typeof data === 'string') { buf = Message.createBuffer(MessageType.Data, this._id, Buffer.from(data)); } else if (data instanceof ArrayBuffer) { buf = Message.createBuffer(MessageType.Data, this._id, Buffer.from(data)); } else if (ArrayBuffer.isView(data)) { buf = Message.createBuffer(MessageType.Data, this._id, Buffer.from(data.buffer, data.byteOffset, data.byteLength)); } else if (data instanceof Blob) { // Blob 需要异步读取,可以暂时 throw 或转换为 ArrayBuffer throw new Error('Blob not supported yet'); } else { // 保护代码 throw new Error('Unsupported data type'); } data = buf; } this._send(data); } private _send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void { const { readyState } = this; if (readyState === this.OPEN) { if (this.ws instanceof Multiplexer) { this.ws.sendData(data); } else { this.ws.send(data); } } else if (readyState === this.ws.CONNECTING) { this.storage.push(data); } else { throw Error(`Socket is already in CLOSING or CLOSED state.`); } } private _createChannel(id: number, sendOpenEvent: boolean): Multiplexer { const emitter = new TypedEmitter<MultiplexerEvents>(); const channel = new Multiplexer(this, id, emitter); this.channels.set(id, { channel, emitter }); if (sendOpenEvent) { if (this.readyState === this.OPEN) { Util.setImmediate(() => { channel.readyState = this.OPEN; channel.dispatchEvent(new EventClass('open')); }); } } else { channel.readyState = this.readyState; } channel.addEventListener('close', () => { this.channels.delete(id); if (!this.channels.size) { this.scheduleEmptyEvent(); } }); this.clearEmptyEvent(); return channel; } public createChannel(data: Buffer): Multiplexer { if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) { throw Error('Incorrect socket state'); } const id = this.getNextId(); const channel = this._createChannel(id, true); this.sendData(Message.createBuffer(MessageType.CreateChannel, id, data)); return channel; } private getNextId(): number { let hitTop = false; while (this.channels.has(++this.nextId)) { if (this.nextId === this.maxId) { if (hitTop) { throw Error('No available id'); } this.nextId = 0; hitTop = true; } } return this.nextId; } public dispatchEvent(event: Event): boolean { if (event.type === 'close' && typeof this.onclose === 'function') { Reflect.apply(this.onclose, this, [event]); } if (event.type === 'open' && typeof this.onopen === 'function') { Reflect.apply(this.onopen, this, [event]); } if (event.type === 'message' && typeof this.onmessage === 'function') { Reflect.apply(this.onmessage, this, [event]); } if (event.type === 'error' && typeof this.onerror === 'function') { Reflect.apply(this.onerror, this, [event]); } return super.dispatchEvent(event); } } 问题出在哪里,怎么解决
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值