Brian P
Brian P

Reputation: 366

implementing next and previous buttons using a LinkedList

This might be a stupid question, but I'm having trouble thinking this through.

I wrote a method that uses a LinkedList to move through loaded MIDI instruments. I want to make a next and a previous button so that every time you click the button you traverse through the LinkedList.

If I hardcode itr.next(); or itr.previous(); multiple times I can traverse through the LinkedList

public void setInsturment(Synthesizer start,MidiChannel currentChannel[])
{
    try
    {
        start.open();

        Soundbank bank = start.getDefaultSoundbank();

        start.loadAllInstruments(bank);

        LinkedList<Instrument> currentInstrument = new LinkedList<Instrument>();

        Instrument instrs[] = start.getLoadedInstruments();

        currentInstrument.add(instrs[0]);
        currentInstrument.add(instrs[1]);
        currentInstrument.add(instrs[2]);
        currentInstrument.add(instrs[3]);
        currentInstrument.add(instrs[4]);

        ListIterator itr = currentInstrument.listIterator();
        itr.next();
        itr.next();
        itr.next();
     // nextInstrument();

        currentChannel[1].programChange(0,itr.nextIndex());

    }

    catch(MidiUnavailableException e)
    {
        System.out.print("error");
    }

}

I'm having a lot of trouble making a button that can traverse through the list. Is there an efficient way to do this? I tried something like this with no success.

public void actionPerformed(ActionEvent e)
{
    if (e.getSource() == nextButton)
    {
        sound.nextInstrument();
    }

public void nextInstrument()
{
    itr.next();
}

Thanks in advance guys!

Upvotes: 3

Views: 2057

Answers (4)

Andrew Thompson
Andrew Thompson

Reputation: 168825

MIDI instruments .. next and a previous button

Use an array (e.g. Instrument[]). It might be displayed in a JComboBox, a JList or a JSpinner to allow the user to select an instrument. Here is an example using a combo with renderer.

enter image description here

import java.awt.Component;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import javax.swing.*;
import javax.sound.midi.*;

class InstrumentSelector {

    public static void main(String[] args) throws MidiUnavailableException {
        Synthesizer synthesizer = MidiSystem.getSynthesizer();
        synthesizer.open();
        final Instrument[] orchestra = synthesizer.getAvailableInstruments();
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JComboBox orchestraSelector = new JComboBox(orchestra);
                orchestraSelector.setRenderer(new InstrumentRenderer());

                JOptionPane.showMessageDialog(null, orchestraSelector);
            }
        });
    }
}

class InstrumentRenderer extends BasicComboBoxRenderer {

    @Override
    public Component getListCellRendererComponent(
        JList list,
        Object value,
        int index,
        boolean isSelected,
        boolean cellHasFocus) {
        Component c = super.getListCellRendererComponent(
            list, value, index, isSelected, cellHasFocus);
        if (c instanceof JLabel && value instanceof Instrument) {
            JLabel l = (JLabel)c;
            Instrument i = (Instrument)value;
            l.setText(i.getName());
        }
        return c;
    }
}

Upvotes: 4

Well, hmm, a linked list is a List and its items can be accessed by index, this is not the optimal structure to access items by index but I really don't know if you can have a cursor on that kind of collection but you can store the current index on an instance variable.

If you really want random access, then you should consider using ArrayList instead of linked list.

Example:

class NextPrevList {
    private int index = 0;
    private List currentList; //initialize it with some list

    public Object next() {
        return list.get(++index);
    }
    public Object prev() {
        //maybe add a check for out of bounds
        if (index == 0) return null;
        return list.get(--index);
    }
}

Personally I think it would be more performant with an ArrayList rather than a LinkedList

Upvotes: 4

trashgod
trashgod

Reputation: 205785

Code to the interface: List<Instrument>. This related example navigates a List<ImageIcon>, but the implementation could be changed as required.

Upvotes: 4

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

The ListIterator#next() method returns the object of interest. If it were my project, I'd assign what is returned from that method to a class field and then notify the GUI of the change.

someInstrument = itr.next();
// fire notify observers method.

Upvotes: 4

Related Questions