Nie wiem czy mam tworzyć nowy wątek, ale uznałem, że skoro wciąż to się tyczy jednego tematu, tj. właściwego użycia ActionListenera, to zapytam tutaj. Chodzi o sytuację, kiedy jeden przycisk "wykonaj" robi różne rzeczy, zależnie od tego jaki radioButton jest zaznaczony: https://zapodaj.net/67a4a649fb271.png.html
Klasa, z której odpala się program wygląda tak:
import java.io.File;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public final class VigenereGUI extends JFrame {
private final JTextArea JTextInput, decryptedTxt,enterTheNumField ;
private final JLabel jSource, jOperation, jCypher, lEnterTheNum;
private final JButton jGetFile, jExecute, jDirectDict;
private final JRadioButton jrCipher, jrBreak, jrCeasar, jrVigenere;
private final ButtonGroup jrChooseOperation, jrChooseCipher;
private File[] dictionaries;
public VigenereGUI()
{
setTitle("kodowanie i łamanie szyfrów");
setSize(800,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
jSource = new JLabel("Źródło:");
jSource.setBounds(50,10,70,20);
add(jSource);
jOperation = new JLabel("Operacja:");
jOperation.setBounds(200,10,70,20);
add(jOperation);
jCypher = new JLabel("Wybierz szyfr:");
jCypher.setBounds(420,10,120,20);
add(jCypher);
lEnterTheNum = new JLabel("Wprowadź wartość szyfru:");
lEnterTheNum.setBounds(200,65,190,20);
add(lEnterTheNum);
enterTheNumField = new JTextArea();
enterTheNumField.setBounds(400,65,100,20);
add(enterTheNumField);
jrCipher = new JRadioButton("Szyfruj", true);
jrCipher.setBounds(180,35,90,20);
add(jrCipher);
jrBreak = new JRadioButton("Rozszyfruj", false);
jrBreak.setBounds(270,35,120,20);
add(jrBreak);
jrChooseOperation = new ButtonGroup();
jrChooseOperation.add(jrCipher);
jrChooseOperation.add(jrBreak);
jrCeasar = new JRadioButton("Caesar", true);
jrCeasar.setBounds(400,35,80,20);
add(jrCeasar);
jrVigenere = new JRadioButton("Vigenere", false);
jrVigenere.setBounds(500,35,100,20);
add(jrVigenere);
jrChooseCipher = new ButtonGroup();
jrChooseCipher.add(jrCeasar);
jrChooseCipher.add(jrVigenere);
jGetFile = new JButton("tekst");
jGetFile.setBounds(50,35,100,20);
add(jGetFile);
jExecute = new JButton("Wykonaj");
jExecute.setBounds(530,360,100,20);
add(jExecute);
jDirectDict = new JButton("słowniki");
jDirectDict.setBounds(50,60,100,20);
add(jDirectDict);
JTextInput = new JTextArea();
JScrollPane scrollPane = new JScrollPane(JTextInput);
scrollPane.setBounds(50,100,600,250);
add(scrollPane);
decryptedTxt = new JTextArea();
JScrollPane spDecrypted = new JScrollPane(decryptedTxt);
spDecrypted.setBounds(50,400,600,250);
add(spDecrypted);
Listener_GetFile gfl = new Listener_GetFile(jGetFile,JTextInput);
jGetFile.addActionListener(gfl);
Listener_GetDictionary gdl = new Listener_GetDictionary(dictionaries);
jDirectDict.addActionListener(gdl);
Listener_CeasarCipher ccl = new Listener_CeasarCipher(JTextInput, decryptedTxt, enterTheNumField, jrCipher, jrCeasar);
jExecute.addActionListener(ccl);
Listener_CeasarCracker crl = new Listener_CeasarCracker(JTextInput, decryptedTxt, jrCipher, jrCeasar);
jExecute.addActionListener(crl);
Listener_VigenereCipher vcl = new Listener_VigenereCipher(JTextInput, decryptedTxt, enterTheNumField, jrCipher, jrCeasar);
jExecute.addActionListener(vcl);
Listener_VigenereBreaker vbl = new Listener_VigenereBreaker(JTextInput, decryptedTxt, enterTheNumField, jrCipher, jrCeasar);
jExecute.addActionListener(vbl);
}
public static void main(String[]args)
{
VigenereGUI appMenu = new VigenereGUI();
appMenu.setVisible(true);
}
Do tego mam jedną klasę abstrakcyjną, która przechowuje zmienne, potem wywoływane przez poszczególne klasy z ActionListenerami:
package Tries4;
import java.io.File;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
public abstract class Listeners {
public JTextArea getJTextInput() {
return JTextInput;
}
public void setJTextInput(JTextArea jTextInput) {
JTextInput = jTextInput;
}
public JTextArea getDecryptedTxt() {
return decryptedTxt;
}
public void setDecryptedTxt(JTextArea decryptedTxt) {
this.decryptedTxt = decryptedTxt;
}
public JTextArea getEnterTheNumField() {
return enterTheNumField;
}
public void setEnterTheNumField(JTextArea enterTheNumField) {
this.enterTheNumField = enterTheNumField;
}
public JLabel getjSource() {
return jSource;
}
public void setjSource(JLabel jSource) {
this.jSource = jSource;
}
public JLabel getjOperation() {
return jOperation;
}
public void setjOperation(JLabel jOperation) {
this.jOperation = jOperation;
}
public JLabel getjCypher() {
return jCypher;
}
public void setjCypher(JLabel jCypher) {
this.jCypher = jCypher;
}
public JLabel getlEnterTheNum() {
return lEnterTheNum;
}
public void setlEnterTheNum(JLabel lEnterTheNum) {
this.lEnterTheNum = lEnterTheNum;
}
public JButton getjGetFile() {
return jGetFile;
}
public void setjGetFile(JButton jGetFile) {
this.jGetFile = jGetFile;
}
public JButton getjExecute() {
return jExecute;
}
public void setjExecute(JButton jExecute) {
this.jExecute = jExecute;
}
public JButton getjDirectDict() {
return jDirectDict;
}
public void setjDirectDict(JButton jDirectDict) {
this.jDirectDict = jDirectDict;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public String getDictPath() {
return dictPath;
}
public void setDictPath(String dictPath) {
this.dictPath = dictPath;
}
public File[] getDictionaries() {
return dictionaries;
}
public void setDictionaries(File[] dictionaries) {
this.dictionaries = dictionaries;
}
public JRadioButton getJrCipher() {
return jrCipher;
}
public void setJrCipher(JRadioButton jrCipher) {
this.jrCipher = jrCipher;
}
public JRadioButton getJrBreak() {
return jrBreak;
}
public void setJrBreak(JRadioButton jrBreak) {
this.jrBreak = jrBreak;
}
public JRadioButton getJrCeasar() {
return jrCeasar;
}
public void setJrCeasar(JRadioButton jrCeasar) {
this.jrCeasar = jrCeasar;
}
public JRadioButton getJrVigenere() {
return jrVigenere;
}
public void setJrVigenere(JRadioButton jrVigenere) {
this.jrVigenere = jrVigenere;
}
public ButtonGroup getJrChooseOperation() {
return jrChooseOperation;
}
public void setJrChooseOperation(ButtonGroup jrChooseOperation) {
this.jrChooseOperation = jrChooseOperation;
}
public ButtonGroup getJrChooseCipher() {
return jrChooseCipher;
}
public void setJrChooseCipher(ButtonGroup jrChooseCipher) {
this.jrChooseCipher = jrChooseCipher;
}
public boolean isdAreDownloaded() {
return dAreDownloaded;
}
public void setdAreDownloaded(boolean dAreDownloaded) {
this.dAreDownloaded = dAreDownloaded;
}
private JTextArea JTextInput, decryptedTxt,enterTheNumField ;
private JLabel jSource, jOperation, jCypher, lEnterTheNum;
private JButton jGetFile, jExecute, jDirectDict;
private String s, dictPath;
private File[] dictionaries;
private JRadioButton jrCipher, jrBreak, jrCeasar, jrVigenere;
private ButtonGroup jrChooseOperation, jrChooseCipher;
private boolean dAreDownloaded;
}
No i tutaj jedna z tych klas, która obsługuje button odpowiedzialny za pobranie pliku z tekstem i wklejenie go do ramki:
package Tries4;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JTextArea;
public class Listener_GetFile extends Listeners implements ActionListener {
public Listener_GetFile(JButton jGetFile, JTextArea JTextInput)
{
setjGetFile(jGetFile);
setJTextInput(JTextInput);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JFileChooser jGet = new JFileChooser();
if(jGet.showOpenDialog(null)==JFileChooser.APPROVE_OPTION)
{
File file = jGet.getSelectedFile();
try {
getJTextInput().setText(null);
Scanner scanner = new Scanner(file);
while(scanner.hasNext())
{
getJTextInput().append(scanner.nextLine()+"\n");
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
No i po pierwsze chciałbym zapytać czy to dobrze, że dla jednego przycisku "wykonaj" mam cztery ActionListenery, które są uruchamiane w zależności od tego, który RadioButton jest zaznaczony. Po drugie, nie wiem czy dobrze robię konstruktory do tych listenerów, tzn. czy nie zawierają aby zbyt dużo parametrów i czy tych zmiennych nie dałoby rady jakoś inaczej przekazać. No i co do samego użycia zmiennych przeze mnie mam najwięcej wątpliwości, ale nie wiem za bardzo jak to rozwiązać. No bo tak: wszystkie elementy graficzne okna chyba muszą być zadeklarowane w klasie z której moje okno się uruchamia. Powinny być ustawione jako private. W ActionListenerze nie wywołam ich za pomocą np: getDecryptedTxt
, bo musiałbym do tego stworzyć obiekt klasy main w klasie, która odpowiada za ActionListenera, a wtedy wywala mi jakiś bład "stackOverFlow". W każdej klasie, która implementuje ActionListenera powtarzać deklaracje zmiennych, wydawało mi się produkowaniem nadmiernego kodu. Uznałem więc, że może stworzę jedną klasę Listeners, po której konkretne Listenery będą dziedziczyć zmienne, ale znowu żebym miał do nich swobodny dostęp, to powinienem oznaczyć je jako protected, czego z jakiegoś powodu nie powinno się podobno robić a tak jak teraz to robię getDecryptedTxt().append(output)
podejrzewam, że też nie jest wskazane, a przynajmniej brzydko wygląda. Jakby ktoś miał chwilę, żeby mi pomóc, to byłby wdzięczny. Przy okazji czy ktoś ma w swoich zbiorach, albo zna linki do podobnych programów w Javie, zawierających też kilka klas, korzystających z JFrame'a i wykorzystujących final static dziedziczenie interfejsy, settery i gettery itd., tylko że wzorowo wykonanych? Myślę, że dla mnie i nie tylko dla mnie byłoby to bardzo pomocne.