To ja spróbuję najprościej jak się da (co nie znaczy najkrócej).
Za pomocą jButton1.addActionListener(odeslij_mnie); zarejestrowałeś dla jButton1 obsługę zdarzenia wciśnięcia przycisku.
Jego odpalenie (tego zdarzenia) spowoduje wywołanie przez jakiś obiekt Swinga (nie jest to ważne tutaj) metody: odeslij_mnie.actionPerformed().
odeslij_mnie musi mieć taką metodę ponieważ implementuje interfejs ActionListener, a ten właśnie taką metodę posiada (i to jest jedyna jego metoda). Zresztą nie może nie posiadać ponieważ addActionListener przyjmie jako argument wyłącznie referencję typu ActionListener (inaczej będzie błąd kompilacji).
Działa to dlatego, że każdą klasę, która implementuje jakiś interfejs można rzutować w górę na referencję do tego interfejsu. Traktuj interfejs jako klasę bazową z abstrakcyjnymi metodami do przeciążenia - łatwiej to rozumieć.
Co do przycisku i etykiety z Osobna_klasa, to Swing nie ma nawet o nich pojęcia, że istnieją. Dla Swinga i jego obsługi zdarzeń istnieją wyłącznie te rzeczy, które zostały zarejestrowane przez jakiś addXXXListener.
Jest jeszcze jeden myk z dostępem do źródła zdarzenia. Z wnętrza metody ActionListener można się dostać do referencji JButton1 bezpośrednio przez pole lub jakąś metodę NewJFrame, ale to bardzo zła i niebezpieczna technika powodująca masę błędów.
Znacznie lepszym sposobem jest użycie zmiennej zdarzenie typu ActionEvent, które jest argumentem ActionPerformed (i ogólniej do każdej metody obsługi zdarzeń dochodzi jako argument jakiś obiekt samego zdarzenia). W zmiennej tej zapisane są niemal wszystkie potrzebne informacje lub odnośniki do tych informacji - szczególnie takie jak dla jakiego obiektu zdarzenie zostało wygenerowane, jaki był jego czas, i co było jego przyczyną. Aby dostać się do jButton1 trzeba użyć (JButton)(zdarzenie.getSource()).
Oczywiście zawsze warto sprawdzić czy wynik getSource da się zrzutować ponieważ pamiętaj, że actionPerformed może być wywoływane nie tylko dla JButtona, a ta ten sam obiekt implementujący ActionListener (czyli tutaj odeslij_mnie) może być zarejestrowany (przez addActionListener) do uruchomienia dla wielu różnych przycisków (więcej niż jednego). Po udanym zrzutowaniu dostajesz referencję do konkretnego przycisku JButton, który został przyciśnięty. Z ActionEvent nie dowiesz się nic więcej niż tylko o tym przycisku. Natomiast z obiektu przycisku możesz dowiedzieć się coś o jego rodzicu za pomocą metody JButton.getParent(). Dostaniesz z niej referencję do obiektu NewJFrame, który zawiera naciśnięty przycisk - ALE - wynikiem jest referencja do klasy Container, z której NewJFrame po łańcuszku rodziców Windows, Frame i JFrame dziedziczy. Dlatego trzeba tę referencję znowu przekonwertować na referencję do klasy NewJFrame upewniając się, że to możliwe. Dopiero wtedy jest możliwe dostanie się do pola jLabel1 w obiekcie tej klasy. W (działającym) uproszczeniu może wyglądać to tak:
JButton źródło = (JButton)(zdarzenie.getSource());
NewJFrame ramka = (NewJFrame)(źródło.getParent());
ramka.jLabel1.setIcon(jakiśObrazek);
ramka.jLabel1.setText("Wciśnięto przycisk");
Można również inaczej. Trzeba w Osobna_klasa stworzyć pole typu JLabel i za pomocą np. konstruktora wypełnić je referencją pobraną z NewJFrame.jLabel1 tego obiektu, który naprawdę zawiera przycisk, który Ciebie interesuje.
Pamiętaj, że aplikacja zawsze może stworzyć nieskończoną ilość obiektów NewJFrame z identycznie wyglądającymi obiektami, których referencje będą przechowywać ich własne pola jButton1. Tyle, że każdy z nich będzie innym egzemplarzem. W razie wyświetlania wszystkich tych okienek, Twój program musi wiedzieć o którego buttona w którym okienku chodzi. Pamiętaj, że w takim wypadku wszystkie obiekty NewJFrame zarejestrują obsługę przyciśnięcia swoich przycisków jButton1 przez różne obiekty, których referencję posiadać będzie lokalna zmienna odeslij_mnie (każdy nowy egzemplarz Osobna_klasa() jest tworzony w initComponents()). Założenie, że jest tylko jedno okienko dziedziczące po JFrame, to tylko przypadek szczególny. Jednak obsługa zdarzeń musi sobie poradzić ze wszystkimi możliwymi przypadkami.
Wracając do tego innego sposobu - jest on dużo mniej bezpieczny ponieważ musisz wiedzieć na pewno (a łatwo się pomylić), który obiekt jest źródłem i który egzemplarz obiektu będzie jego odbiornikiem. Można w tym celu porównywać referencję pobraną jButton1 z referencją (JButton)(zdarzenie.getSource()). Jeżeli będą równe (==), to pomyłki nie ma.
Z powodów, które napisałem najbezpieczniejszą obsługą zdarzeń jest przekazywanie do addXXXListener klasy wewnętrznej tego obiektu, który posiada obiekt wywołujący zdarzenie. Wtedy jest pewność, że zdarzenie jest obsługiwane przez właściwy odbiornik dla właściwego źródła.
Obsługa zdarzeń obiektów jednej klasy przez metody zupełnie innej klasy (szczególnie publicznej), to proszenie się o naprawdę duże kłopoty. Trzeba mieć naprawdę bardzo mocne powody (ja takich nigdy nie miałem), żeby w taki sposób zakodować obsługę zdarzeń.
Tutaj wersja z odbiornikiem zdzarzeń, który jest klasą wewnętrzną. Można to jeszcze uprościć przez zamianę jawnej klasy wewnętrznej na klasę anonimową, ale to może przy innej okazji.
import javax.swing.*;
public class NewJFrame extends JFrame {
public NewJFrame() {
initComponents();
}
private void initComponents() {
jButton1 = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Wewnetrzna_klasa odeslij_mnie = new Wewnetrzna_klasa();
jButton1.addActionListener(odeslij_mnie);
jButton1.setText("Napis");
jLabel1.setBackground(new java.awt.Color(0, 0, 0));
}
private class Wewnetrzna_klasa implements ActionListener {
public void actionPerformed(ActionEvent zdarzenie)
{ //można wykorzystać jLabel1 i jButton1 bezpośrednio bez używania obiektu zdarzenie
//można użyć dostępu jawnego NewJFrame.this. lub niejawnego jak poniżej
jLabel1.setIcon(jakiśObrazek);
jLabel1.setText("Wciśnięto przycisk");
}
}
private JLabel jLabel1; //prywatne, zawsze możesz zrobić metodę
private JButton jButton1; //public getMójLabel() { return jLabel1; }
}
I jeszcze jedno. 99% pól wszelkich obiektów powinno być typu private. Użycie pola z modyfikatorem public to na 99% bardzo poważny błąd, który srogo się kiedyś zemści. Nie rób tak.
Przy okazji używaj konsekwentnie formatowania kodu ponieważ jeżeli tego nie zrobisz, to cały czas będziesz mieć wielkie problemy z brakującymi lub nadmiarowymi nawiasami klamrowymi (i nie tylko). Takie błędy czasem piekielnie trudno wykryć, szczególnie jak się pechowi pomaga.
Się rozpisałem... :d