【发布时间】:2016-01-10 21:40:41
【问题描述】:
我正在尝试弄清楚如何正确使用JList。我正在努力将列表与我自己的类/数据模型结合使用。
我的目标是在一个单独的类中提取列表,并从多个操作(按钮事件/操作侦听器)更改列表中显示的数据。
例如:如果用户选择了兼容的 CSV 文件,则列表应显示该文件的内容。该文件本身包含一个简单的播放列表,其组合如下:艺术家;标题;文件路径
如果用户在播放列表中添加更多歌曲,则列表应该“刷新”。我读过一些关于“FireContents...”的内容,但我首先想知道如何正确使用这些列表。
我将添加我的源代码的相关部分。任何帮助和建议表示赞赏。
public class MusicTrack implements project.model.Track{
private String strArtist;
private String strTitle;
private String strFilepath;
public MusicTrack(String strArtist, String strTitle, String strFilepath){
this.strArtist = strArtist;
this.strTitle = strTitle;
this.strFilepath = strFilepath;
}
音乐播放器:
public class MusicPlayer implements ActionListener{
private JFrame mainframe;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MusicPlayer window = new MusicPlayer();
window.mainframe.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MusicPlayer() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
mainframe = new JFrame();
mainframe.setTitle("MusicPlayer");
mainframe.setBounds(100, 100, 450, 300);
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setLocationRelativeTo(null);
// menu & menuitems
JMenuBar menuBar = new JMenuBar();
mainframe.setJMenuBar(menuBar);
JMenu mnFile = new JMenu("Datei");
menuBar.add(mnFile);
JMenuItem mnItemLoadNewList = new JMenuItem("Neue Liste laden");
mnFile.add(mnItemLoadNewList);
JMenuItem mnItemLoadLIst = new JMenuItem("Liste laden & anhängen");
mnFile.add(mnItemLoadLIst);
JMenuItem mnItemSave = new JMenuItem("Speichern");
mnFile.add(mnItemSave);
JMenuItem mnItemNewEntry = new JMenuItem("Neuer Eintrag");
mnFile.add(mnItemNewEntry);
JMenu mnSort = new JMenu("Sortieren");
menuBar.add(mnSort);
JMenuItem mnItemArtist = new JMenuItem("nach Interpret");
mnSort.add(mnItemArtist);
JMenuItem mnItemTitle = new JMenuItem("nach Titel");
mnSort.add(mnItemTitle);
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{450, 0};
gridBagLayout.rowHeights = new int[]{227, 29, 0};
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
mainframe.getContentPane().setLayout(gridBagLayout);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
JPanel listPanel = new JPanel();
listPanel.setLayout(gridBagLayout);
mainframe.getContentPane().add(listPanel);
listPanel.setVisible(true);
// Buttons
JButton btnPlayAll = new JButton("Play All");
GridBagConstraints gbc_btnPlayAll = new GridBagConstraints();
gbc_btnPlayAll.anchor = GridBagConstraints.NORTH;
gbc_btnPlayAll.fill = GridBagConstraints.HORIZONTAL;
gbc_btnPlayAll.gridx = 0;
gbc_btnPlayAll.gridy = 1;
mainframe.getContentPane().add(btnPlayAll, gbc_btnPlayAll);
//Action- & Eventlistener, registering individual ActionListener per Button
mnItemLoadNewList.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JFileChooser fChoose = new JFileChooser();
FileNameExtensionFilter fExt = new FileNameExtensionFilter("CSV", "csv");
fChoose.setFileFilter(fExt);
int returnVal = fChoose.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION){
JList<Track> list = new JList<Track>();
ListModel<Track> listModel = new DefaultListModel<Track>();
list.setModel(listModel);
JScrollPane sPane = new JScrollPane(list);
sPane.add(listPanel);
}
};
});
// FIXME - Attach!
mnItemLoadLIst.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JFileChooser fChoose = new JFileChooser();
FileNameExtensionFilter fExt = new FileNameExtensionFilter("CSV", "csv");
fChoose.setFileFilter(fExt);
int returnVal = fChoose.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION){
}
};
});
// FIXME - Save!
mnItemSave.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JFileChooser fChoose = new JFileChooser();
FileNameExtensionFilter fExt = new FileNameExtensionFilter("CSV", "csv");
fChoose.setFileFilter(fExt);
int returnVal = fChoose.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION){
File selcdFile = new File(fChoose.getSelectedFile().toString());
PlayList myPL = new PlayList();
myPL.getTracks();
try {
myPL.save(selcdFile);
} catch (IOException e1) {
JOptionPane.showMessageDialog(mainframe, e1 + "\n\nBitte eine kompatible Datei wählen.", "MusicPlayer Error", JOptionPane.WARNING_MESSAGE);
}
}
};
});
mnItemNewEntry.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
NewEntry myNewEntry = new NewEntry(new JFrame(), "Neuer Eintrag");
myNewEntry.setSize(300, 240);
myNewEntry.setLocationRelativeTo(mainframe);
myNewEntry.setVisible(true);
};
});
类新条目
// FIXME - btnChooseFile
btnChooseFile.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JFileChooser fChoose = new JFileChooser();
FileNameExtensionFilter fExt = new FileNameExtensionFilter("MP3", "mp3"); // FIXME add wave etc.
fChoose.setFileFilter(fExt);
int returnVal = fChoose.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION){
txtFilepath.setText(fChoose.getSelectedFile().getAbsolutePath());
}
};
});
PlayList(包含保存、加载等简单方法)
public class PlayList implements project.model.PlayList{
private List<Track> playList = new LinkedList<>();
private String strDelimiter = ";";
public void setPlayList(List<Track> playList) {
this.playList = playList;
}
JList 的代码,还是让我头疼。
ListModel<PlayList> theModel = new DefaultListModel<PlayList>();
JList<PlayList> myJList = new JList<PlayList>(theModel);
for(int i = 0; i < myPlayList.getTracks().size(); i++){
theModel.addElement(i);
}
JScrollPane myScrollPane = new JScrollPane(myJList);
mainframe.add(myScrollPane);
【问题讨论】:
-
好吧,不要在
actionPerformed方法中创建JList的新实例,而是创建一个实例并在需要时简单地更改ListModel -
“我将添加我的源代码的相关部分。” 如需更好的帮助,请尽快发布minimal reproducible example 或Short, Self Contained, Correct Example。
mainframe.setBounds(100, 100, 450, 300);停止猜测。只需pack()框架(添加组件后)!顺便说一句 - 该数据(每行三个数据)最适合JTable。 -
@MadProgrammer 我是否理解正确,我应该创建一个新类“myJList”来创建一个单一实例并通过不同 actionPerformed 方法的 Getter 和 Setter 方法更改 ListModel?
-
不,在你存在代码(actionPerformed)中,每次调用它时你都在创建一个新的 JList 实例,你不需要这样做。您只需创建一个实例字段,在创建时将其添加到 UI,然后根据需要更改 ListModel
-
感谢您提供的信息和帮助。照你说的去做。