Witam. Mam pewien problem. Otóż stworzyłem sobie komponent na panelu na którym jest guzik. Po jego naciśnięciu pokazuje się nowe okno z guzikami i po naciśnięciu któregoś guzika ustawia się pewna zmienna (powiedzmy z) w komponencie i okno się zamyka. I w tym momencie pojawia się problem, ponieważ po dodaniu tego komponentu do głównego programu mam problem z tym, żeby w momencie naciśnięcia przycisku na oknie komponentu przechwycić tą zmienną z. Ma ktoś może pomysł jak to zrobić??
Możesz np stworzyć nowy konstruktor w tym komponencie, w którym przekazujesz obiekt, który będzie przechowywał obliczoną/ przechwyconą wartość.
a mógłbyś pokazać jakiś przykładowy kod bo nie bardzo jestem w stanie sobie to wyobrazić
Tworzysz klasę ModelZeZmienną która trzyma zmienną. Potem poprzez własnoręcznie napisane konstuktory (tzn musisz napisać własne klasy rozszerzające komponenty Swingowe) wpychasz model do komponentów, tak żeby wszykie komponenty w hierarchii miały referencję do tego samego modelu. To jest rozwiązanie preferowane wg mnie, bo najbardziej elastyczne/ testowalne/ rozszerzalne/ etc
Inne rozwiązanie to rozszerzanie samego parenta i wywoływanie w pęli getParent() aż instanceof powie nam że natrafiliśmy na naszą klaskę. Wtedy wystarczy zrzutować i wywołać odpowiednią własnoręcznie napisaną metodę zwracającą model ze zmienną.
Jeszcze inny sposób to zrobienie z modelu singletonu (obojętne jak). Singleton to jest jednak antywzorzec bo wprowadza globalny stan, nie da się stworzyć dwóch singletonów tej samej klasy.
Narysuj hierarchię komponentów w Paincie / załącz zrzut z programu jak to ma wyglądać i co gdzie ma lecieć.
Ok to sprawa wygląda tak, że po naciśnięciu guzika oknie utworzonym przez komponent to wywoływana jest metoda setId_rodzaju(), która ustawia zmienna id_rodzaju_zdarzenia w komponencie i teraz pojawia się problem jak przechwycić w tym samym momencie wartość tej zmiennej do głównego programu.
Nie wiem, czy dobrze zrozumialem, ale jesli tak, to wedlug mnie mozesz po prostu tak stworzyc klase drugiego okna, by przy jego tworzeniu przekazywac referencje do pierwszego okna. W ten sposob mozesz wykonac dowolna (publiczna) metode i przekazywac dane.
Przyklad kodu:
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Przyklad
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
@Override public void run()
{
Okno1 okno = new Okno1();
okno.setVisible(true);
}
});
}
}
class Okno1
extends JFrame
{
private JTextField poleTekstowe = new JTextField(10);
private JButton buttonOkno2 = new JButton("Okno 2");
private Okno2 okno = new Okno2(this);
public Okno1()
{
setSize(400, 300);
setTitle("Okno 1");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
buttonOkno2.addActionListener(new ActionListener()
{
@Override public void actionPerformed(ActionEvent e)
{
okno.setVisible(true);
}
});
add(poleTekstowe);
add(buttonOkno2);
}
public void ustawTekst(String text)
{
poleTekstowe.setText(text);
}
}
class Okno2
extends JFrame
{
private Okno1 parent;
private JTextField poleTekstowe = new JTextField(10);
private JButton buttonClose = new JButton("Zamknij");
public Okno2(Okno1 oknoGlowne)
{
parent = oknoGlowne;
setSize(400, 300);
setTitle("Okno 2");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
buttonClose.addActionListener(new ActionListener()
{
@Override public void actionPerformed(ActionEvent e)
{
parent.ustawTekst(poleTekstowe.getText());
dispose();
}
});
add(poleTekstowe);
add(buttonClose);
}
}
Okno1, to glowne okno programu wyswietlajace sie po uruchomieniu. Jesli wcisniesz przycisk, pojawi sie okno2, ktore w konstruktorze otrzymalo referencje do okno1. Wprowadzenie dowolnego tekstu w drugim oknie i wcisniecie buttona zamykajacego wywoluje action listener przypisany do tego buttona, w ktorym jest wywolywana metoda ustawiajaca zawartosc pola tekstowego w pierwszym, glownym oknie.
Wszystko ładnie pięknie tyle tylko, że ja mam komponent stworzony na panelu jako osobny projekt i na tym panelu jest guzik po naciśnięciu którego jest wywoływane okno z guzikami i to jak ustawić zmienna tylko w komponencie to wiem, natomiast jak potem zczytać wartość tej zmiennej do głównego okna programu??
No to już pisałem. Robisz model dla zmiennej i podajesz do obydwu komponentów.
class Model {
typ zmienna;
}
class Komponent1 extends Komponent {
Model model;
Komponent1(Model model) {
this.model = model;
}
}
class Komponent2 extends Komponent {
Model model;
Komponent2(Model model) {
this.model = model;
}
}
Teraz wepchnij poprzez konstruktory ten sam model do obu komponentów i zmiana zmiennej w jednym komponencie automatycznie będzie widoczna w drugim komponencie.