java自定義事件
A. java中addMouseListener(this)中的this是指啥怎麼好多方法都有this ,this具體指啥,求詳解!!
this是指您正在編寫的這個類,在軟體運行時(運行時)所實例化的對象。
Swing程序可以說是基於「事件」的程序。所謂「事件」是指程序運行時所發生的事情,包括圖形界面的用戶交互操作、Swing組件內部對某事件的連續反應所產生的其他事件、某種情況下所發生的自定義事件。
運行時的事件是一個事件對象,它有三個要素:1、事件源是誰,也就是說是在哪個Swing組件中產生的這個事件;2、事件內部所包含的數據,我們可以將一些重要數據封裝在事件中;3、有那些監聽器對象負責處理這個事件。
總體來講,一個事件只有一個事件源,可以有0或多個負責處理這個事件的監聽器。
事件源負責向外拋出事件,拋出事件就是在告知添加到此事件源的所有監聽器,這個事件已經被拋出,已被添加到此事件源負責處理該事件的監聽器應該開始處理該事件了。
綜上所述,只有將監聽器添加到事件源上,當事件被事件源拋出後,才可能會有監聽器處理此事件。從你的例子來看,這是在向當前類(事件源)添加一個滑鼠事件監聽器(此監聽器還是當前類的實例)。
重復一下,只有將監聽器添加到事件源上,當事件被事件源拋出後,才可能會有監聽器處理此事件。
你必須清晰認識到:事件源、事件、監聽器是圍繞事件的三個不同概念。
作為初學者,很少有機會手動寫拋出事件的代碼。比如滑鼠事件作為Java內部定義好的事件,當用戶滑鼠在界面中執行任何動作(如移位、點擊、拖動等等等等),都會由Java已經封裝好的、支持滑鼠事件的組件作為事件源,向外拋出滑鼠事件。組件(事件源)拋出事件後,應該由添加到此事件源的滑鼠事件監聽器處理此事件。
一般來講,Java已經封裝好了很多內置事件監聽器的介面和實現類,要處理某事件,必須創建一個監聽器類,使其實現處理此事件監聽器的介面或繼承處理此事件監聽器的實現類。
B. java KeyEventHandler
EventHandler是一個委託聲明
public delegate void EventHandler( object sender , EventArgs e )
注意這里的參數,前者是一個對象(其實這里傳遞的是對象的引用,如果是button1的click事件則sender就是button1),後面是包含事件數據的類的基類。
下面我們研究一下Button類看看其中的事件聲明(使用WinCV工具查看),以Click事件為例。
public event EventHandler Click;
這里定義了一個EventHandler類型的事件Click
前面的內容都是C#在類庫中已經為我們定義好了的。下面我們來看編程時產生的代碼。
private void button1_Click(object sender, System.EventArgs e)
{
...
}
這是我們和button1_click事件所對應的方法。注意方法的參數符合委託中的簽名(既參數列表)。那我們怎麼把這個方法和事件聯系起來呢,請看下面的代碼。
this.button1.Click = new System.EventHandler(this.button1_Click);
把this.button1_Click方法綁定到this.button1.Click事件。 字串8
下面我們研究一下C#事件處理的工作流程,首先系統會在為我們創建一個在後台監聽事件的對象(如果是button1的事件那麼監聽事件的就是button1),這個對象用來產生事件,如果有某個用戶事件發生則產生對應的應用程序事件,然後執行訂閱了事件的所有方法。
二、簡單的自定義事件(1)
首先我們需要定義一個類來監聽客戶端事件,這里我們監聽鍵盤的輸入。
定義一個委託。
public delegate void UserRequest(object sender,EventArgs e);
前面的object用來傳遞事件的發生者,後面的EventArgs用來傳遞事件的細節,現在暫時沒什麼用處,一會後面的例子中將使用。
下面定義一個此委託類型類型的事件
public event UserRequest OnUserRequest;
下面我們來做一個死循環
public void Run() { bool finished=false; do { if (Console.ReadLine()=="h") { OnUserRequest(this,new EventArgs()); } }while(!finished); }
此代碼不斷的要求用戶輸入字元,如果輸入的結果是h,則觸發OnUserRequest事件,事件的觸發者是本身(this),事件細節無(沒有傳遞任何參數的EventArgs實例)。我們給這個類取名為UserInputMonitor。
下面我們要做的是定義客戶端的類 字串5
首先得實例化UserInputMonitor類
UserInputMonitor monitor=new UserInputMonitor();
然後我們定義一個方法。
private void ShowMessage(object sender,EventArgs e)
{
Console.WriteLine("HaHa!!");
}
最後要做的是把這個方法和事件聯系起來(訂閱事件),我們把它寫到庫戶端類的構造函數里。
Client(UserInputMonitor m)
{
m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage);
//m.OnUserRequest =new m.UserRequest(this.ShowMessage);
//注意這種寫法是錯誤的,因為委託是靜態的
}
下面創建客戶端的實例。
new Client(monitor);
對了,別忘了讓monitor開始監聽事件。
monitor.run();
大功告成,代碼如下:
using System;class UserInputMonitor{ public delegate void UserRequest(object sender,EventArgs e); //定義委託 public event UserRequest OnUserRequest; //此委託類型類型的事件 public void Run() { bool finished=false; do { if (Console.ReadLine()=="h") { OnUserRequest(this,new EventArgs()); } }while(!finished); }}
public class Client{ public static void Main() { UserInputMonitor monitor=new UserInputMonitor(); new Client(monitor); monitor.Run(); } private void ShowMessage(object sender,EventArgs e) { Console.WriteLine("HaHa!!"); } Client(UserInputMonitor m) { m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage); //m.OnUserRequest =new m.UserRequest(this.ShowMessage); //注意這種寫法是錯誤的,因為委託是靜態的 }} 字串3
三、進一步研究C#中的預定義事件處理機制
可能大家發現在C#中有些事件和前面的似乎不太一樣。例如
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
}
this.textBox1.KeyPress =newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
這里使用了KeyPressEventArgs而不是EventArgs作為參數。這里使用了KeyEventHandler委託,而不是EventHandler委託。
KeyPressEventArgs是EventArgs的派生類,而KeyEventHandler的聲明如下
public delegate void KeyEventHandler( object sender , KeyEventArgs e );
是參數為KeyEventArgs的委託。那為什麼KeyPress事件要這么做呢,我們可以從兩個類的構造函數來找答案。
public EventArgs();
public KeyPressEventArgs(char keyChar);
這里的keyData是什麼,是用來傳遞我們按下了哪個鍵的,哈。
我在KeyEventArgs中又發現了屬性
public char KeyChar { get; }
進一步證明了我的理論。下面我們來做一個類似的例子來幫助理解。
四、簡單的自定義事件(2)
拿我們上面做的例子來改。
我們也定義一個EventArgs(類似KeyEventArgs)取名MyEventArgs,定義一個構造函數public MyEventArgs(char keyChar),同樣我們也設置相應的屬性。代碼如下 字串3
using System;class public MyMyEventArgs(char keyChar) { this.keychar=keychar; } public char KeyChar { get { return keyChar; } }}
因為現在要監聽多個鍵了,我們得改寫監聽器的類中的do...while部分。改寫委託,改寫客戶端傳遞的參數。好了最終代碼如下,好累
using System;class public MyEventArgs(char keyChar) { this.keyChar=keyChar; } public char KeyChar { get { return keyChar; } }}
class UserInputMonitor{ public delegate void UserRequest(object sender,MyEventArgs e); //定義委託 public event UserRequest OnUserRequest; //此委託類型類型的事件 public void Run() { bool finished=false; do { string inputString= Console.ReadLine(); if (inputString!="") OnUserRequest(this,new MyEventArgs(inputString[0])); }while(!finished); }}
public class Client{ public static void Main() { UserInputMonitor monitor=new UserInputMonitor(); new Client(monitor); monitor.Run(); } private void ShowMessage(object sender,MyEventArgs e) { Console.WriteLine("捕捉到:{0}",e.KeyChar); } Client(UserInputMonitor m) { m.OnUserRequest =new UserInputMonitor.UserRequest(this.ShowMessage); //m.OnUserRequest =new m.UserRequest(this.ShowMessage); //注意這種寫法是錯誤的,因為委託是靜態的 }}
C. java自定義事件,線程a如何每一秒鍾觸發一個事件,然後另一個線程b監聽之,並作出反應
線程a是作為事件源,那麼線程a這個類就必須提供一個可以增加監聽器的方法,就像GUI編程中的addActionListener這個樣的方法。線程a這個類裡面是有一個專門存放監聽器的一個容器,例如是list。然後你 增加監聽器的方法就是把監聽器放進這個容器裡面。你用一個監聽器去監聽一個事件的發生,就可以在線程a這個類中,寫一個產生事件的一段代碼,然後每當產生一個事件之後,去遍歷list,去調用監聽器的對於這個事件的處理方法,這樣子就可以了。這應該就是java中的事件模式。
D. 關於java自定義異常類的一個代碼
1 程序中的異常指不期而至的各種狀況,如:文件找不到、網路連接失敗、非法參數等。異常是一個事件,它發生在程序運行期間,干擾了正常的指令流程。Java通 過API中Throwable類的眾多子類描述各種不同的異常。因而,Java異常都是對象,是Throwable子類的實例,描述了出現在一段編碼中的 錯誤條件。當條件生成時,錯誤將引發異常。
Java異常類層次結構圖:
{
=1L;
publicMyException(){
super();
}
publicMyException(Stringmsg){
super(msg);
}
}
使用的話就不演示了 如果你已經研究到了自定義異常 那麼我相信你也一定會使用了
如果不會使用 建議學會使用後再來看這篇文章
E. Java 添加按鈕點擊事件
xml文件代碼如下:
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
四種方法分述如下:
匿名內部類:
public class TestButtonActivity extends Activity {
Button btn1, btn2;
Toast tst;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_button);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast tst = Toast.makeText(TestButtonActivity.this, "111111111", Toast.LENGTH_SHORT);
tst.show();
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast tst = Toast.makeText(TestButtonActivity.this, "222222222", Toast.LENGTH_SHORT);
tst.show();
}
});
}
}
自定義單擊事件監聽類:
public class TestButtonActivity extends Activity {
Button btn1, btn2;
Toast tst;
class MyClickListener implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button1:
tst = Toast.makeText(TestButtonActivity.this, "111111111", Toast.LENGTH_SHORT);
tst.show();
break;
case R.id.button2:
tst = Toast.makeText(TestButtonActivity.this, "222222222", Toast.LENGTH_SHORT);
tst.show();
break;
default:
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_button);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn1.setOnClickListener(new MyClickListener());
btn2.setOnClickListener(new MyClickListener());
}
}
Activity繼承View.OnClickListener,由Activity實現OnClick(View view)方法,在OnClick(View view)方法中用switch-case對不同id代表的button進行相應的處理
public class TestButtonActivity extends Activity implements OnClickListener {
Button btn1, btn2;
Toast tst;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_button);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button1:
tst = Toast.makeText(this, "111111111", Toast.LENGTH_SHORT);
tst.show();
break;
case R.id.button2:
tst = Toast.makeText(this, "222222222", Toast.LENGTH_SHORT);
tst.show();
break;
default:
break;
}
}
}
最後一種是我今天看到的一種寫法,在XML文件中逗顯示指定按鈕的onClick屬性,這樣點擊按鈕時會利用反射的方式調用對應Activity中的click()方法地
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button2" />
這里在輸完android:的時候按下 Alt+/ 會有 onClick 屬性的提示, 但輸入到 android:onClick=逗 的地方按下 Alt+/ 並沒有提示 onClick 選項,讓我突然覺得這里好像有點問題。
public class TestButtonActivity extends Activity {
Button btn1, btn2;
Toast tst;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_button);
}
// 注意 這里沒有 @Override 標簽
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button1:
tst = Toast.makeText(this, "111111111", Toast.LENGTH_SHORT);
tst.show();
break;
case R.id.button2:
tst = Toast.makeText(this, "222222222", Toast.LENGTH_SHORT);
tst.show();
break;
default:
break;
}
}
}
這種寫法整個代碼中都不用聲明button就可以實現button的單擊事件。
F. java自定義事件監聽觸發的實現
java.util.EventObject 繼承
java.util.EventListener 實現
寫成自己的事件 。。。。。。。。。。。。
G. Java 編寫JFrame窗體右上角紅色打叉關閉按鈕的自定義事件
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class TestFrame {
public static void main(String[] args) {
JFrame frame=new JFrame();
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
int value=JOptionPane.showConfirmDialog(null, "確定要關閉嗎?");
if (value==JOptionPane.OK_OPTION) {
System.exit(0);
}
}
});
}
}
H. java如何將滑鼠點擊事件設置到特定圖片
圖片所在容器.addMouseListener(newMouseListener(){//添加滑鼠監聽
publicvoidmouseReleased(MouseEvente){
}
publicvoidmousePressed(MouseEvente){
}
publicvoidmouseExited(MouseEvente){
}
publicvoidmouseEntered(MouseEvente){
}
publicvoidmouseClicked(MouseEvente){//滑鼠點擊時執行
點擊後要執行的代碼
}
});
I. java自定義異常
代碼修改了,如下,有疑問可以追問:
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.JOptionPane;
publicclassNumExcp{
publicstaticvoidmain(String[]args){
NumExcpne=newNumExcp();
}
Frameframe;
Panelpanel;
TextFieldtf;
Buttonbtn;
NumExcp(){
frame=newFrame();
panel=newPanel();
btn=newButton("Check");
tf=newTextField(":");
ListenerAL=newListener();
btn.setEnabled(true);
frame.setVisible(true);
frame.setSize(400,400);
frame.setLocation(200,200);
panel.setSize(200,200);
panel.setVisible(true);
frame.add(panel);
frame.addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){
System.exit(0);
}
});
panel.add(tf);
panel.add(btn);
panel.setLayout(newFlowLayout(FlowLayout.CENTER));
btn.addActionListener(AL);
}
{
publicvoidactionPerformed(ActionEvente){
try{
intn=Integer.valueOf(tf.getText());
check(n);
}catch(Num_Exceptione1){
e1.e_message();
}
}
}
publicvoidcheck(intn)throwsNum_Exception{
if(n<10||n>100){
thrownewNum_Exception("請輸入between10to100:");
}else{
tf.setText("Congrats!Yourinputiscorrect!");
}
}
classNum_ExceptionextendsException{
privateNum_Exception(Stringmessage){
super(message);
}
publicvoide_message(){
JOptionPane.showMessageDialog(null,"Invalidinput!"+this.getMessage(),"",JOptionPane.ERROR_MESSAGE);
}
}
}
J. java 自定義事件的觸發及監聽
JAVA事件響應機制
1,先自定義一個事件
public class MyEvent extends java.util.EventObject{
public MyEvent(Object source)
{
super(source);
}
}
2,再自定義一個監聽器
public class MyListener implements java.util.EventListener{
//這里是當事件發生後的響應過程
public void EventActivated(MyEvent me)
{
System.out.println("事件已經被觸發");
}
}
3,以下這個類為觸發事件的事件源
public class MyObject {
private Vector vectorListeners=new Vector();
public synchronized void addMyListener(MyListener ml)
{
vectorListeners.addElement(ml);
}
public synchronized void removeMyListener(MyListener ml)
{
vectorListeners.removeElement(ml);
}
protected void activateMyEvent()
{
Vector tempVector=null;
MyEvent e=new MyEvent(this);
synchronized(this)
{
tempVector=(Vector)vectorListeners.clone();
for(int i=0;i<tempVector.size();i++)
{
MyListener ml=(MyListener)tempVector.elementAt(i);
ml.EventActivated(e);
}
}
}
//定義一個公用方法用於觸發事件
public void test()
{
activateMyEvent();
}
}
4,測試類
public class Test {
public static void main(String[] args)
{
MyObject mo=new MyObject();
//注冊該事件
mo.addMyListener(new MyListener());
//觸發該事件
mo.test();
}
}