问题描述
所以我认为我需要拆分滚动窗格列表,因为它要显示100多个项目。我当时在想我可以有一个带有选项卡的滚动窗格,而每个选项卡都具有列表的不同部分。有点像选项卡式窗格,但仅对于滚动窗格而言,它只是一个组件。问题是我不知道该怎么做或是否可能。
解决方法
这里是显示JTable
中所有库的MIDI乐器的示例。在其上方提供三个组合框(JComboBox
)和一个JTextField
。
文本字段可以搜索(不区分大小写)用户输入的任何字符串。
组合可以用于过滤:
- 乐器的类别。
- 乐器类型。
- 乐器名称中的公用字符串。
哦,我投入了JList
个类别。它什么也没做,但是如果我再做完,我将以LINE_START
位置开始并且只有列表。
import java.awt.*;
import java.awt.event.*;
import javax.sound.midi.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.EmptyBorder;
public class MidiInstrumentSearch {
private JComponent ui = null;
Instrument[] instruments;
JLabel messageLabel = new JLabel("Message Label");
JTable table;
MidiInstrumentTableModel tm;
TableRowSorter sorter;
InstrumentCategory[] instrumentCategories = {
new InstrumentCategory("All",1,10000),new InstrumentCategory("Piano",8),new InstrumentCategory("Chromatic Percussion",9,16),new InstrumentCategory("Organ",17,24),new InstrumentCategory("Guitar",25,32),new InstrumentCategory("Bass",33,40),new InstrumentCategory("Strings",41,48),new InstrumentCategory("Ensemble",49,56),new InstrumentCategory("Brass",57,64),new InstrumentCategory("Reed",65,72),new InstrumentCategory("Pipe",73,80),new InstrumentCategory("Synth Lead",81,88),new InstrumentCategory("Synth Pad",89,96),new InstrumentCategory("Synth Effects",97,104),new InstrumentCategory("Ethnic",105,112),new InstrumentCategory("Percussive",113,120),new InstrumentCategory("Sound Effects",121,128)
};
MidiInstrumentSearch() {
try {
initUI();
} catch (MidiUnavailableException ex) {
ex.printStackTrace();
}
}
public final void initUI() throws MidiUnavailableException {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4));
ui.add(messageLabel,BorderLayout.PAGE_END);
ui.add(new JScrollPane(new JList(instrumentCategories)),BorderLayout.LINE_START);
Synthesizer synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
instruments = synthesizer.getAvailableInstruments();
InstrumentPOJO[] inst = new InstrumentPOJO[instruments.length];
for (int ii = 0; ii < inst.length; ii++) {
inst[ii] = new InstrumentPOJO(instruments[ii]);
}
tm = new MidiInstrumentTableModel(inst);
sorter = new TableRowSorter<>(tm);
table = new JTable(tm);
table.setRowSorter(sorter);
ui.add(new JScrollPane(table));
JToolBar toolBar = new JToolBar();
toolBar.setLayout(new FlowLayout());
ui.add(toolBar,BorderLayout.PAGE_START);
final JComboBox categoryBox = new JComboBox<>(instrumentCategories);
ActionListener categoryListener = (ActionEvent e) -> {
InstrumentCategory ic = (InstrumentCategory) categoryBox.getSelectedItem();
CategoryFilter categoryFilter = new CategoryFilter(ic);
sorter.setRowFilter(categoryFilter);
setNumber();
};
categoryBox.addActionListener(categoryListener);
toolBar.add(new JLabel("Category"));
toolBar.add(categoryBox);
toolBar.add(new JLabel("Type"));
String[] types = {"","Instrument","Drumkit"};
final JComboBox typeBox = new JComboBox<>(types);
toolBar.add(typeBox);
ActionListener typeSearchListener = (ActionEvent e) -> {
String s = typeBox.getSelectedItem().toString();
SearchFilter sf = new SearchFilter(0,s);
sorter.setRowFilter(sf);
setNumber();
};
typeBox.addActionListener(typeSearchListener);
String[] nameCommon = {
"","bass","bell","brass","bs","drum","flute","gt","harp","horn","org","orch","pad","piano","sax","str","syn","vox","wave"
};
final JComboBox nameBox = new JComboBox(nameCommon);
ActionListener nameListener = (ActionEvent e) -> {
SearchFilter sf = new SearchFilter(1,nameBox.getSelectedItem().toString());
sorter.setRowFilter(sf);
setNumber();
};
nameBox.addActionListener(nameListener);
toolBar.add(new JLabel("Name"));
toolBar.add(nameBox);
JTextField searchField = new JTextField("Enter to Search",12);
toolBar.add(searchField);
ActionListener textSearchListener = (ActionEvent e) -> {
SearchFilter sf = new SearchFilter(1,e.getActionCommand());
sorter.setRowFilter(sf);
setNumber();
};
searchField.addActionListener(textSearchListener);
}
private void setNumber() {
int i = table.getRowCount();
setNumber(i);
}
private void setNumber(int n) {
messageLabel.setText(n + " presets");
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
MidiInstrumentSearch o = new MidiInstrumentSearch();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
class InstrumentPOJO {
private final Instrument instrument;
private final String category;
private final String name;
private final int bank;
private final int preset;
InstrumentPOJO(Instrument instrument) {
this.instrument = instrument;
String s = instrument.toString();
category = getTextBetween(s,"",":");
name = getTextBetween(s,":","bank");
bank = Integer.parseInt(getTextBetween(s,"bank #"," preset"));
String pre = "preset #";
int index = s.indexOf(pre);
s = s.substring(index + pre.length());
preset = Integer.parseInt(s);
}
private String getTextBetween(String s,String s1,String s2) {
int i1 = s.indexOf(s1);
int c1 = i1 + s1.length();
int i2 = s.indexOf(s2);
return s.substring(c1,i2).trim();
}
@Override
public String toString() {
return getCategory() + " \t"
+ getName() + " \t"
+ getBank() + " \t"
+ getPreset() + " \t";
}
public Instrument getInstrument() {
return instrument;
}
public String getCategory() {
return category;
}
public String getName() {
return name;
}
public int getBank() {
return bank;
}
public int getPreset() {
return preset;
}
}
class MidiInstrumentTableModel extends AbstractTableModel {
final static String[] colNames = {"Category","Name","Bank","Preset"};
InstrumentPOJO[] orchestra;
MidiInstrumentTableModel(InstrumentPOJO[] orchestra) {
this.orchestra = orchestra;
}
@Override
public int getRowCount() {
return orchestra.length;
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Object getValueAt(int rowIndex,int columnIndex) {
final InstrumentPOJO ip = orchestra[rowIndex];
switch (columnIndex) {
case 0:
return ip.getCategory();
case 1:
return ip.getName();
case 2:
return ip.getBank();
case 3:
return ip.getPreset();
default:
return null;
}
}
@Override
public String getColumnName(int columnIndex) {
return colNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return String.class;
case 2:
return Integer.class;
case 3:
return Integer.class;
default:
return Integer.class;
}
}
@Override
public boolean isCellEditable(int rowIndex,int columnIndex) {
return false;
}
}
class SearchFilter extends RowFilter {
int col;
String target;
SearchFilter(int col,String target) {
this.col = col;
this.target = target;
}
@Override
public boolean include(Entry entry) {
String s = entry.getValue(col).toString();
return s.toLowerCase().contains(target.toLowerCase());
}
}
class CategoryFilter extends RowFilter {
InstrumentCategory cat;
CategoryFilter(InstrumentCategory cat) {
this.cat = cat;
}
@Override
public boolean include(Entry entry) {
int i = (Integer) entry.getValue(3) + 1;
return (i >= cat.getFirst() && i <= cat.getLast());
}
}
class InstrumentCategory {
private final String name;
private final int first;
private final int last;
public InstrumentCategory(String name,int first,int last) {
this.name = name;
this.first = first;
this.last = last;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the first
*/
public int getFirst() {
return first;
}
/**
* @return the last
*/
public int getLast() {
return last;
}
@Override
public String toString() {
return name;
}
}