Java obsługa zdarzeń


(marcinkk) #1

Witam, napisałem prosty program który zlicza kliknięcia przycisku i wypisuje w komponencie label ilość tych kliknięć. Niestety mam problem z obsługą zdarzeń. proszę o opinie kodu i pomoc z obslugą zdarzeń :wink::

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package java_swing_licznik;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.*;



/**

 *

 * @author marcin

 * program bedzie zliczal klikniecia przycisku

 */


class Okno{

    private JPanel jPanel = new JPanel();

    private JFrame jFrame = new JFrame();

    private JButton jButton = new JButton();

    private JLabel jLabel = new JLabel();

    private GridLayout gridLayout = new GridLayout(2, 1);

    private ActionListener actionListener;

    private ActionEvent actionEvent;


    public Okno() {

    }


    void createWindow(){

        int w = 200;

        int h = 100;

        jPanel.setLayout(gridLayout);


        jButton.setText("kliknij");

        jButton.addActionListener(actionListener);


        jLabel.setText("0");


        jFrame.setTitle("zliczacz klikniec !!");


        jFrame.setLocation(600, 300);

        jFrame.setSize(w, h);

        jFrame.add(jPanel);


        jPanel.add(jButton);

        jPanel.add(jLabel);


        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jFrame.setVisible(true);

    }


    void obslugaZdarzen(){

        int i = 0;

        Object object = actionEvent.getSource();

        if(object == jButton){

            i = i + 1;

            jLabel.setText(String.valueOf(i));

        }

    }

}


public class Java_swing_licznik {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                Okno window = new Okno();

                window.createWindow();

                window.obslugaZdarzen();

            }

        });

    }

}

(kostek135) #2

http://docs.oracle.com/javase/tutorial/ ... tener.html


(marcinkk) #3

dziękuje, ale chciałem żeby mi ktoś to wytłumaczył na moim przykładzie

-- Dodane 16.06.2012 (So) 21:16 --

po zamianie i działa tak jak chciałem ale przydała by się porada co do zmian kosmetycznych.

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package java_swing_licznik;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.*;




/**

 *

 * @author marcin

 * program bedzie zliczal klikniecia przycisku

 */


class Okno implements ActionListener{

    private JPanel jPanel = new JPanel();

    private JFrame jFrame = new JFrame();

    private JButton jButton = new JButton();

    private JLabel jLabel = new JLabel();

    private GridLayout gridLayout = new GridLayout(2, 1);

    private int i = 0;


    public Okno() {

    }


    void createWindow(){

        int w = 200;

        int h = 100;

        jPanel.setLayout(gridLayout);


        jButton.setText("kliknij");



        jLabel.setText("0");


        jFrame.setTitle("zliczacz klikniec !!");


        jFrame.setLocation(600, 300);

        jFrame.setSize(w, h);

        jFrame.add(jPanel);


        jPanel.add(jButton);

        jPanel.add(jLabel);


        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jFrame.setVisible(true);

        jButton.addActionListener(this);

    }


    @Override

    public void actionPerformed(ActionEvent e) {

        i = i + 1;

        jLabel.setText(String.valueOf(i));

    }


}


public class Java_swing_licznik {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                Okno window = new Okno();

                window.createWindow();

                //window.obslugaZdarzen();

            }

        });

    }

}

(kostek135) #4

Ech..

1) Konwencja przyjmuje jedną klasę na plik, chyba, że używasz klasy zagnieżdżonej, kiedy nie ma sensu żeby klasa podrzędna istniała poza ekosystemem nadrzędnej. Tu nie ma takiego przypadku.

2) Twoje Okno powinno dziedziczyć z JFrame, a nie używać instancji tej klasy.

3) Po co robisz pusty konstruktor, a potem wywołujesz na jego rzecz createWindow? nie można tego umieścić w konstruktorze?

4) Korzystasz ze swingu, który jest typowo nastawiony na MVC, to co piszesz jest bardzo dalekie od tych założeń, no ale whatever.

Na twoim przykładzie (pierwszy kod) nie dało się tego wytłumaczyć, bo robiłeś synchroniczne wywołanie, a nie podczepiałeś oczekujący na asynchroniczne zdarzenie kontroler.


(marcinkk) #5

poprawiłem trochę ten program, klasy są teraz w osobnych plikach i komponenty trochę uporządkowałem, dodałem komponent JButton i za jego pomocą po kliknięciu można wyjść z programu, no i czekam na uwagi :wink:, o to kod:

/*

 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package java_swing_licznik_v2;


import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;


/**

 *

 * @author marcin

 */

public class KlasaOkno extends JFrame implements ActionListener{


    private final int wysokosc = 100;

    private final int szerokosc = 200;

    private final int pozycja_okna_x = 400;

    private final int pozycja_okna_y = 200;

    private JPanel jPanel;

    private JButton jButtonLicz;

    private JButton jButtonWyjscie;

    private JLabel jLabel;

    private int i = 0;


    public KlasaOkno(){    

        jPanel = new JPanel();

        jLabel = new JLabel();

        jButtonLicz = new JButton();

        jButtonWyjscie = new JButton();


        setTitle("zliczacz klikniec !!");

        setLocation(pozycja_okna_x, pozycja_okna_y);

        setSize(szerokosc, wysokosc);

        setVisible(true);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(jPanel);


        jPanel.setLayout(new GridLayout(3, 1));

        jPanel.add(jLabel);

        jPanel.add(jButtonLicz);

        jPanel.add(jButtonWyjscie);


        jLabel.setText("0");


        jButtonLicz.setText("kliknij");

        jButtonLicz.addActionListener(this);


        jButtonWyjscie.setText("wyjscie");

        jButtonWyjscie.addActionListener(this);

    }



    @Override

    public void actionPerformed(ActionEvent e) {

        Object zrodlo = e.getSource();

        if(zrodlo == jButtonLicz){

            ++i;

            jLabel.setText(String.valueOf(i));

        } else if(zrodlo == jButtonWyjscie){

            System.exit(0);

        }

    }


}


 * To change this template, choose Tools | Templates

 * and open the template in the editor.

 */

package java_swing_licznik_v2;


import javax.swing.SwingUtilities;


/**

 *

 * @author marcin

 */

public class Java_swing_licznik_v2 {


    /**

     * @param args the command line arguments

     */

    public static void main(String[] args) {

        // TODO code application logic here

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                KlasaOkno klasaOkno = new KlasaOkno();

            }

        });

    }

}

(kostek135) #6

Nadal jest to dalekie od MVC, twój Model czyli wartość licznika jest silnie związany z Widokiem. Ciężko w tym momencie prezentować te dane na wiele sposobów. Darujmy już sobie ten przykład. Jest on za prosty, żeby wytłumaczyć o co chodzi. Jeśli chcesz się "naumieć" czegoś. Zrób program, który z pliku wczyta dane n/t osoby, przykładowy format może wyglądać tak: imię;nazwisko;wiek

Następnie dostępne będą dwa widoki, korzystające z jednego źródła danych. Jednym z widoków będzie JList, która do wyświetlania danych użyje przeciążonej metody toString(). Drugi widok to JTable, w którym kolejność komórek w wierszu może być ustalona w czasie kompilacji (if, else if), albo w czasie runtime przy pomocy refleksji i adnotacji.


(marcinkk) #7

dziękuje za uwagi :wink: postaram się to wykonać