在动态添加许多元素后,自定义Jlist开始滞后

时间:2016-11-02 18:51:49

标签: java swing jlist lag populate

我制作了一个自定义ListModel,自定义CellRenderer来填充自定义对象JList。每个单元格包含两个图像和三个字符串。这个JList由并发中的三个线程动态填充,但首先我测试它是通过按一个按钮逐个添加对象。将对象添加到列表的方法作为链接到该按钮的ActionListener调用。

问题在于,当我的列表中显示许多对象时,我的程序开始滞后。然后我的问题是:什么是动态填充JList并使其成为"滞后"?

的最佳方式

Adding objects lagScroll lag

主要课程:

public class Main extends JFrame{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    JFrame main = new JFrame();
    @SuppressWarnings("rawtypes")
    JList tradesList = new JList();
    TradesListModel lm = new TradesListModel();


    @SuppressWarnings("unchecked")
    public Main(){
        GUI();
        tradesList.setCellRenderer(new TradeRenderer());
        tradesList.setModel(lm);
    }

    public void GUI(){

    main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main.setMinimumSize(new Dimension(450,700));
    main.setLocationRelativeTo(null);
    Container pane = main.getContentPane();
    pane.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.insets = new Insets(5, 5, 5, 5);
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.weightx = 1;

    // BUTTONS PANEL
    JPanel buttonsPanel = new JPanel();
    buttonsPanel.setLayout(new GridBagLayout());

    gbc.gridx = 0;
    gbc.gridy = 0;
    JButton startButton = new JButton("Start");
    startButton.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            addTrade();
        }

    });
    buttonsPanel.add(startButton, gbc);

    gbc.gridx++;
    JButton stopButton = new JButton("Stop");
    stopButton.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            lm.clear();
        }

    });
    buttonsPanel.add(stopButton, gbc);
    // LIST PANEL
        JPanel listPanel = new JPanel();
        listPanel.setLayout(new GridBagLayout());
        listPanel.setBorder(BorderFactory.createTitledBorder("Trades List"));

        JScrollPane scrollList = new JScrollPane(tradesList);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weighty = 1;
        listPanel.add(scrollList, gbc);

        GridBagConstraints mc = new GridBagConstraints();
        mc.insets = new Insets(5,5,5,5);
        mc.fill = GridBagConstraints.BOTH;

        mc.weightx = 1;
        mc.gridx = 0;
        mc.gridy = 0;
        pane.add(buttonsPanel, mc);
        mc.gridy++;
        mc.weighty = 1;
        pane.add(listPanel, mc);

        main.setVisible(true);
    }

public void addTrade(){
    lm.add(new Trade("userr", "Platform", "#", "Noteeeeeessss", "Site", 999));;
}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
            | UnsupportedLookAndFeelException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    new Main();
}

TradesListModel类:

package window;

import java.util.ArrayList;

import javax.swing.AbstractListModel;

import main.Trade;

public class TradesListModel extends AbstractListModel<Object>{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private ArrayList<Trade> trades;

    public TradesListModel(){
        trades = new ArrayList<Trade>();
    }

    public void add(Trade trade){
        trades.add(trade);
        this.fireContentsChanged(this, 0, trades.size());
    }

    public void remove(int index){
        trades.remove(index);
    }

    public void clear(){
        trades.clear();
        this.fireIntervalRemoved(this, 0, trades.size());
    }

    @Override
    public int getSize() {
        return trades.size();
    }

    @Override
    public Object getElementAt(int index) {
        return trades.get(index);
    }

}

TradeRenderer类:

package window;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;

import main.Trade;

    public class TradeRenderer extends JPanel implements ListCellRenderer<Object>{

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        private GridBagConstraints gbc;

        public TradeRenderer(){
            this.setLayout(new GridBagLayout());
            gbc = new GridBagConstraints();
        }

        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus){
            Trade trade = (Trade) value;


            JLabel haveLabel = new JLabel(trade.getUsername());
            JLabel wantLabel = new JLabel(trade.getNotes());

            gbc.gridx = 0;
            gbc.gridy = 0;
            this.add(haveLabel, gbc);

            gbc.gridy++;
            this.add(wantLabel, gbc);

            setEnabled(true);

            return this;
        }

    }

贸易类:

package main;

import java.text.SimpleDateFormat;
import java.util.ArrayList;

public class Trade {

    private String username;
    private String platform;
    private String url;
    private ArrayList<Item> have;
    private ArrayList<Item> want;
    private String notes;
    private String site;
    private long time;

    public Trade(String username, String platform, String url, String notes, String site, long time){
        this.username=username;
        this.platform=platform;
        this.url=url;
        this.notes=notes;
        this.site=site;
        this.time=time;
        have = new ArrayList<Item>();
        want = new ArrayList<Item>();
    }

    public void addHave(Item i){
        have.add(i);
    }

    public void addWant(Item i){
        want.add(i);
    }

    public String getUsername(){
        return username;
    }

    public String getPlatform(){
        return platform;
    }

    public String getUrl(){
        return url;
    }

    public String getNotes(){
        return notes;
    }

EDIT1:我尝试使用SwingWorker运行我的应用程序,但它没有改善延迟,并且随着许多新的Trade对象被添加到JList并显示,GUI开始滞后。 这是SwingWorker的实现:

private void start(){
    SwingWorker<Boolean, Trade> worker = new SwingWorker<Boolean, Trade>(){

        @Override
        protected Boolean doInBackground() throws Exception {
            for(int i=0; i<30; i++){
                publish();
                System.out.println("Trade added.");
            }
            return true;
        }

        @Override
        protected void process(List<Trade> chunks) {
            lm.add(new Trade("username", "platform", "#", "Noteeeeeessss", "Site", 999));
        }

    };

    worker.execute();
}

该应用程序由这个新的主类启动:

package window;

import javax.swing.SwingUtilities;

public class App {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                new MainFrame();
            }

        });
    }

}

0 个答案:

没有答案