Reputation: 366
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
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.
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
Reputation: 4704
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
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
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