Osobne klasy działa ale nie...

0

Witam, jeszcze raz ...już mi brak pomysłów jak to rozwiązać. Chodzi o przekazanie zdjęcia do JLabel z innej klasy. Sytuacja wyglada tak jak w kodzie wszystko działa ale nie wyświetla mi tego zdjęcia, nie ma zadnych błędów :

public class A extends javax.swing.JFrame {
  
    public A() {
     
        initComponents();
    }
 
    public void initComponents() {
        jButton1 = new javax.swing.JButton();
        B odwolaj_sie = new B();
        jButton1.addActionListener(odwolaj_sie);
        jLabel1 = new javax.swing.JLabel();

    }
    public javax.swing.JLabel jLabel1;
    public javax.swing.JButton jButton1;
}


public class B implements ActionListener 
{
    
    public void actionPerformed(ActionEvent evt)

    {
    // tu wczytanie fotki 
        A przejdz = new A();
        przejdz.jLabel1.setIcon(image);
    }

    public ImageIcon image;
}

Próbowałem też odwrotnie:

public class A extends javax.swing.JFrame {
  
    public A() {
     
        initComponents();
    }
 
    public void initComponents() {
        jButton1 = new javax.swing.JButton();
        B odwolaj_sie = new B();
        jButton1.addActionListener(odwolaj_sie);
        jLabel1 = new javax.swing.JLabel();

    }
    public void wez_fote()
    {
    B przejdz = new B();
    jLabel1.setIcon(przejdz.image);
    }
    public javax.swing.JLabel jLabel1;
    public javax.swing.JButton jButton1;
}


public class B implements ActionListener 
{
    
    public void actionPerformed(ActionEvent evt)

    {
    // tu wczytanie fotki 
        
    }

    public ImageIcon image;
}

W obu przypadkach jest to samo kompiluje się ale nie wyświetla fotki, żeby chociaż jakieś błędy były a tu nic. Jeśli chodzi o to czy ten kod z klasy B sie wykonuje to wlepilem w klase B System.out.print("dziala button"); i po nacisnieciu przycisku ktory jest w klasie A wyświetliło mi się ten string.
W przypadku gdy kompilowalem jedna klase A z actionPerformed i wysyłaniem zdjęcia na JLabel
wszystko działa ładnie wyświetla się no ale chcę to zrobić w osobnych klasach. Proszę o pomoc.

0

O coś takiego Ci chodzi:

import javax.swing.*;
import java.awt.event.*;
import java.net.*;

public class B extends JFrame implements ActionListener{
	
	private JButton button = new JButton("Ustaw obrazek");
	private URL url;
	
	public B() {
		super("Ramka B");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		button.addActionListener(this);
		add(button);
		pack();
	
	}
		
	public void actionPerformed(ActionEvent e) {
		
		try {
			url = new URL("http://img73.imageshack.us/img73/7084/greateagle.jpg");
			} catch(Exception ex) {
				
			} finally {
				ImageIcon img = new ImageIcon(url);
				A a = new A(img);
			}
		
		
	}
	
	public static void main(String[] args) {
		B b = new B();
		b.setVisible(true);
	}
	
	
}

import javax.swing.*;


public class A extends JFrame  {
	
	private JLabel label = new JLabel();
	
	public A(ImageIcon img) {
		super("Ramka A");
	    label.setIcon(img);
	    add(label);
	    pack();
	    setVisible(true);
		
	}
	

}

Pozdrawiam

0

No i

                              ImageIcon img = new ImageIcon(url);
                                A a = new A(img);

powinno się znajdować w klauzuli try nie w finally, ale tak poza tym to działa

0

Dzieki Wielkie, a z tymi moimi wypocinami wiesz może co jest nie tak? Pytam z ciekawości, bo w zasadzie niby działa, nie wywala błędu a mimo to sie nie sprawdza także troche mnie to ciekawi.

0

Strzelam że masz za małą wielkość okna żeby cokolwiek zobaczyć.

0

Zdjęcia nie ma prawa wyświetlić ponieważ nie zrozumiałeś jednej rzeczy - obiekt, do którego referencję trzyma przejdź nie ma nic wspólnego z obiektem zawierającym przycisk, dla którego została wywołana addActionListener().

Obiekt, na rzecz, którego wywołujesz tę metodę został utworzony pewnie gdzieś w main() lub innym miejscu. Jak widzę uparcie tworzysz nowe obiekty, tu: A przejdz = new A(); i tu: B przejdz = new B();.
Przecież za każdym razem tworzysz zupełnie nowy obiekt! Ten obiekt w wypadku JFrame nie jest nawet wyświetlony (Swing, a tym bardziej Windows nie ma o nim najmniejszego pojęcia) bo do tego potrzeba wywołać metodę: przejdź.setVisible(true). A i tak jest to zupełnie inny obiekt, który do obsługi swojego przycisku tworzy inny obiekt, który ma to robić, ale zamiast tego tworzy kolejny obiekt B.
Ile razy naciśniesz przycisk, tyle razy utworzy się nowe nieaktywne okno A i nowy obiekt B do obsługi jego własnego przycisku jButton1.
Tak na marginesie nawet obiekt kryjący się pod jButton1 nie jest przyciskiem, który widzisz na ekranie. Ale nie będę tego rozwijał bo już zupełnie stracisz orientację.

Pamiętaj, że definicja klasy, to tylko przepis na stworzenie obiektu - sama klasa nie jest obiektem. Ważne jest gdzie tworzysz obiekt i co się dalej dzieje z referencją lub referencjami do niego.
Referencje możesz kopiować i powielać nieskończoną liczbę razy. Referencje o różnych nazwach mogą odnosić się do tego samego obiektu, ba te referencje nie muszą być nawet referencjami do tej samej klasy, lecz referencjami do klas przodków klasy tego obiektu. Jeżeli referencję rzutuje się w górę na przodka klasy, to nie trzeba używać nawet operatora konwersji. Natomiast odwrotnie jak najbardziej (i jeszcze należy użyć operatora instanceof), ponieważ jeżeli mamy referencję A a, to żeby było możliwe (B)a, to gdzieś kiedyś musiało być takie pośrednie przypisanie: a = /...kawał programu.../ = new B(), a B musi być jakimś potomkiem (być może dalekim) klasy A.

Co do przykładu nr 1, powinno to być albo tak:

public class A extends javax.swing.JFrame {
 
    public A() {
     
        initComponents();
    }
 
    public void initComponents() {
        jButton1 = new javax.swing.JButton();
        B odwolaj_sie = new B(this);
        jButton1.addActionListener(odwolaj_sie);
        jLabel1 = new javax.swing.JLabel();

    }
    public javax.swing.JLabel jLabel1;
    public javax.swing.JButton jButton1;
}

public class B implements ActionListener
{
    public B(A obiekt) { this.przejdz = obiekt; }

    public void actionPerformed(ActionEvent evt)
    {
        // tu wczytanie fotki
        przejdz.jLabel1.setIcon(image);
    }

    private ImageIcon image;
    private A przejdz;
}

Albo tak:

public class A extends javax.swing.JFrame {
 
    public A() {
     
        initComponents();
    }
 
    public void initComponents() {
        jButton1 = new javax.swing.JButton();
        B odwolaj_sie = new B();
        jButton1.addActionListener(odwolaj_sie);
        jLabel1 = new javax.swing.JLabel();

    }
    private javax.swing.JLabel jLabel1;
    private javax.swing.JButton jButton1;
}

public class B implements ActionListener
{
    public void actionPerformed(ActionEvent evt)
    {
        // tu wczytanie fotki
        JButton przycisk = (JButton)(evt.getSource());
        A przejdz = (A)(przycisk.getParent());
        przejdz.jLabel1.setIcon(image);
    }

    public ImageIcon image;
}

Jednak nie rozumiem po jakiego grzyba umieszczać obsługę zdarzeń obiektów jednej klasy w innej klasie publicznej, na dodatek z publicznymi polami. Stracisz miesiące na odkręcanie problemów jakie przez to spowodujesz. Po jakimś czasie wyrzucisz tak napisany program do kosza bo szybciej będzie napisać go poprawnie od początku.

0

Dzieki za wypowiedź, czas :-), Co do Twojego pytania "po jakiego grzyba.." Piszę program w Netbeans i nie chciałem w jednej klasie dziedziczącej po JFrame pakować całego kodu. Ale miedzy innymi dzięki Twojej wypowiedzi postanowaiłem zmienić postępowanie z programem. Bo faktycznie to się mija z celem.Mam jeszcze jedno pytanie w jaki sposób Ty byś napisał taki program żeby wszystko nie znajdowało się w jednej klasie no i też żeby to miało rece i nogi i nie zamulało. Chodzi mi o ogolny rozrys jak to powinno wygladać z punktu widzenia javy dobrego kodu. A coś więcej o programie JLabel kilka przycisków obsługujęcych wczytanie zapisanie zdjęć jakieś efekty np negatyw obsługiwany przyciskiem + kilka innych efektów. Pozdrawiam i jeszcze raz dzieki za już poświecony czas no i wypowiedz oczywiście :-)

0

Będziesz miał jeszcze mnóstwo innych okazji, żeby Twój kod znalazł się w osobnych klasach. Akurat listenery, dla pojedynczego okienka to jeden z niewielu wypadków kiedy najbardziej przydatne jest wpakowanie wszystkiego w obrębie jednej klasy.

Co do równomiernego rozłożenia kodu, to zauważ, że jeżeli coś w swoim programie możesz nazwać jednym słowem, to jest to już całkiem niezły kandydat na zupełnie osobną klasę. Tym bardziej jeżeli będziesz takich "cosiów" potrzebować więcej niż jeden egzemplarz. A na pewno będziesz. Na przykład "zdjęcie" może być Twoją Klasą. Co prawda istnieje klasa BufferedImage reprezentująca obrazek i pewne nawet dość rozbudowane operacje, ale aby zakodować sobie kilka operacji na zdjęciu, które akurat będziesz potrzebować możesz stworzyć klasę opakowującą tę pierwszą, której metody będą tymi kilkoma operacjami, które będą Ci akurat potrzebne.

A co do poprawnego robienie programów w Swingu, to polecam śledzenie gotowych przykładów z tutoriali (np. tego ze strony Suna). Po oglądnięciu kilkunastu lub kilkudziesięciu z nich wyrobisz sobie pogląd jak powinien wyglądać dość dobrze zakodowany program w Swingu. Alternatywą jest wyhaczenia jakiegoś podręcznika do Swinga (a najlepiej zastosować obie metody). Mimo to nie unikniesz potrzeby podciągnięcia samej Javy ponieważ Swing czy inne GUI zaczepiają o wielowątkowość, klasy wewnętrzne i anonimowe, tablice oraz kolekcje.

0

Okej, no to zabieram sie za tutoriale suna. THX za pomoc . Pozdrawiam

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