ActionListener nie reaguje na RadioButtony

0

Witam na forum

Jestem w trakcie nauki GUI i mam taki problem z ActionListenerem.Tworze prosty program ktory konwertuje wpisane mile na kilometry.Tak jak mówiłem jestem trakcie nauki i po prostu staram sie dodawac do programu jakies pojedyncze elementy. Na początku stanąłem na tym:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class milenakm  implements ActionListener {
	JLabel mile, km;
	JTextField tmile, tkm;
	 public JButton konwert;
	public double tempmile, tempkm;

	public milenakm() {
JFrame rama = new JFrame();
		rama.setSize(500, 350);
	
		rama.setLayout(null);
		rama.setTitle("Mile na kilosy");
		rama.setVisible(true);
		rama.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JLabel mile = new JLabel("mile");
		JLabel km = new JLabel("km");
		mile.setBounds(30, 20, 50, 20);
		rama.add(mile);
		km.setBounds(30, 80, 50, 20);
		rama.add(km);
		JTextField tmile = new JTextField();
		JTextField tkm = new JTextField();
		tmile.setBounds(90, 20, 50, 20);
		tkm.setBounds(90, 80, 50, 20);
		rama.add(tmile);
		rama.add(tkm);

		JButton konwert = new JButton("Konwertuj");
		konwert.setBounds(70, 120, 90, 18);
		rama.add(konwert);
		konwert.addActionListener(this);

	}

	@Override
	public void actionPerformed(ActionEvent e) {

		tempmile = Double.parseDouble(tmile.getText());
		tempkm = tempmile * 1.61;
		tkm.setText(String.valueOf(tempkm));

	}

	public static void main(String[] args) {
		milenakm apka = new milenakm();
	
	}

}

Przy probie nacisniecia przycisku Konwertuj wyskakuje mi blad na konsoli(cytuje tylko dwie pierwsze linijki)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at GUI_Lesson5.milenakm.actionPerformed(milenakm.java:45)

Ominąłem ten błąd to tworząc JFrame za pomocą metody a nie konstruktora,i tutaj pytanie czy stanowi to jakąś różnicę?
W kodzie chyba nic nie zmieniłem poza tym sposobem utworzenia JFrame,ale zupełnie nie wiem co tak naprawdę zmieniło że zaczęło działać(ta wersja jest poniżej)
Dodajac nowe elementy znowu stanąłem przy dodawaniu RadioButtonów

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

public class MileNaKm_v_3 implements ActionListener {
	private JFrame rama;
	private JLabel mile, km;
	private JTextField tmile, tkm;
	private JButton konwert;
	private JCheckBox boxik;
	private ButtonGroup bf;
	private JRadioButton rbSmall, rbMiddle, rbLarge;
	double tempMiles, tempKm;

	public void robota() {
		JFrame rama = new JFrame();
		rama.setSize(600, 400);
		rama.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		rama.setVisible(true);
		rama.setTitle("Konwerter mil na Km");
		rama.setLayout(null);

		mile = new JLabel("MILE");
		mile.setBounds(50, 50, 50, 20);
		rama.add(mile);

		km = new JLabel("Km");
		km.setBounds(50, 100, 50, 20);
		rama.add(km);

		tmile = new JTextField();
		tmile.setBounds(120, 50, 50, 20);
		rama.add(tmile);
		tmile.addActionListener(this);

		tkm = new JTextField();
		tkm.setBounds(120, 100, 50, 20);
		rama.add(tkm);

		konwert = new JButton("Konwertuj");
		konwert.setBounds(80, 140, 150, 25);
		rama.add(konwert);
		konwert.addActionListener(this);

		boxik = new JCheckBox("zaznacz");
		boxik.setBounds(240, 140, 110, 23);
		rama.add(boxik);
		boxik.addActionListener(this);
		
		ButtonGroup bf = new ButtonGroup();
		JRadioButton rbSmall = new JRadioButton("Small",true);
		rbSmall.setBounds(100, 190, 70, 30);
		rama.add(rbSmall);
		bf.add(rbSmall);
		rbSmall.addActionListener(this);
		
		JRadioButton rbMiddle = new JRadioButton("Medium",false);
		rbMiddle.setBounds(170, 190, 70, 30);
		rama.add(rbMiddle);
		bf.add(rbMiddle);
		rbMiddle.addActionListener(this);
		
		JRadioButton rbLarge = new JRadioButton("Large",false);
		rbLarge.setBounds(240, 190, 70, 30);
		rama.add(rbLarge);
		bf.add(rbLarge);
		rbLarge.addActionListener(this);
	}

	public static void main(String[] args) {
		MileNaKm_v_3 obiekt = new MileNaKm_v_3();
		obiekt.robota();

	}

	@Override
	public void actionPerformed(ActionEvent cos) {
		Object source = cos.getSource();
		if (source == konwert ) {
			tempMiles = Double.parseDouble(tmile.getText());
			tempKm = tempMiles * 1.61;
			tkm.setText(String.valueOf(tempKm));
		} 
		else if (source == rbSmall){
		
			tmile.setFont(new Font("Arial", Font.ITALIC, 35));
		}
		else if (source == rbMiddle){
		
			tkm.setFont(new Font ("Arial",Font.BOLD, 42));
		}
		else if (source == rbLarge){
		
			tkm.setFont(new Font ("Arial",Font.BOLD, 44));
		}
		else if (source == boxik) {
			if (boxik.isSelected() == true) {
				tmile.setFont(new Font("Arial", Font.ITALIC, 35));
			} else {
				tmile.setFont(new Font("TimesNewRoman", Font.BOLD, 17));
			}

		}

	}

}

No i tutaj konwertowanie mi działa,z CheckBoxem wszystko OK. Natomiast zaznaczanie RadioButtonów kompletnie nic nie zmienia.W którym miejscu sie wywalam?
Z góry dzięki za pomoc
pozdrawiam

0

Przed przystąpieniem do pisania czegoś okienkowego polecałbym najpierw solidnie przerobić jakiś kurs z podstaw Java - dzięki temu na przykłd zrozumiesz różnicę pomiędzy polem klasy a zmienną lokalną. Błąd w obydwu przypadkach dotyczy tego samego (dodałem komentarze w kodzie):

public class milenakm  implements ActionListener {
    JLabel mile, km;
    JTextField tmile, tkm; /* tutaj jest pole klasy o nazwie tkm*/
     public JButton konwert;
    public double tempmile, tempkm; 
 
    public milenakm() {
        JFrame rama = new JFrame();
        rama.setSize(500, 350);
 
        rama.setLayout(null);
        rama.setTitle("Mile na kilosy");
        rama.setVisible(true);
        rama.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        JLabel mile = new JLabel("mile");
        JLabel km = new JLabel("km");
        mile.setBounds(30, 20, 50, 20);
        rama.add(mile);
        km.setBounds(30, 80, 50, 20);
        rama.add(km);
        JTextField tmile = new JTextField();
        JTextField tkm = new JTextField(); /* a tutaj zmienna lokalna o nazwie tkm - przysłania nazwę pola klasy*/
        tmile.setBounds(90, 20, 50, 20);
        tkm.setBounds(90, 80, 50, 20);
        rama.add(tmile);
        rama.add(tkm);
 
        JButton konwert = new JButton("Konwertuj");
        konwert.setBounds(70, 120, 90, 18);
        rama.add(konwert);
        konwert.addActionListener(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        tempmile = Double.parseDouble(tmile.getText());
        tempkm = tempmile * 1.61;
        tkm.setText(String.valueOf(tempkm)); 
    } 
    public static void main(String[] args) {
        milenakm apka = new milenakm();
 
    }
}

w efekcie pola w twojej klasie są niezainicjalizowane i dostajesz NPE.

0

Podstawy przerobiłem ale jak widać nie wystarczająco solidnie.Z drugiej strony dzięki temu praktycznemu przykładowi zrozumiałem na czym polega różnica.
Dzięki wielkie w każdym razie.
pozdrawiam

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