Search code examples
javaxmlswingjcombobox

Two JComboBoxes. The first one doesn't change the second one


I'd like my application to be able to choose 1000 presets.

So I got the idea that the 1000 presets divided into 10 banks of 100 presets.

I'd like to use two JComboboxes, which the first one is list of banks (the choice of 1 of 10). The second one would have 100 presets.

After selecting one of banks in the first one, it doesn't refresh the list of presets in the second one.

The method GetXML.setBankFromBankCombo() is changing variable bank. (GetXML is a class that reads an XML file). As can be seen by printing System.out.println (), but I don't know why the presets in JCombo does not change.

To make it more clearly code, I limited the number of banks and presets to 3 items.

screenshot1 screenshot2

Class FrameCombo:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.*;

public class FrameCombo extends JPanel {

    private Presets comboPresets;
    private JComboBox comboBank;
    private int activeBank;

    public FrameCombo() {

        activeBank = 1;
        setPreferredSize(new Dimension(410, 200));


        /**
         * Bank Combo
         *
         */
        String[] banks = {
            "Bank 0",
            "Bank 1",
            "Bank 2"
        };


        comboBank = new JComboBox(banks);
        comboBank.setEditable(true);
        comboBank.setPreferredSize(new Dimension(180, 30));
        comboBank.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JComboBox cb = (JComboBox) e.getSource();
                activeBank = cb.getSelectedIndex();
                comboPresets.setBank(activeBank);
                System.out.println("FrameCombo.activeBank = " + activeBank);

            }
        });
        JPanel bankPanel = new JPanel();
        bankPanel.setPreferredSize(new Dimension(180, 100));
        bankPanel.add(new JLabel("Banks"));
        bankPanel.add(comboBank);
        add(bankPanel);





        /**
         * Presets Combo
         *
         */
        comboPresets = new Presets();
        comboPresets.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                //presets do something
            }
        });

        JPanel presetPanel = new JPanel();
        presetPanel.setPreferredSize(new Dimension(180, 110));
        presetPanel.add(new JLabel("Presets"));
        presetPanel.add(comboPresets);
        add(presetPanel);
    }

    public void setBank(int value) {
        activeBank = value;
    }

    public int getBank() {
        return activeBank;
    }

    public static void main(String[] args) {
        final String title = " Frame Combo";
        System.out.println(title);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame(title);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().add(new FrameCombo());

                frame.setResizable(false);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

class Presets:

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

public class Presets extends JPanel
        implements ActionListener {

    private int bank;
    private int value;
    private int[] ctrlIdx = new int[3];
    private int controller;
    private ChangeEvent changeEvent = null;
    private EventListenerList listenerList = new EventListenerList();
    private GetXMLPresets dane;
    private String[][] patern;
    private String[] itemName;
    public MainWindow model = new MainWindow();
    JComboBox item;

    public Presets() {


        dane = new GetXML(bank);
        patern = dane.ct; // controllers
        itemName = dane.lb; // name
        System.out.println("Presets() " + bank);
        JComboBox item = new JComboBox(itemName);
        item.setSelectedIndex(0);
        item.addActionListener(this);
        item.setPreferredSize(new Dimension(180, 30));
        add(item);
        setPreferredSize(new Dimension(210, 40));
    }

    public void setValue(int c, int v) {
        controller = c;
        value = v;
        ctrlIdx[controller] = value;
        repaint();
        fireChangeEvent();
    }

    public int getController() {
        return controller;
    }

    public int getValue(int c) {
        int w = (int) ctrlIdx[c];
        return (int) w;
    }

    public void setBank(int value) {
        bank = value;
        dane.setBankFromBankCombo(bank);
        repaint();
        fireChangeEvent();
    }

    public int getBank() {
        return bank;
    }

    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox) e.getSource();
        String item = (String) cb.getSelectedItem();
        int indeks = cb.getSelectedIndex();

        for (int i = 0; i < itemName.length; i++) {
            for (int j = 0; j < patern[i].length; j++) {
                model.setController(j, Integer.parseInt(patern[indeks][j]));
                setValue(j, Integer.parseInt(patern[indeks][j]));
            }
        }

    }

    public void addChangeListener(ChangeListener cl) {
        listenerList.add(ChangeListener.class, cl);
    }

    public void removeChangeListener(ChangeListener cl) {
        listenerList.remove(ChangeListener.class, cl);
    }

    protected void fireChangeEvent() {

        Object[] listeners = listenerList.getListenerList();

        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ChangeListener.class) {

                if (changeEvent == null) {
                    changeEvent = new ChangeEvent(this);
                }
                ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
            }
        }
    }
}

class GetXML:

import java.io.*;
import javax.swing.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class GetXML extends JPanel {

    private int numpresets;
    public String[] lb = new String[3];
    public String[][] ct = new String[3][3];
    private int bank;

    public GetXML(int a) {

        bank = a;
        try {

            XPathFactory factory = XPathFactory.newInstance();
            XPath xPath = factory.newXPath();

            NodeList patches = (NodeList) xPath.evaluate("/bank/patch",
                    new InputSource(new FileReader(new File("patches/presets" + bank + ".xml").getAbsolutePath())),
                    XPathConstants.NODESET);
            setNumPresets(patches.getLength());
            String[] labels = new String[numpresets];
            String[][] ctrl = new String[numpresets][3];

            for (int i = 0; i < numpresets; i++) {
                Element patch = (Element) patches.item(i);
                String controllerName = xPath.evaluate("controllers/name/text()", patch);

                for (int j = 0; j < 3; j++) {
                    ctrl[i][j] = xPath.evaluate("controllers/c" + Integer.toString(j + 1) + "/text()", patch);
                    ct[i][j] = ctrl[i][j];
                }
                labels[i] = controllerName;
                lb[i] = labels[i];
            }
        } catch (FileNotFoundException fnfe) {
            System.out.println("FileNotFoundException " + fnfe);
            fnfe.printStackTrace();
        } catch (IOException ioe) {
            System.out.println("IOException " + ioe);
        } catch (Exception eio) {
            System.out.println("eio " + eio);
        }

    }

    public void setBank(String[] b) {
        lb = b;
    }

    public String[] getBank() {
        return lb;
    }

    public void setPreset(String[][] c) {
        ct = c;
    }

    public String[][] getPreset() {
        return ct;
    }

    public void setNumPresets(int a) {
        numpresets = a;
    }

    public int getNumPresets() {
        return numpresets;
    }

    public void setBankFromBankCombo(int id) {
        System.out.println("GetXMLPresets.setIDFromBankCombo() " + id);
        bank = id;


    }
}

and sample of one XML file Presets0.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bank bid="0">
    <patch pid="1">
        <controllers>
            <name>bank 0: preset 1</name>
            <c1>55</c1>
            <c2>3</c2>
            <c3>24</c3>
        </controllers>
    </patch>
    <patch pid="2">
        <controllers>
            <name>bank 0: preset 2</name>
            <c1>33</c1>
            <c2>1</c2>
            <c3>45</c3>
        </controllers>
    </patch>
    <patch pid="3">
        <controllers>
            <name>bank 0: preset 3</name>
            <c1>43</c1>
            <c2>23</c2>
            <c3>39</c3>   
        </controllers>
    </patch>
</bank>

Solution

  • Quite simple, you've not changed the contents of the Preset's combo box, meaning that while the data has been loaded, it has not been applied to the combo boxes model, so the combo box doesn't know that it has new data to show.

    Take a look at How to Use Comb Boxes for more details