Gyakorlati alapok IV.
Végre ablakozunk! (AWT, Swing, JavaFX)
Eseménykezelés + Button + exit
Amint arról a honlapon több helyen szó volt, programjaink vagy algoritmusvezéreltek, vagy eseményvezéreltek. Erről részletesen írtunk a Algoritmusvezéreltség - eseményvezéreltség című fejezetben. Ebben a fejezetcsomagban egészen eddig olyan programokat kreáltunk, amelyek ebben a tökéletes átmenetet képeztek: bár alapjában véve képesek eseményreakciókra, ezen tulajdonságukat eleddig mégsem használtuk ki. Egészen eddig a pontig, mert most jön az ügy legérdekesebb része: ablakos Java-alkalmazásunkat eseményvezéreltté tesszük!
Ehhez először találnunk kell 1 megfelelő objektumot, ez nyilvánvalóan a legismertebb és a legtöbbet használt, a gomb (button) lesz:
Programozási kiindulópontunk az IP-cím lekérdező alapkód:
Main.java
public class Main {
public static void main(String[] args) {
Window window = new Window();
}
}
Window.java
import javax.swing.*;
class Window extends JFrame {
Window() {
super();
String hostName = "x";
String ipNumber = "";
try{
ipNumber =
java.net.InetAddress.getByName(hostName).getHostAddress();
}catch(Exception ex){
System.out.println("Resolution was not successful.");
}
JFrame frame = new JFrame();
JLabel label = new JLabel();
label.setText("My IP-number is " + ipNumber);
frame.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.CENTER);
Center center = new Center();
frame.setSize(400, 300);
frame.setTitle("PJP - Penzes Java Programming");
center.setCenter(frame);
frame.setVisible(true);
}
}
Center.java
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import javax.swing.JFrame;
public class Center {
void setCenter(JFrame frame) {
Point center =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
int x = (int) center.getX() -
(frame.getWidth() / 2);
int y = (int) center.getY() -
(frame.getHeight() / 2);
Point ablakCenter = new Point(x, y);
frame.setLocation(ablakCenter);
}
}
Végeredmény (a monitor közepén / felbontástól függetlenül/):
-
exit gomb működik
Gyorsan nézzünk erre 1 működő példát!
Az alábbi kódban először kidobjuk a label-t, valamint az IP-cím lekérdezést és pontosan középre beteszünk egy button-objektumot. Az ehhez kapcsolódó kötelező metódusok a következők:
JButton button = new JButton("Exit");
button.setBounds(150, 100, 90, 25);
frame.add(button);
frame.setLayout(null);
Ez a button még nem csinál semmit, de már potenciálisan számíthatunk rá (rákattinthatunk, amire reagálni fog, de az eseményt még nem kezeltük le):
Main.java
public class Main {
public static void main(String[] args) {
Window window = new Window();
}
}
Window.java
import javax.swing.*;
class Window extends JFrame {
Window() {
super();
JFrame frame = new JFrame();
JButton button = new JButton("Exit");
button.setBounds(150, 100, 90, 25);
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Center center = new Center();
frame.setSize(400, 300);
frame.setTitle("PJP - Penzes Java Programming");
center.setCenter(frame);
frame.setLayout(null);
frame.setVisible(true);
}
}
Center.java
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import javax.swing.JFrame;
public class Center {
void setCenter(JFrame frame) {
Point center =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
int x = (int) center.getX() -
(frame.getWidth() / 2);
int y = (int) center.getY() -
(frame.getHeight() / 2);
Point ablakCenter = new Point(x, y);
frame.setLocation(ablakCenter);
}
}
Végeredmény (a monitor közepén / felbontástól függetlenül/):
-
exit gomb működik (jobb felső sarok)
-
a középen lévő Exit feliratú gomb nem működik
Az eseménykezelés azt jelenti, hogy az erre felkészített objektumokban a felhasználó kivált valamilyen eseményt, például rákattint egy gombra, vagy beír valamit egy szövegdobozba (textfield), stb.
Az események folyamatos érzékeléséről és figyeléséről az Actionlistener nevű interfész gondoskodik. Ez azonban még csak az eseménykezelés egyik fele, hiszen azt is le kell programoznunk, hogy mi legyen az esemény lekezelése. Ezt többféleképpen tudjuk megtenni.
1.
Először nézzük meg azt a megoldást, amely lambda-kifejezéssel dolgozik (A funkcionális interfész és a lambda-kifejezések című fejezet). Ez egyébként a Java 8 óta áll rendelkezésünkre és könnyed eleganciája miatt az eseménykezelésnél -ha lehetséges-, a továbbiakban ezt a mechanizmust fogjuk célzottan felhasználni.
A lekezelendő esemény legyen a programból való kilépés, azaz a System.exit(0) metódus meghívása (A totálisan destruktív magatartás: a System.exit() metódus című fejezet). A lambdás varázsige a következő:
button.addActionListener(event -> buttonAction());
Az utasítás voltaképpen egy különálló, buttonAction() nevű metódus felé mutat (ezt mi neveztük el ilyen módon), amelynek törzsében kötelezően ki kell dolgoznunk az esemény lekezelését, ebben az esetben a System.exit(0) függvény meghívását:
private void buttonAction() {
System.exit(0);
}
}
Nézzük meg a futtatható Java-kódot:
Main.java
public class Main {
public static void main(String[] args) {
Window window = new Window();
}
}
Window.java
import javax.swing.*;
class Window extends JFrame {
Window() {
super();
JFrame frame = new JFrame();
JButton button = new JButton("Exit");
button.setBounds(150, 100, 90, 25);
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(event -> buttonAction());
Center center = new Center();
frame.setSize(400, 300);
frame.setTitle("PJP - Penzes Java Programming");
center.setCenter(frame);
frame.setLayout(null);
frame.setVisible(true);
}
private void buttonAction() {
System.exit(0);
}
}
Center.java
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import javax.swing.JFrame;
public class Center {
void setCenter(JFrame frame) {
Point center =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
int x = (int) center.getX() -
(frame.getWidth() / 2);
int y = (int) center.getY() -
(frame.getHeight() / 2);
Point ablakCenter = new Point(x, y);
frame.setLocation(ablakCenter);
}
}
Végeredmény (a monitor közepén / felbontástól függetlenül/):
-
exit gomb működik (jobb felső sarok)
-
a középen lévő Exit feliratú gombra való kattintással a program kilép
2.
Az eseménykezelés "hagyományosabb" eszközzel, például névtelen osztály bevetésével is kivitelezhető (A "névtelen" osztály című fejezet). Erről az ActionListener interfész actionPerformed() nevű metódusa gondoskodik, amelynek törzsébe kell belevezetnünk konkrét eseménykezelő utasításainkat. Használatuk előtt a rutinokat az import java.awt.event.* utasítással be kell importálnunk!
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
Nézzük meg a futtatható Java-kódot:
Main.java
public class Main {
public static void main(String[] args) {
Window window = new Window();
}
}
Window.java
import java.awt.event.*;
import javax.swing.*;
class Window extends JFrame {
Window() {
super();
JFrame frame = new JFrame();
JButton button = new JButton("Exit");
button.setBounds(150, 100, 90, 25);
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(new ActionListener(){
public void
actionPerformed(ActionEvent e){
System.exit(0);
}
});
Center center = new Center();
frame.setSize(400, 300);
frame.setTitle("PJP - Penzes Java Programming");
center.setCenter(frame);
frame.setLayout(null);
frame.setVisible(true);
}
}
Center.java
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import javax.swing.JFrame;
public class Center {
void setCenter(JFrame frame) {
Point center =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
int x = (int) center.getX() -
(frame.getWidth() / 2);
int y = (int) center.getY() -
(frame.getHeight() / 2);
Point ablakCenter = new Point(x, y);
frame.setLocation(ablakCenter);
}
}
Végeredmény (a monitor közepén / felbontástól függetlenül/):
-
exit gomb működik (jobb felső sarok)
-
a középen lévő Exit feliratú gombra való kattintással a program kilép