1. 程式人生 > >java丨事件驅動程式設計學習筆記(二)

java丨事件驅動程式設計學習筆記(二)

一、匿名監聽器
監聽器類是特意為建立一個GUI元件(例如,一個按鈕)而設計的監聽物件。監聽器類不被其他應用程式所共享,因此,正確的做法是將它作為一個內部類定義在框架中。
可以使用匿名內部類簡化內部類監聽器。匿名內部類時沒有名字的內部類。它進一步完成定義內部類和建立一個該類的例項。
內部類EnlargeListener:

  •  

匿名內部類:

public ControlCircle(){
//omitted
jbtEnlarge.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
    canvas.enlarge();
    }
   }
 );
}
  • 部類的語法如下:
new SuperClassName/InterfaceName(){
//implement or override methods in superclass or interface
//Other method if necessary
}

由於匿名類是一種特殊的內部類,所以,可以將它看做有以下特徵的內部類:
(1)匿名內部類必須總是擴充套件父類或實現介面,但是它不能有顯式的extends或者implements子句。
(2)匿名內部類實現父類或介面中所有的抽象方法
(3)匿名內部類總是使用它的父類的五引數構造法建立例項。如果匿名內部類實現了介面,構造方法就是Object()
(4)匿名內部類被編譯為一個名為OuterClassNamen.class的類。例如,Test類中有兩個匿名內部類,那麼他們被編譯為Testn.class的類。例如,Test類中有兩個匿名內部類,那麼他們被編譯為Test1.class和Test$2.class
程式處理來自四個按鈕的事件
AnonymousListenerDemo.java

AnnoymousListener

二、定義監聽器類的另一種方式
定義監聽器類有很多其他方式。例如,改寫程式AnnoymousListenerDemo.java,新程式只建立一個監聽器,將這個監聽器註冊給按鈕,然後讓監聽器檢測出事件源,即那個按鈕觸發了這個事件
DetectSourceDemo.java

import javax.swing.*;
import java.awt.event.*;

public class DetectSourceDemo extends JFrame {
    //建立四個按鈕
    private JButton jbtNew = new JButton("New");
    private JButton jbtOpen = new JButton("Open");
    private JButton jbtSave = new JButton("Save");
    private JButton jbtPrint = new JButton("Print");

    public DetectSourceDemo() {
        //建立一個存放按鈕的面板
        JPanel panel = new JPanel();
        panel.add(jbtNew);
        panel.add(jbtOpen);
        panel.add(jbtSave);
        panel.add(jbtPrint);

        add(panel);
        //建立一個監聽器
        ButtonListener listener = new ButtonListener();
        //將監聽器註冊到事件源
        jbtNew.addActionListener(listener);
        jbtOpen.addActionListener(listener);
        jbtSave.addActionListener(listener);
        jbtPrint.addActionListener(listener);

    }
    class ButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            if(e.getSource()==jbtNew)//檢查事件源
                System.out.println("Process New");
            else if(e.getSource()==jbtOpen)
                System.out.println("Process Open");
            else if(e.getSource()==jbtSave)
                System.out.println("Process Save");
            else if(e.getSource()==jbtPrint)
                System.out.println("Process Print");
        }
    }
    /** Main Method */
    public static void main(String[] args) {
        JFrame frame = new DetectSourceDemo();
        frame.setTitle("DetecSourceDemo");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
  •  

也可以自定義一個框架類實現ActionListener
FrameAsListenerDemo.java

import javax.swing.*;
import java.awt.event.*;

public class FrameAsListenerDemo extends JFrame implements ActionListener{
    //建立四個按鈕
    private JButton jbtNew = new JButton("New");
    private JButton jbtOpen = new JButton("Open");
    private JButton jbtSave = new JButton("Save");
    private JButton jbtPrint = new JButton("Print");

    public FrameAsListenerDemo() {
        //建立一個存放按鈕的面板
        JPanel panel = new JPanel();
        panel.add(jbtNew);
        panel.add(jbtOpen);
        panel.add(jbtSave);
        panel.add(jbtPrint);

        add(panel);
        //註冊監聽器到按鈕
        jbtNew.addActionListener(this);
        jbtOpen.addActionListener(this);
        jbtSave.addActionListener(this);
        jbtPrint.addActionListener(this);
    }
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==jbtNew)
            System.out.println("Process New");
        else if(e.getSource()==jbtOpen)
            System.out.println("Process Open");
        else if(e.getSource()==jbtSave)
            System.out.println("Process Save");
        else if(e.getSource()==jbtPrint)
            System.out.println("Process Print");
    }
    /**Main Method */
    public static void main(String[] args) {
        JFrame frame = new FrameAsListenerDemo();
        frame.setTitle("FrameAsListenerDemo");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

FrameAsListenerDemo
這種設計並不是很好,因為它將太多的責任放在一個類中。最好能設計一個監聽器類,它只負責處理事件,這樣會讓程式碼易於閱讀和維護
使用內部類和匿名內部類定義監聽器類已經成為事件處理程式設計的標準,因為它通常能提供清晰、乾淨和簡潔的程式碼。
三、貸款計算器
(1)建立一個5行2列的GridLayou面板。將標籤和文字域新增到面板中。將面板標題設定為“Enter loan amount,interset rate,and years”(請輸入貸款總額、利率和年份)
(2)建立另一個帶FlowLayout(FlowLayout.RIGHT)的面板,並將一個按鈕新增到這個面板
(3)將第一個面板新增到框架的中央,將第二個面板新增到框架的南邊
(4)建立和註冊用以處理點選按鈕動作事件的監聽器,處理器獲取關於貸款總額、利率和年數的輸入,計算月償還額和總償還額,然後再文字域顯示這些值
LoanCalculator.java

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.border.TitledBorder;

public class LoanCalculator extends JFrame{
    //為利率、年數、貸款總額、月償還額、總償還額建立文字框
    private JTextField jtfAnnualInterestRate = new JTextField();
    private JTextField jtfNumberOfYear = new JTextField();
    private JTextField jtfLoanAmount = new JTextField();
    private JTextField jtfMonthlyPayment = new JTextField();
    private JTextField jtfTotalPayment = new JTextField();
    //建立一個計算償還額的按鈕
    private JButton jbtComputeLoan = new JButton("Compute Payment");
    public LoanCalculator() {
        //存放標籤和文字框的面板p1
        JPanel p1 = new JPanel(new GridLayout(5,2));
        p1.add(new Label("Annual Interest Rate"));
        p1.add(jtfAnnualInterestRate);
        p1.add(new Label("Number of Years"));
        p1.add(jtfNumberOfYear);
        p1.add(new Label("Loan Amount"));
        p1.add(jtfLoanAmount);
        p1.add(new Label("Monthly Payment"));
        p1.add(jtfMonthlyPayment);
        p1.add(new Label("Total Payment"));
        p1.add(jtfTotalPayment);
        p1.setBorder(new TitledBorder("Enter loan amount,interest rate,and year"));
        //存放按鈕的面板p2
        JPanel p2 = new JPanel();
        p2.add(jbtComputeLoan);
        //將面板新增到框架中
        add(p1,BorderLayout.CENTER);
        add(p2,BorderLayout.SOUTH);
        //註冊監聽器
        jbtComputeLoan.addActionListener(new ButtonListener());

    }
    private class Loan{
        private double interest;
        private int year;
        private double loanAmount;
        public Loan(double interest,int year,double loanAmount) {
            this.interest=interest;
            this.year=year;
            this.loanAmount=loanAmount;
        }
        public double getMonthlyPayment() {
            double monthlyInterestRate = interest/1200;
            double monthlypayment = loanAmount*monthlyInterestRate/(1-(Math.pow(1/(1+monthlyInterestRate),year*12)));
            return monthlypayment;
        }
        public double getTotalPayment() {
            double totalPayment = getMonthlyPayment()*year*12;
            return totalPayment;
        }
    }
    private class ButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            //從文字框中獲取值
            double interest = Double.parseDouble(jtfAnnualInterestRate.getText());
            int year = Integer.parseInt(jtfNumberOfYear.getText());
            double loanAmount = Double.parseDouble(jtfLoanAmount.getText());
            //建立一個名為loan的Loan類的例項
            Loan loan = new Loan(interest,year,loanAmount);
            //顯示月償還額和總償還額
            jtfMonthlyPayment.setText(String.format("%.2f",loan.getMonthlyPayment()));
            jtfTotalPayment.setText(String.format("%.2f", loan.getTotalPayment()));
        }
    }
    public static void main(String[] args) {
        LoanCalculator frame = new LoanCalculator();
        frame.pack();
        frame.setTitle("LoanCalculator");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

--------------------- 作者:一梭 來源:CSDN 原文:https://blog.csdn.net/qq_36642407/article/details/78764173?utm_source=copy 版權宣告:本文為博主原創文章,轉載請附上博文連結!