CodeGym /Kurslar /JAVA 25 SELF /Swing və AWT-də hadisələr: əsaslar, nümunələr

Swing və AWT-də hadisələr: əsaslar, nümunələr

JAVA 25 SELF
Səviyyə , Dərs
Mövcuddur

1. Swing və AWT-yə çox qısa giriş

Əgər Java avtomobil olsaydı, onda Swing və AWT — onun “idarə paneli” və “sükanı” olardı. AWT (Abstract Window Toolkit) — Java-da pəncərəli tətbiqlər yaratmaq üçün ilk kitabxanadır. O, OS-in “yerli” idarəetmə elementlərindən istifadə edir, buna görə Windows, Linux və Mac-da fərqli görünür.

Swing — AWT üzərində daha müasir bir təbəqədir, tamamilə Java-da yazılıb. Swing daha gözəl, çevikdir, çoxlu əlavə imkanları dəstəkləyir və bütün platformalarda eyni cür görünür (demək olar ki). Hər iki halda bütün interfeys elementləri (düymələr, mətn sahələri, checkbox-lar və s.) hadisələrlə işləməni dəstəkləyir.

Bu mühazirədə Swing istifadə edəcəyik: o, yeni başlayanlar üçün daha sadədir və tədris nümunələrində daha çox rast gəlinir. Gəlin ən məşhur tapşırıq — düymənin basılmasına reaksiya — nümunəsi üzərindən hadisələrin emalının necə qurulduğunu anlayaq.

Düymənin yaradılması

Swing-də düymə belə yaradılır:

JButton button = new JButton("Məni bas!");

Burada “Məni bas!” — düymənin üzərindəki yazıdır.

Dinləyicinin əlavə edilməsi

Basmaya reaksiya vermək üçün hadisəyə dinləyicini “qoşmaq” lazımdır:

button.addActionListener(new MyActionListener());

Bəs bu MyActionListener kimdir? Bu, ActionListener interfeysini reallaşdıran sinifdir:

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

public class MyActionListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Düymə basıldı!");
    }
}

İstifadəçi düyməni basanda, Swing addActionListener vasitəsilə qeydiyyata alınmış bütün dinləyicilərin actionPerformed metodunu çağırır.

Tam nümunə: düyməli sadə pəncərə

Gəlin hər şeyi birləşdirib işlək bir tətbiq yaradaq:

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

public class SimpleButtonApp {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Hadisə nümunəsi");
        JButton button = new JButton("Məni bas!");

        // Düyməyə dinləyici əlavə edirik
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Düymə basıldı!");
                JOptionPane.showMessageDialog(frame, "Ura! Düymə basıldı!");
            }
        });

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(button);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

Burada nə baş verir:

  • Pəncərə yaradırıq (JFrame).
  • Düymə yaradırıq (JButton).
  • Dinləyici əlavə edirik (ayrı fayllar yaratmamaq üçün anonim sinif).
  • actionPerformed daxilində konsola və açılan pəncərəyə (JOptionPane) mesaj çıxarırıq.
  • Düyməni pəncərəyə əlavə edir və pəncərəni istifadəçiyə göstəririk.

Özünüz sınayın: bu kodu kopyalayın, işə salın — və düyməni basın!

2. Anonim siniflər və lambda ifadələri

Müasir Java kodunda tək bir emalçı üçün ayrıca siniflər yazmaq — çörək almağa tankla getməyə bənzəyir. Xeyli rahatdır ki, anonim siniflər və ya lambda ifadələrindən istifadə edəsiniz.

Anonim sinif

Bu yanaşmanı yuxarıda artıq görmüşdük:

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // emal kodu
    }
});

Burada sinif birbaşa yerində, ad verilmədən elan edilir.

Lambda ifadəsi (Java 8+)

Əgər dinləyici interfeysi — funksionaldırsa (yəni yalnız bir abstrakt metoddan ibarətdirsə), lambda istifadə etmək olar:

button.addActionListener(e -> {
    System.out.println("Düymə lambda ilə basıldı!");
});

Hətta daha qısa — əgər bədən bir sətirdirsə:

button.addActionListener(e -> System.out.println("Lambda: düymə basıldı!"));

Bu, kodu yalnız qısaltmır, həm də onu daha oxunaqlı edir. Maraqlananlar üçün fakt: ActionListener interfeysi funksionaldır, çünki onda yalnız bir metod — actionPerformed var.

4. Digər hadisə tipləri

Dünya düymələrlə məhdudlaşmır! Swing və AWT-də demək olar ki, hər bir interfeys elementi öz hadisələrini dəstəkləyir. Ən məşhurları bunlardır:

Siçan hadisələri: MouseListener və MouseAdapter

Siçan kliklərinə reaksiya vermək istəyirsinizsə, MouseListener istifadə edin:

button.addMouseListener(new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("Düyməyə siçan kliki!");
    }
    // Qalan metodları boş saxlamaq olar
    @Override public void mousePressed(MouseEvent e) {}
    @Override public void mouseReleased(MouseEvent e) {}
    @Override public void mouseEntered(MouseEvent e) {}
    @Override public void mouseExited(MouseEvent e) {}
});

Tək bir emalçı üçün beş boş metod yazmaq o qədər də rahat deyil. Bunun üçün MouseAdapter var:

button.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("Düyməyə siçan kliki (adapter vasitəsilə)!");
    }
});

MouseAdapter interfeysin bütün metodlarını reallaşdırır, siz isə yalnız lazım olanları override edirsiniz.

Klaviatura hadisələri: KeyListener/KeyAdapter

Əgər düymə basmalarını tutmaq lazımdırsa:

button.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Düymə basıldı: " + e.getKeyChar());
    }
});

Mətn dəyişiklikləri: DocumentListener

Mətn sahələri (JTextField, JTextArea) üçün xüsusi dinləyicilər var:

JTextField textField = new JTextField();
textField.getDocument().addDocumentListener(new DocumentListener() {
    @Override
    public void insertUpdate(DocumentEvent e) {
        System.out.println("Mətn dəyişdirildi: " + textField.getText());
    }
    @Override public void removeUpdate(DocumentEvent e) {}
    @Override public void changedUpdate(DocumentEvent e) {}
});

Yeri gəlmişkən, əksər hadisələr üçün boş metodlar yazmamaq məqsədilə adapterlər mövcuddur.

5. Təcrübə: pəncərə və düymə ilə mini nümunə

Gəlin ən sadə GUI-tətbiqi edək: düyməli pəncərə; düymə basıldıqda sayğac artır və mesaj göstərilir.

Nümunə: klik sayğacı

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

public class ClickCounterApp {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Klik sayğacı");
        JButton button = new JButton("Məni bas!");
        JLabel label = new JLabel("Basımlar: 0");
        // Basma sayğacı (final və ya effektiv final olmalıdır)
        final int[] count = {0};

        button.addActionListener(e -> {
            count[0]++;
            label.setText("Basımlar: " + count[0]);
        });

        frame.setLayout(new FlowLayout());
        frame.add(button);
        frame.add(label);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(250, 100);
        frame.setVisible(true);
    }
}

İzah:

  • Sayğacı göstərmək üçün pəncərəni, düyməni və etiketi yaradırıq.
  • Lambda-nın final/effektiv final dəyişən məhdudiyyətini aşmaq üçün bir elementli massivdən istifadə edirik (final int[] count = {0};).
  • Hər dəfə düymə basıldıqda sayğacı artırır və etiketin mətnini yeniləyirik.

Təcrübə üçün fikir: hər beşinci basmada düymənin rəngini dəyişməyə çalışın!

6. Hadisə modeli daxildə necə işləyir

Gəlin bir dəqiqə “kapotun altına” baxaq. Siz bunu çağıranda:

button.addActionListener(listener);

düymə (obyekt JButton) dinləyicinizi daxili siyahıya əlavə edir. İstifadəçi düyməni basanda, daxilində aşağıdakılar baş verir:

  1. Düymə hadisə obyektini yaradır (ActionEvent).
  2. Düymə dinləyicilər siyahısını gəzərək hər biri üçün metod actionPerformed çağırır.
  3. Emalçınız lazım olan addımları yerinə yetirir (məsələn, etiketi yeniləyir).

Əsas odur ki, yadda saxlayın: hər bir hadisənin istənilən sayda dinləyicisi ola bilər — bir düymə üçün bir neçə emalçı əlavə edə bilərsiniz, onlar növbə ilə çağırılacaq.

7. Vizual sxem: hadisənin emalı

graph TD
    A[İstifadəçi düyməni basdı] --> B{JButton}
    B --> C[ActionEvent yarat]
    C --> D[Bütün dinləyicilər üçün actionPerformed çağır]
    D --> E[Emalçı hərəkətləri yerinə yetirir]

7. Swing və AWT-də hadisələrlə işləyərkən tipik səhvlər

Səhv № 1: dinləyicini qeydiyyatdan keçirməyi unutmusunuz. Düymə basmalara reaksiya vermir, çünki siz addActionListener çağırmağı unutmusunuz.

Səhv № 2: emalçıda ağır iş. Hadisə emalçısında uzun döngə işə salırsınızsa və ya internetdən nəsə yükləyirsinizsə, interfeys “donacaq”. Uzunmüddətli tapşırıqlar üçün ayrı axınlardan və ya SwingWorker-dən istifadə edin.

Səhv № 3: final/effektiv final olmadan lambda daxilindən dəyişəni dəyişdirməyə cəhd. Lambda daxilində yalnız final və ya “effektiv final” dəyişənlərdən istifadə etmək olar. Sayğaclar üçün massivlərdən və ya xüsusi siniflərdən istifadə edin (AtomicInteger, ciddi yanaşma istəyirsinizsə).

Səhv № 4: dinləyicini silməyi unutmusunuz. Komponenti silirsinizsə, amma dinləyicini silməmisinizsə, yaddaş sızması mümkündür. Komponent artıq lazım olmadıqda abunələri ləğv edin.

Səhv № 5: interfeysin bütün metodları reallaşdırılmayıb. Məsələn, MouseListener-i birbaşa reallaşdırırsınızsa, bütün metodları unutmayın! Daha yaxşısı adapterlərdən istifadə edin (MouseAdapter, KeyAdapter).

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION