使用swing worker线程更新swing组件

uurv41yg  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(233)

目前,我正在尝试使用swingworker构建swing应用程序,以不断更新面板。
我在这里试图完成的是从数据库中加载数据,对于每个数据,都将在面板中以图标的形式发布。图标的颜色基于严重性字段的值。例如:
示例数据在这张图片中,我有12个对象的数据\u id a001。doinbackground()方法中的函数将循环12次,并调用publish()函数在面板中显示图标。基于每个对象id的严重性字段的最高值的图标颜色。
在doinbackground()方法中,我使用了两个结果不同的方法:
没有thread.sleep()函数console resultui result
使用thread.sleep()函数10毫秒控制台结果
使用thread.sleep()函数20毫秒控制台结果
不使用thread.sleep()函数的程序将只打印控制台中的最后一个图标,就好像publish()函数只执行一次一样。
使用thread.sleep()函数的程序将打印出控制台中的所有图标,但这取决于我们在thread.sleep()函数中使用的值。值越低,控制台中可能无法打印某些图标。
数据库中的所有图标都完全显示在ui面板中,但颜色不一致,这取决于thread.sleep()函数的使用和延迟所用的时间。
就我个人而言,我不想使用thread.sleep()函数,因为数据越大,延迟就越大。
我遇到的问题可能是由于我的程序逻辑错误,因为这是我第一次使用swingworker。
如果有人想试试的话,我也会把我所有的代码都放在这个问题上。https://drive.google.com/file/d/1fs1r72hwezomwvy2ff9ujtl3eud-4ois/view?usp=sharing
处理数据在doinbackground()方法中完成,然后将值传递给process()方法以更新面板。
以下是swingworker线程的代码:

package com.akbar.thread;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;

import javax.persistence.TypedQuery;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import com.akbar.datastructure.TerminalData;
import com.akbar.sources.RoundImageButton;

public class MonitorThread extends SwingWorker<Void, LinkedHashMap<String, String>> {
    private static final String GREEN = "/com/akbar/resources/green48.png";
    private static final String YELLOW = "/com/akbar/resources/yellow48.png";
    private static final String RED = "/com/akbar/resources/red48.png";
    private static final String BLACK = "/com/akbar/resources/black48.png";
    private static final int SEVERITY_LEVEL = 0;

    private boolean print = false;

    private int newCount = 0;
    private int updCount = 0;
    private int terminalSev;
    private int terminalCount = 0;

    private String lastTerminal;
    private String terminalId;
    private String termDetail;
    private String terminalStatus;

    private JPanel terminalPanel;
    private JScrollPane terminalScroll;

    private TerminalData terminalData;

    private TreeMap<String, JButton> updatedTerminal;

    private LinkedHashMap<String, LinkedHashMap<String, TerminalData>> terminalList;
    private LinkedHashMap<String, TerminalData> terminalDetail;
    private LinkedHashMap<String, String> zCommand;

    private SessionFactory factory = generateSessionFactory();
    private Session session;
    private Transaction tx;
    private TypedQuery<TerminalData> query;

    public MonitorThread(JPanel terminalPanel, JScrollPane terminalScroll) {
        this.terminalPanel = terminalPanel;
        this.terminalScroll = terminalScroll;

        updatedTerminal = new TreeMap<String, JButton>();
        terminalDetail = new LinkedHashMap<String, TerminalData>();
        terminalList = new LinkedHashMap<String, LinkedHashMap<String, TerminalData>>();
        zCommand = new LinkedHashMap<String, String>();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Void doInBackground() throws Exception {
        try {
            session = factory.openSession();
            tx = (Transaction) session.beginTransaction();
            query = session.createQuery("FROM TerminalData", TerminalData.class);
            List<TerminalData> result = query.getResultList();

            if (result.size() > 0) {
                for (int i = 0; i < result.size(); i++) {
                    terminalData = (TerminalData)result.get(i);
                    terminalSev = 0;
                    termDetail = terminalData.getObjectDetail();
                    terminalId = terminalData.getObjectId();
                    if (terminalList.get(terminalId) != null) {
                        terminalDetail.put(termDetail, terminalData);
                        terminalList.put(terminalId, (LinkedHashMap<String, TerminalData>)terminalDetail.clone());
                        zCommand.put("UPD", terminalId);
                        publish(zCommand);
//                      if (!(terminalId).equals(lastTerminal)) {
//                          lastTerminal = terminalId;
//                          updCount++;
//                      }
                    } else {
//                      if("125006".equals(terminalId)) {
//                          System.out.println("test");
//                      }
                        terminalDetail = new LinkedHashMap<String, TerminalData>();
                        terminalDetail.put(termDetail, terminalData);
                        terminalList.put(terminalId, (LinkedHashMap<String, TerminalData>)terminalDetail.clone());
                        zCommand.put("NEW", terminalId);
                        publish(zCommand);
//                      newCount++;
                    }
                    Thread.sleep(20);
                }
//              System.out.println(String.format("New count: [%s], Update count: [%s]", newCount, updCount));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return null;
    }

    @Override
    protected void process(List<LinkedHashMap<String, String>> chunks) {
        LinkedHashMap<String, String> test = chunks.get(chunks.size() - 1);
        List<String> commandKey = new ArrayList<String>(test.keySet());
        LinkedHashMap<String, TerminalData> tempDetail;
        List<String> terminalKey;
        List<String> detailKeys;

        TerminalData tempData = new TerminalData();

        int sev = 0;

        String color;
        String command = commandKey.get(0);
        String terminal = test.get(command);
        zCommand.remove(command);

//      if (!(terminal.equals(lastTerminal))) {
//          lastTerminal = terminal;
//          System.out.println(String.format("Terminal [%s], count [%s]", terminal, ++terminalCount));
//      }

        switch (command) {
        case "NEW":
            System.out.println(String.format("Newly Terminal [%s], count [%s]", terminal, ++terminalCount));
            lastTerminal = terminal;
            updatedTerminal = new TreeMap<String, JButton>();
            terminalKey = new ArrayList<String>(terminalList.keySet());
            tempDetail = new LinkedHashMap<String, TerminalData>();
            for (int i = 0; i < terminalKey.size(); i++) {
                tempDetail = terminalList.get(terminalKey.get(i));
                detailKeys = new ArrayList<String>(tempDetail.keySet());
                sev = 0;
                for (int j = 0; j < detailKeys.size(); j++) {
                    tempData = tempDetail.get(detailKeys.get(j));
                    int tempSev = Integer.parseInt(tempData.getSeverity());
                    if (tempSev > sev) {
                        sev = tempSev;
                    }
                }
                color = terminalKey.get(i).equals(terminal) ? BLACK : getIconColor(sev);
                updatedTerminal.put(tempData.getObjectId(), new RoundImageButton(tempData.getObjectId(), color, tempData.getObjectId(), new Dimension(130, 48)));
            }
            updatePanel(updatedTerminal);
            break;

        case "UPD":
//          System.out.println(String.format("Updated Terminal [%s], count [%s]", terminal, terminalCount++));
//          if (!(terminal.equals(lastTerminal))) {
//              lastTerminal = terminal;
//              System.out.println(String.format("Terminal [%s], count [%s]", terminal, terminalCount++));
//          }
            sev = 0;
            tempDetail = new LinkedHashMap<String, TerminalData>();
            Component[] comps = terminalPanel.getComponents();
            if (comps.length > 0) {
                for (Component comp : comps) {
                    if (comp instanceof JButton) {
                        if (terminal.equals(comp.getName())) {
                            tempDetail = new LinkedHashMap<String, TerminalData>();
                            tempDetail = terminalList.get(terminal);
                            detailKeys = new ArrayList<String>(tempDetail.keySet());
                            for (int j = 0; j < detailKeys.size(); j++) {
                                tempData = tempDetail.get(detailKeys.get(j));
                                int tempSev = Integer.parseInt(tempData.getSeverity());
                                if (tempSev > sev) {
                                    sev = tempSev;
                                }
//                              if ("125006".equals(terminal)) {
//                                  System.out.println(String.format("Terminal [%s], object detail [%s], severity [%s]", terminal, tempData.getObjectDetail(), sev));
//                              }
                            }
//                          System.out.println(String.format("Terminal [%s], object detail [%s], severity [%s]", terminal, tempData.getObjectDetail(), sev));
                            color = getIconColor(sev);
                            ((AbstractButton) comp).setIcon(new ImageIcon(getClass().getResource(color)));
                            break;
                        }
                    }
                }
            }
            break;

        case "RMV":
            break;

        default:
            break;
        }
    }

    @Override
    protected void done() {
        super.done();
    }

    private void updateComponent(String terminal) {
        LinkedHashMap<String, TerminalData> temp = terminalList.get(terminal);
        List<String> key = new ArrayList<String>(temp.keySet());
        TerminalData data;
        int highestSeverity = 0;
        int severity = 0;
        for (int i = 0; i < key.size(); i++) {
            data = temp.get(key.get(i));
            severity = Integer.parseInt(data.getSeverity());
            if (severity > highestSeverity) {
                highestSeverity = severity;
            }
        }

        if (highestSeverity > SEVERITY_LEVEL) {

        }
    }

    private String getIconColor(int severity) {
        if (severity >= 0 && severity <= 10) {
            return GREEN;
        } else if (severity > 10 && severity <= 30) {
            return YELLOW;
        } else if (severity > 30 && severity <= 40) {
            return RED;
        }
        return BLACK;
    }

    private TreeMap<String, JButton> retrieveDisplayedTerminal() {
        TreeMap<String, JButton> temp = new TreeMap<String, JButton>();
        Component[] comps = terminalPanel.getComponents();
        if (comps.length > 0) {
            for (Component comp : comps) {
                if (comp instanceof JButton) {
                    temp.put(comp.getName(), (JButton) comp);
                }
            }
        }
        return temp;
    }

    private boolean checkCurrentTerminal(String terminal) {
        Component[] comps = terminalPanel.getComponents();
        if (comps.length > 0) {
            for (Component comp : comps) {
                if (comp instanceof JButton) {
                    if ((comp.getName()).equals(terminal)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void updatePanel(TreeMap<String, JButton> terminals) {
        final int MAX_COLUMN = 14;
        JButton button;
        Component[] components = terminalPanel.getComponents();
        if (components.length > 0) {
            for (Component comp : components) {
                if (comp instanceof JButton) {
                    terminalPanel.remove(comp);
                    terminalPanel.validate();
                    terminalPanel.repaint();
                    terminalScroll.validate();
                    terminalScroll.repaint();
                }
            }
        }

        GridBagConstraints gc = new GridBagConstraints();
        gc.insets = new Insets(0, 5, 5, 0);

        int currentLine = 1;
        int size = terminals.size();
        int totalLine = size / MAX_COLUMN;
        if (totalLine == 0) {
            totalLine += 1;
        } else {
            int temp = size % MAX_COLUMN;
            if (temp > 0) {
                totalLine += 1;
            }
        }

        int xCount = -1;
        int yCount = 0;

        List<String> keyList = new ArrayList<String>(terminals.keySet());
        for (int i = 0; i < size; i++) {
            if (terminals.get(keyList.get(i)) instanceof JButton) {
                button = terminals.get(keyList.get(i));
                if (xCount == MAX_COLUMN - 1) {
                    currentLine++;
                    yCount++;
                    xCount = 0;
                    gc.gridx = xCount;
                    gc.gridy = yCount;
                    gc.weightx = 0.0;
                    gc.weighty = (currentLine == totalLine ? 50.0 : 0.1);
                    gc.anchor = GridBagConstraints.NORTHWEST;
                    gc.fill = GridBagConstraints.HORIZONTAL;
                } else {
                    xCount++;
                    gc.gridx = xCount;
                    gc.gridy = yCount;
                    gc.weightx = 0.0;
                    gc.weighty = 0.1;
                    gc.anchor = GridBagConstraints.NORTH;
                    gc.fill = GridBagConstraints.NONE;
                }
                terminalPanel.add(button, gc);
            }
        }
        terminalPanel.validate();
        terminalPanel.repaint();
        terminalScroll.validate();
        terminalScroll.repaint();
    }

    private SessionFactory generateSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

提前谢谢。

ny6fqffe

ny6fqffe1#

如果频繁调用“publish”方法,则在edt上调用“process”之前,值可能会累积。
这就是“process”方法接收要发布的对象列表的原因。代码负责遍历列表并使用列表中的所有数据更新gui。
因此,假设您的“doinbackground”逻辑使用for循环,我建议您累积多个值,并且您的“process”方法只是众多方法中的一个。
当您使用thread.sleep(…)时,您限制了可能合并为单个“进程”事件的对象的数量。
因此,解决方案是确保“process”方法遍历列表中的所有对象。

相关问题