Обновление компонентов JList

У меня есть JProgressBar на JPanel как компоненты JList. Компоненты JList должны обновлять JProgressBar каждые две секунды. Но проблема в том, что я не знаю, как передать значение прогресса в JProgressBar. вот мой код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class download {
    download(){}
}
class myPanelListCellRenderer extends DefaultListCellRenderer{
    private static final long serialVersionUID = 1L;
    private JPanel downloadPanel,labelStack;
    private JProgressBar downloadProgress;
    private JLabel fileTypeIconLabel,fileNameLabel,downloadInfoLabel,freeLabel;
    public myPanelListCellRenderer(){
        setLayout(null);
        downloadPanel=new JPanel(new BorderLayout(10,20));
        labelStack=new JPanel(new GridLayout(0,1,2,2));
        downloadProgress=new JProgressBar() {
            @Override
            public Dimension getPreferredSize() {
                Dimension d = super.getPreferredSize();
                return new Dimension(400,d.height);
            }
        };
        fileTypeIconLabel=new JLabel("test", SwingConstants.CENTER);
        fileNameLabel=new JLabel("fileNameLabel", SwingConstants.CENTER);
        downloadInfoLabel=new JLabel("downloadInfoLabel", SwingConstants.CENTER);
        freeLabel=new JLabel("freeLabel", SwingConstants.CENTER);
        fileTypeIconLabel.setFont(fileTypeIconLabel.getFont().deriveFont(60f));
        labelStack.add(fileNameLabel);
        labelStack.add(downloadInfoLabel);
        labelStack.add(downloadProgress);
        labelStack.add(freeLabel);  
        labelStack.setOpaque(false);
        downloadPanel.add(fileTypeIconLabel,BorderLayout.LINE_START);
        downloadPanel.add(labelStack,BorderLayout.CENTER);
    }
    @Override
    public Component getListCellRendererComponent(JList<?> list,Object value,int index,boolean isSelected,boolean cellHasFocus) {
        JLabel l = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        downloadPanel.setBackground(l.getBackground());
        fileTypeIconLabel.setText("" + (index + 1));
        return downloadPanel;
    }
}

public class JListPanel implements ActionListener{
    private JPanel btnPanel;
    private JButton jbtAdd,jbtDelete;
    private JFrame jf;
    private download dl;
    DefaultListModel<download> myListModel;
    JList<download>myList;
    public JListPanel(){
        myListModel=new DefaultListModel<download>();
        myList=new JList<download>(myListModel);
        myList.setCellRenderer(new myPanelListCellRenderer());
        myList.setVisibleRowCount(8);
        btnPanel=new JPanel();
        jbtAdd=new JButton("addJpanel");
        jbtDelete=new JButton("delJpanel");
        btnPanel.setLayout(new FlowLayout(FlowLayout.LEFT,1,1));
        btnPanel.add(jbtAdd);
        btnPanel.add(jbtDelete);
        jf=new JFrame("hello");
        for(int i=0;i<6;i++){
            dl=new download();
            myListModel.add(0, dl);
        }
        jf.setLocationByPlatform(true);
        jf.add(btnPanel,BorderLayout.NORTH);
        jf.add(new JScrollPane(myList),BorderLayout.CENTER);
        jbtAdd.addActionListener(this);
        jbtDelete.addActionListener(this);
        jf.pack();
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
    public static void main(String args[]){
        new JListPanel();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if(e.getSource()==jbtAdd){
            addMyPanel();
        }
        else if(e.getSource()==jbtDelete){
            delMyPanel();
        }
    }
    public void addMyPanel(){
        myListModel.add(0,new download());
    }
    public void delMyPanel(){
        int index = myList.getSelectedIndex();
        if (index < 0) {
            JOptionPane.showMessageDialog(
                    myList,
                    "Select a download to delete!",
                    "Select Download",
                    JOptionPane.ERROR_MESSAGE);
        } else {
            myListModel.removeElementAt(index);
        }
    }
}

person icook    schedule 11.02.2014    source источник


Ответы (1)


Вместо того, чтобы передавать значение прогресса в JProgressBar напрямую, позвольте панели прослушивать изменения от любого процесса, обновляющего модель данных списка. SwingWorker, см. здесь, особенно удобен для этого, так как setProgress() воркера автоматически уведомляет слушателей.

person trashgod    schedule 11.02.2014
comment
Проблема в том, что JProgressBar находится в ListCellRenderer - person icook; 11.02.2014
comment
Ваш ListModel должен включать List<DownloadWorker>, где DownloadWorker расширяет SwingWorker. - person trashgod; 11.02.2014
comment
Вы можете ошибиться в моем вопросе, ключевым моментом является изменение значения JProgressBar во время выполнения. Параллелизм не является моим ключевым моментом прямо сейчас. JProgressBar находится в Renderer, но я не знаю, как изменить значение JProgressBar в JList Renderer - person icook; 13.02.2014
comment
JProgressBar должен отслеживать изменения; для этого удобен PropertyChangeListener; SwingWorker срабатывает подходящий PropertyChangeEvent; вы можете управлять своими событиями, но рано или поздно вам придется решать проблему параллелизма; Голосую за раньше. - person trashgod; 13.02.2014