ActionListener i podział na klasy - prośba o sprawdzenie kodu

0

Witam. Ostatnio przy okazji innego wątku, kolega Szalom zwrócił mi uwagę, że nie powinno się używać
addActionListener(this) i nie powinno się potem w metodzie przywoływać tego w taki sposób:

Object o = new Object();
if(o.getSource()==nazwaButtonaAlboCzegoś){}
else if(o.getSource()==nazwaInnegoButtona){}

Itd.
Chciałem zapytać czy to jak tutaj podzieliłem program na dwie klasy jest poprawne i ma sens:

public class CelsiusToFahrenheit extends JFrame  {
	private JLabel lCelsius, lFahrenheit;
	private JButton bConvert;
	private JTextField tCelsius, tFahrenheit;


	public CelsiusToFahrenheit() 
	{
		setSize(400,200);
		setTitle("Przeliczanie stopni Celsiusza na Fahrenheita");
		setLayout(null);
		
		lCelsius = new JLabel("Stopnie Celsiusza: ");
		lCelsius.setBounds(10, 20, 150, 20);
		add(lCelsius);
		
		lFahrenheit = new JLabel("Stopnie Fahrenheita: ");
		lFahrenheit.setBounds(10, 70, 150, 20);
		add(lFahrenheit);
		
		tCelsius = new JTextField("");
		tCelsius.setBounds(170, 20, 150,20);
		add(tCelsius);
		
		tFahrenheit = new JTextField("");
		tFahrenheit.setBounds(170,70,150,20);
		add(tFahrenheit);
		
		bConvert = new JButton("Konwertuj");
		bConvert.setBounds(100,120,150,20);
		add(bConvert);

		ConvertListener kListener = new ConvertListener(tCelsius,tFahrenheit);
		bConvert.addActionListener(kListener);
	}

	public static void main(String[]args) 
	{
		CelsiusToFahrenheit ceToFahr = new CelsiusToFahrenheit();
		ceToFahr.setVisible(true);
		ceToFahr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

i:

public class ConvertListener implements ActionListener{

	private double tempCelsius, tempFahrenheit;
	private JTextField celArea;
	private JTextField fahrArea;
	
	
	public ConvertListener(JTextField celArea, JTextField fahrArea) 
	{
		this.celArea = celArea;
		this.fahrArea = fahrArea;
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
				tempCelsius = Double.parseDouble(celArea.getText());
				tempFahrenheit = 32+(tempCelsius*9/5);
				fahrArea.setText(String.valueOf(tempFahrenheit));				
	}

}

0

Teraz lepiej. Zalecam też robić pola private final gdzie się tylko da, dla czytelności.

0

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: titlehttps://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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1