Gyakorlati alapok IV.

Végre ablakozunk! (AWT, Swing, JavaFX)

 

Tanulói jelenlétek összeszámlálása (Button + Textfield + filekezelés)

 

Ebben a fejezetben a textfield-objektum (A textfield alaptulajdonságai) szokásos felhasználását célozzuk meg, de a funkciókat külső file-műveletekkel is kiegészítjük.

Adott egy naplo.txt nevű állomány…
 


...amely tanulók félévi jelenléti-hiányzási adatait tartalmazza. A tanuló neve mellett lévő, szisztematikusan elhelyezett szimbólumok a következő státuszokat jelentik:

Például:

A feladat 1. körben, hogy az állományból szűrjűk le a keresett tanuló teljes jelenléti státuszát. Ugyanakkor alapszinten az adatbevitelt validálnunk is kell, illetve emlékezzünk a Filekezelés című fejezetcsomagban tanultakra, amely szerint a filekezelés -lévén külső, “veszélyes” művelet-, kötelező kivételkezeléssel is párosul.

A kötelezőségeken felül a feladatot meg lehet oldani egyszerűen és bonyolultan is. Az utóbbi az objektumorientált alapelvek nagyon következetes és szigorú követését jelenti, például ha minden magasabb szintű funkció külön osztályba kerül. A megoldás 1. részében ettől most el fogunk tekinteni és marad az egyszerűbb megoldás, amely során szinte minden funkciót a buttonAction() függvényben dolgozunk ki.

Először nézzük meg az alapszintű validálási szabányokat!


Amint az már említésre került, az állomány megnyitását kötelező kivételkezeléssel kell bebiztosítanunk (try-catch). Ezt könnyű megtennünk a catch() blokkokba tett üzenetablakok segítségével. Az üzenetek -az elkapott kivételek, hibák jellegéből következtetve-, lehetnek különbözők is:


} catch (FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(frame, "A fájl nem található!");

} catch (IOException ioe) {
JOptionPane.showMessageDialog(frame, "Fájlkezelési vagy egyéb hiba!");


Mindenképpen le kell védenünk a bemeneti szövegmezőket. Alapszinten azt akadályozzuk meg, hogy a felhasználó kitöltetlenül hagyja azokat, bár ha rosszul gépeli be a file elérési útját, úgyis kap egy A fájl nem található! feliratú üzenetablakot:

if(textPath.getText().equals("")) {
    JOptionPane.showMessageDialog(frame, "Üres fájl elérési út!");
    return;
}

if(textSearch.getText().equals("")) {
    JOptionPane.showMessageDialog(frame, "Üres keresési mező!");
    return;
}


Nagyjából ugyanez érvényes a névkeresési szövegmezőre, kivéve:

Ezen 2 probléma lekezelése a projekt 1. körös megalkotása szempontjából nem volt lényeges, ráadásként pedig bonyolítani is kellett volna hozzá a kódot:

A file beolvasásakor egy hátulról induló for ciklus Integer típusú számlálókba osztályozza a jelenléti adatokat:

while(line != null) {
    if(line.contains(textSearch.getText())) {
        System.out.println(line); //kiírás konzolra tesztelésre
        for(int i = line.length()-1; i >= 11; i--) {
            char character = line.charAt(i);
            switch (character) {
                case ('O'): count_O++; break;
                case ('X'): count_X++; break;
                case ('I'): count_I++; break;
                case ('N'): count_N++; break;
        }
    }
}


Ezután a számlálók tartalmai konvertálásra kerülnek String adattípusba a végső megjelenítéshez. Ennek objektuma a már jól ismert üzenetablak, amelynek tartalmát megjelenítés előtt szépen megformázhatjuk:

String stringCount_O = Integer.toString(count_O);
String stringCount_X = Integer.toString(count_X);
String stringCount_I = Integer.toString(count_I);
String stringCount_N = Integer.toString(count_N);

String stringResult = textSearch.getText()
+ " jelen volt " + stringCount_O + " órán,\n"
+ "igazoltan hiányzott " + stringCount_X + " órán,\n"
+ "igazolatlanul hiányzott " + stringCount_I + " órán,\n"
+ "nem volt jelen " + stringCount_N + " órán.";

JOptionPane.showMessageDialog(frame, stringResult);


Mindezután kicsit inicializálunk, alaphelyzetbe állítunk, hiszen lehet, hogy a felhasználó az applikációban nemcsak egyszer kíván keresni...

textPath.setText("");
textSearch.setText("");
count_O = 0;
count_X = 0;
count_I = 0;
count_N = 0;
System.out.println();
return;


...majd már csak kivételkezelés és végső lezárások következnek:

} catch (FileNotFoundException fnfe) {
    JOptionPane.showMessageDialog(frame, "A fájl nem található!");
    textPath.setText("");
    textSearch.setText("");
    return;
} catch (IOException ioe) {
    JOptionPane.showMessageDialog(frame, "Fájlkezelési vagy egyéb hiba!");
    ioe.printStackTrace();
} finally {
    try {
        if (reader != null) {
        reader.close();
    }
    } catch (IOException ioe) {
        JOptionPane.showMessageDialog(frame, "Fájlkezelési vagy egyéb hiba!");
        ioe.printStackTrace();
            }
        }
    }
}

 

Nézzük meg a futtatható Java-kódot:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

Main.java


public class Main {

public static void main(String[] args) {
    Window window = new Window();
    }
}

 

Window.java

 

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

class Window extends JFrame {
    JFrame frame = new JFrame();
    JButton button = new JButton("Keress!");
    JLabel labelPath = new JLabel();
    JLabel labelSearch = new JLabel();
    JTextField textPath = new JTextField();
    JTextField textSearch = new JTextField();

Window() {
    super();
    labelPath.setBounds(100, 50, 200, 25);
    labelPath.setFont(new Font("Serif", Font.PLAIN, 12));
    labelPath.setText("Elérési út + fájlnév (pl. C:\\\\naplo.txt)");

    textPath.setBounds(100, 75, 200, 25);

    labelSearch.setBounds(100, 100, 200, 25);
    labelSearch.setFont(new Font("Serif", Font.PLAIN, 16));
    labelSearch.setText("Névkeresés");

    textSearch.setBounds(100, 125, 200, 25);

    button.setBounds(100, 175, 200, 30);
    button.addActionListener(event -> buttonAction());

    frame.add(button);
    frame.add(labelPath);
    frame.add(labelSearch);
    frame.add(textPath);
    frame.add(textSearch);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 325);
    frame.setTitle("PJP - Penzes Java Programming");

    Center center = new Center();
    center.setCenter(frame);

    frame.setLayout(null);
    frame.setVisible(true);
}

private void buttonAction() {
    if(textPath.getText().equals("")) {
        JOptionPane.showMessageDialog(frame, "Üres fájl elérési út!");
        return;
    }

    if(textSearch.getText().equals("")) {
        JOptionPane.showMessageDialog(frame, "Üres keresési mező!");
        return;
    }

//tesztelésre, a beviteli mezők tartalmának kiírása konzolra
// System.out.println(textPath.getText());
// System.out.println(textSearch.getText());

/* 0 - jelen
* X - igazolt hiányzás
* I - igazolatlan hiányzás
* N - nem volt óra
* E:\\naplo.txt
* Papaja Inez
* Alma Hedvig
* Galagonya Alfonz
* E:\\naplo.txt
*/


    FileReader reader = null;
    try {
        reader = new FileReader(textPath.getText());
        BufferedReader bufferedReader = new BufferedReader(reader);
        String line = bufferedReader.readLine();
        int count_O = 0;
        int count_X = 0;
        int count_I = 0;
        int count_N = 0;

        while(line != null) {
            if(line.contains(textSearch.getText())) {
                System.out.println(line); //kiírás konzolra tesztelésre
                for(int i = line.length()-1; i >= 11; i--) {
                    char character = line.charAt(i);
                    switch (character) {
                        case ('O'): count_O++; break;
                        case ('X'): count_X++; break;
                        case ('I'): count_I++; break;
                        case ('N'): count_N++; break;
                    }
                }
            }
        line = bufferedReader.readLine();
    }

    String stringCount_O = Integer.toString(count_O);
    String stringCount_X = Integer.toString(count_X);
    String stringCount_I = Integer.toString(count_I);
    String stringCount_N = Integer.toString(count_N);

    String stringResult = textSearch.getText()
    + " jelen volt " + stringCount_O + " órán,\n"
    + "igazoltan hiányzott " + stringCount_X + " órán,\n"
    + "igazolatlanul hiányzott " + stringCount_I + " órán,\n"
    + "nem volt jelen " + stringCount_N + " órán.";

    JOptionPane.showMessageDialog(frame, stringResult);

    textPath.setText("");
    textSearch.setText("");
    count_O = 0;
    count_X = 0;
    count_I = 0;
    count_N = 0;
    System.out.println();
    return;

    } catch (FileNotFoundException fnfe) {
        JOptionPane.showMessageDialog(frame, "A fájl nem található!");
        textPath.setText("");
        textSearch.setText("");
        return;
    } catch (IOException ioe) {
        JOptionPane.showMessageDialog(frame, "Fájlkezelési vagy egyéb hiba!");
        ioe.printStackTrace();
    } finally {
        try {
            if (reader != null) {
                reader.close();
        }
    } catch (IOException ioe) {
        JOptionPane.showMessageDialog(frame, "Fájlkezelési vagy egyéb hiba!");
        ioe.printStackTrace();
            }
        }
    }
}
 

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/):

 

www.informatika-programozas.hu


A projektből következő további feladatok a következők lehetnek:

Ezek legyenek a Tisztelt Olvasó házi feladatai!