Swing - usuwanie elementów z ComboBox'a

Swing - usuwanie elementów z ComboBox'a
M0
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:38
0

Do kodu z książki Thinking in Java dodałem przycisk do usuwania elementów z rozwijanej listy (JComboBox), a wygląda to tak:

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

public class Main extends JApplet{

    private String[] opis = {
      "Rozentuzjazmowany", "Ograniczony", "Krnabrny", "Blyskotliwy",
      "Samolubny", "Niesmialy", "Zdrowy", "Zgnily"
    };
    private JTextField t = new JTextField(15);
    private JComboBox c = new JComboBox();
    private JButton b = new JButton("Dodaj elementy"),
            b2 = new JButton("Usun 0 element");
    private int count = 0;
    public void init(){
        for(int i = 0;i<4;i++){
            c.addItem(opis[count++]);
        }
        t.setEditable(false);
        b.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                if(count<opis.length)
                    c.addItem(opis[count++]);
            }
        });
        b2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                    c.removeItemAt(0);
            }
        });
        c.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                validate();
                t.setText("Indeks: "+ c.getSelectedIndex() + " " + ((JComboBox)e.getSource()).getSelectedItem());
            }
        });
//reszta kodu do uruchamiania programu - standardowa

Problem jest z wyświetlaniem tekstu. Gdy przełącza się między elementami listy to wszystko jest dobrze, lecz gdy kliknie się przycisk i usunie się pierwszy element z listy (Indeks: 0) to faktycznie on się usuwa, reszta elementów się przesuwa do góry lecz w polu tekstowym pojawia się: "Indeks: 1 Ograniczony", a przecież po usunięciu elementu: "Rozentuzjazmowany", element "Ograniczony" ma już Indeks: 0, a wyświetla, że 1. Gdy rozwinie się listę i kliknie na pierwszy element to pole tekstowe się odświeża i już wyświetla prawidłowo: Indeks: 0 Ograniczony. Lecz co zrobić by wyświetlał tak od razu po usunięciu elementu? Dopisałem przed wyświetlanie tekstu: validate(); bo to podobno od odświeżania całej ramki ale to nic nie dało.

0
  1. Dlaczego oczekujesz, że po kliknięciu w button b2 wykona się metoda actionPerformed() podpięta do JComboBoxa? Musisz sam zmienić tekst.
  2. Wyświetlasz index wybranej pozycji, po usunięciu żadna może nie być wybrana.
M0
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:38
0

Tylko właśnie chodzi o to, metoda ta chyba jednak się wywołuje bo tekst w JTextField się zmienia, tylko dlaczego źle odczytuje indeks ale dobrze to co się pod nim znajduje?

iooi
  • Rejestracja:prawie 15 lat
  • Ostatnio:ponad 11 lat
  • Postów:573
1

actionPerformed listenera ComboBoxa wywołuje się wtedy, kiedy zaznaczenie zostaje zmienione: czyli, przy naciśnięciu b2, tylko wtedy, gdy wcześniej zaznaczony był pierwszy item na liście (wtedy najpierw następuje zmiana na następny, wywołanie metody listenera, ustawienie tekstu, a na koniec usunięcie pierwszego elementu). Łatwo to sprawdzić:

Kopiuj
b2.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        c.removeItemAt(0);
        System.out.println("usuwanie");
    }
});
c.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        t.setText("Indeks: " + c.getSelectedIndex() + " " + c.getSelectedItem());
        System.out.println("indeks");
    }
});

W żadnym wypadku jednak tekst nie jest zmieniany już po usunięciu - musisz to zrobić sam, najlepiej przenosząc t.setText... do osobnej metody i wołając ją z actionPerformed b2 i c.

edytowany 1x, ostatnio: iooi
1

"Dupa" debugger rozstrzyga, że ta metoda wykonuje się czasami - tylko wtedy gdy usuwany jest "widoczny" item. Tak działa ("dupa" debuggera możesz usunąć ;-)).

Kopiuj
        b2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                    c.removeItemAt(0);
                    t.setText("Indeks: "+ c.getSelectedIndex() + " " + c.getSelectedItem());
            }
        });
        c.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                System.out.println("dupa");
                t.setText("Indeks: "+ c.getSelectedIndex() + " " + c.getSelectedItem());
            }
        });
M0
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:38
0

Według wersji @bo po kliknięciu przycisku od usuwania, wyświetla "dupa" a potem wyrzuca wyjątek "Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox" w linii t.setText w listenerze od b2 (JButton od usuwania).

Z kolei w wersji @iooi nie wyrzuca wyjątków, a podczas usuwania najpierw wyświetla "indeks" a potem "usuwanie".

Czyli wychodzi na to, że gdy usuwany jest aktualnie zaznaczony element z listy to wykonuje się najpierw listener ComboBox'a a potem dopiero usuwanie. Z kolei gdy zaznaczony był sobie element np. 3 a usuwa się pierwszy (tzn indeks 0) to w polu tekstowym nic się nie zmienia a wyświetla się tylko "usuwanie" bez "indeks" czyli listener ComboBox'a w ogóle nie jest uruchamiany.

Tylko skąd ten wyjątek w przypadku wersji @bo?

0

Z tego, że źle przepisałeś kod. W moim kodzie __nie ma __rzutowania.

M0
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 10 lat
  • Postów:38
0

Faktycznie, nie zauważyłem. I rzeczywiście nie ma "d**y" tzn. lipy;) Dzięki wielkie.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.