zmiana rysunku w okienku

0

Witam, mam mały-wielki problem i chciałam się nim podzielić ;)
Tworzę aplikacje sieciową (typu chat) i mam kłopot z jedną rzeczą... Mianowicie chciałabym, żeby na niektóre komunikaty od serwera (rozpoczynające się od "*") w okienku aplikacji zmieniał się rysunek... I szczerze mówiąc jako że nie miałam wcześniej zbyt wiele z java do czynienia mam z tym cholerny kłopot.
Dokładnie rzecz biorąc chcę, żeby zamiast napisu "Przylali mi plansze" w polu okno.plansza pojawiał się inny obrazek. Niestety żadne z moich zabiegów nie pozwoliły mi uzyskać takiego efektu:( Ktoś pomoże?

znaczek ='*';
public void run() {
try {
while ((str = in.readLine()) != null) { //az nie bedzie konca pliku
//nie mozna tego sprawdzac wyjatkiem !!!
//po koncu pliku jest zwracany null
znaczek = str.charAt(0);
if (znaczek != '%')
{
okno.lista.append(str + znaczek + "\n");
//ponizsze by widzec ostatni wpis
okno.lista.scrollRectToVisible(
new Rectangle(0, okno.lista.getHeight()-2, 1, 1));
okno.gora.repaint();
}
if (znaczek == '%') {okno.lista.append(" Przylali mi plansze :D \n");} // okno.plansza = new JLabel(new ImageIcon("plik2.jpg")); okno.plansza.repaint();}
}

Okienko jest inicjowane w ten sposób :

public class ChatKlient extends JFrame implements ActionListener {
PrintWriter out;
int portSerwera = 12345;
String adresSerwera = null;
InetAddress iAdres = null;
Socket socket = null;
static ChatKlient okno;
JLabel plansza = new JLabel(new ImageIcon("plik.jpg"));
JLabel plansza2 = new JLabel(new ImageIcon("plik2.jpg"));
JTextArea lista = new JTextArea();
JScrollPane gora = new JScrollPane(lista);
JTextField wpis = new JTextField(17);
JButton wyslij = new JButton("Wyslij.....");

ChatKlient(String tytul) {
super(tytul);
}
public static void main(String[] args) {
okno = new ChatKlient(".:. Gra sieciowa kółko i krzyżyk .:. ");
okno.init();
Zamykacz stroz = new Zamykacz(okno);
okno.addWindowListener(stroz);
okno.show();
okno.polacz();
}
void init() {
setSize(500, 450);
setResizable(false);
Container cp = getContentPane();
//cp.setLayout(new GridLayout(5,3));
lista.setEditable(false);
gora.setBorder(
new TitledBorder(new LineBorder(Color.blue), "Info od serwera"));
cp.add(BorderLayout.CENTER, gora);
JPanel dol2 = new JPanel();
JPanel dol = new JPanel();
dol.setLayout(new FlowLayout());dol2.setLayout(new FlowLayout());
wyslij.addActionListener(this);
wpis.addActionListener(this);
dol2.add(plansza);
dol.add(wpis);
dol.add(wyslij);
cp.add(BorderLayout.SOUTH, dol);
cp.add(BorderLayout.WEST, dol2);
}
void polacz() {
try {
iAdres = InetAddress.getByName(adresSerwera);
lista.append("Łacze sie z adresem = " + iAdres + "\n");
} catch (Exception e) {
System.exit(0);
}
try {
socket = new Socket(iAdres, portSerwera);
} catch (IOException e) {
lista.append("Nie udało sie uzyskac połaczenia\n");
}
//startuje watek nasłuchujacy
Thread watek = new WatekKlientaChat(this);
watek.start();
try {
out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
} catch (Exception e) {
lista.append("Blad: " + e);
}
}
public void actionPerformed(ActionEvent zdarzenie) {
out.println(wpis.getText());
if (wpis.getText().equals("1")) try{{ { dol2.add(plansza);cp.add(BorderLayout.WEST, dol2);}}}catch(Exception e){}
if (wpis.getText().equals("KONIEC")){
try{
out.close();
socket.close();
}catch(Exception e){}
System.exit(0);
}
wpis.setText("");
}
}

Bardzo proszę o jakąś podpowiedź.

0

Nie uwzględniasz faktu, że plansza nie ma nic wspólnego z obiektem, który stworzyłaś na ekranie. To, że tworzysz pole w swojej klasie i nazywasz go plansza nie ma dla Swinga znaczenia. Znaczenie ma natomiast ten fragment:
dol2.add(plansza);
To co on robi, to dodaje do panelu obiekt JLabel zainicjowany tak: JLabel(new ImageIcon("plik.jpg"));
Sam panel dodajesz do contentPane, co jest prawidłowe.
Aby więc coś zmieniło się na ekranie musisz poinformować Swinga, że to co dodałaś za pomocą instrukcji na początku zmieniło się. Przy czym możesz to zrobić na dwa sposoby. Pierwszy, to zmienić sam obiekt Jlabel na inny przez przypisanie jakiejś zmiennej (np. nowaPlansza) nowej wersji, a następnie wykonaniu poleceń:

dol2.remove(plansza);
plansza = nowaPlansza; //tu może być też utworzenie nowego obiektu JLabel
dol2.add(plansza);

lub przez zmianę zawartości obiektu JLabel, którego komponent GUI jest już na ekranie np.:

plansza.setImage(...);
plansza.invalidate();
dol2.revalidate();

Oczywiście nie musi to od razu zadziałać w takiej postaci jak podałem ponieważ piszę z pamięci i dlatego trzeba zaglądnąć do dokumentacji (javadoc). :)

Ucząc się Swinga (lub jakiegokolwiek GUI) trzeba załapać, że jedyne polecenia, które "coś robią" na ekranie za pośrednictwem Swinga, to setVisible, validate, revalidate i repaint. Całą reszta, to tylko przygotowanie danych dla metod, które wymieniłem.

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