JComboBox und Model

Diskutiere JComboBox und Model im AWT, Swing, JavaFX & SWT Bereich.
F

Fohnbit

Hallo,

ich habe diese Klasse:
Java:
public class CategorieExport extends AbstractListModel implements ComboBoxModel {
    public ArrayList<Product> product = new ArrayList<Product>();

    Product selection = null;

    @Override
    public Object getElementAt(int index) {
        return product.get(index);
    }

    @Override
    public int getSize() {
        return product.size();
    }

    @Override
    public Object getSelectedItem() {
        return selection;
    }

    @Override
    public void setSelectedItem(Object item) {
        selection = (Product) item;
    }
}
Und binde die als Model an eine Combobox:
Java:
JComboBox cmbProducts = new JComboBox();
cmbProducts.setModel(categorieExport);
cmbProducts.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                product = (Product) cmbProducts.getSelectedItem();
                product.addPropertyChangeListener(ProductEditor.this);
                product.refresh();
            }
        });
wenn ich nun das Objekt mit aus einem JSON lade, passt alles:
Java:
categorieExport = gson.fromJson(reader, CategorieExport.class);
cmbProducts.setModel(categorieExport);
cmbProducts.setSelectedIndex(0);
** Muss ich eigentlich hier nochmal das "setModel" aufrufen?

Wie kann ich nun aber "Product" zu dem Objekt "CategorieExport" hinzufügen, damit die in der ComboBox auftauchen?:
Code:
categorieExport.product.add(new Product());
cmbProducts.setModel(categorieExport);
cmbProducts.setSelectedIndex(categorieExport.getSize() - 1);
product = (Product) cmbProducts.getSelectedItem();
poduct.addPropertyChangeListener(ProductEditor.this);
product.refresh();
Da zeigt die ComboBox dann nichts mehr an.

Und wie lösche ich wieder ein product?

Ich dachte ich brauch nur die "CategorieExport" aktualisieren mit .add und .remove der einzelnen Product .. aber die ComboBox refresht dann nicht.[/CODE]
 
Zuletzt bearbeitet:
mihe7

mihe7

Du spendierst Deiner Model-Klasse eine Methode:
Java:
    public void add(Product p) {
        int ix = product.size();
        product.add(p);
        fireIntervalAdded(this, ix, ix);
    }
und verwendest die, um ein Produkt hinzuzufügen. Du musst also nur noch categorieProduct.add(...) aufrufen, die Aktualisierung geschieht automatisch.
 
F

Fohnbit

edit:

updateUI() ist wohl die passende Methode um die Komponente zu aktualisieren:
Java:
    categorieExport.product.add(new Product());
                cmbProducts.updateUI();
                cmbProducts.setSelectedIndex(categorieExport.getSize() - 1);
 
F

Fohnbit

Du spendierst Deiner Model-Klasse eine Methode:
Java:
    public void add(Product p) {
        int ix = product.size();
        product.add(p);
        fireIntervalAdded(this, ix, ix);
    }
und verwendest die, um ein Produkt hinzuzufügen. Du musst also nur noch categorieProduct.add(...) aufrufen, die Aktualisierung geschieht automatisch.
Mir hatte die ComboBox nie aktualisiert. Mit updateUI() bildet Sie dann wieder exact das ab, was im Model drinnen ist (nachdem dieses geändert wurde)
 
mihe7

mihe7

Java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

import java.util.*;

public class Test {

    static class Product {
        final String name;
        public Product(String name) { this.name = name; }
        public String toString() { return name; }
    }

    static class ProductModel extends AbstractListModel<Product> 
            implements ComboBoxModel<Product> {
        List<Product> products = new ArrayList<>();
        Object selected;

        public void add(Product p) {
            int ix = products.size();
            products.add(p);
            fireIntervalAdded(this, ix, ix);
        }

        public Product getElementAt(int ix) { return products.get(ix); }
        public int getSize() { return products.size(); }

        public void setSelectedItem(Object item) {
            this.selected = item;
            fireContentsChanged(this, -1, -1);
        }

        public Object getSelectedItem() { return selected; }
    }

    public void run() {
        ProductModel model = new ProductModel();
        JButton newProduct = new JButton("Neues Produkt");
        newProduct.addActionListener(e -> {
            String input = JOptionPane.showInputDialog(newProduct, "Produktname");
            if (input != null) {
                model.add(new Product(input));
            }
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(newProduct, BorderLayout.SOUTH);
        frame.add(new JComboBox<Product>(model), BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
 
F

Fohnbit

Hallo mihe7,

danke ... das klappt nun soweit, aber:
Die ComboBox refresht erst, wenn ich mit der Maus drüber fahre!

Kannst du erahnen warum das so ist, oder muss ich den ganzen Code hier einstellen?
 
F

Fohnbit

Ok, sorry, habs nicht gut beschrieben:
Meine Produkte haben toString() von der SKU.
Das ist beim neu anlegen noch leer.

Wenn ich in die Form die SKU eingebe, refresht die CombcoBox erst wenn ich mit der Maus drüber fahre. Da sich der Name geändert hat.

Wenn ich dort das updateUI setze, wird die Combobox gleich aktualisiert:.
Java:
txtInternalReference = new JTextField();
        txtInternalReference.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent arg0) {
                product.setInternalReference(txtInternalReference.getText());
                cmbProducts.updateUI();
            }
        });
Ist das in diesem Fall nötig?

product ist das aktuell ausgewählte ComboBox Objekt
 
mihe7

mihe7

Du änderst ein Produkt, das bereits in der Liste ist? Das musst Du dem Model bekanntgeben (z. B. eine Methode implementieren) und das Model muss daraufhin mittels fireContentsChanged der ComboBox Bescheid geben.
 
Thema: 

JComboBox und Model

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben