gpt4 book ai didi

java - SwingWorker 更新多个面板中的多个组合框

转载 作者:行者123 更新时间:2023-12-04 05:35:17 27 4
gpt4 key购买 nike

我有一个小 gui 程序,它在启动时从 Excel 文件中读取数据,其中一些数据需要转到相关的组合框。我知道如何通过为每个组合框使用单独的 SwingWorker 来做到这一点:

public class ExcelReader extends SwingWorker<DefaultComboBoxModel, String> {

private final DefaultComboBoxModel model;

// Constructor called from a panel that has a combobox
public ExcelReader(DefaultComboBoxModel model) {
this.model = model;
}

@Override
protected DefaultComboBoxModel doInBackground() throws Exception {

///// code to read data from Excel file
///// publish(someString) used here

return model;
}

@Override
protected void process(List<String> chunks) {

for(String row : chunks)
model.addElement(row);
}
}

这工作正常,但我如何使用一个 SwingWorker 类来填充多个组合框?这样做的好处是只需读取一次文件。每当发现需要进入组合框的内容时,相关组合框就会更新,然后程序继续读取下一行,直到文件结束。

因此,我尝试在我想在一个 JPanel 中更新 2 个组合框的情况下使用 boolean 标志,但这似乎没有按预期工作。这也不是一个好的解决方案,因为将来我计划在多个面板中更新 2 个以上的组合框。
public class ExcelReader extends SwingWorker<DefaultComboBoxModel[], String> {

private boolean isData1 = false;
private final DefaultComboBoxModel model1;
private final DefaultComboBoxModel model2;
private final DefaultComboBoxModel[] models = new DefaultComboBoxModel[2];

// Constructor called from a panel that has 2 comboboxes
public ExcelReader(DefaultComboBoxModel model1, DefaultComboBoxModel model2) {
this.model1 = model1;
this.model2 = model2;
}

@Override
protected DefaultComboBoxModel[] doInBackground() throws Exception {

///// some code .....
///// some code .....

// If data that needs to go to combobox1 is found
if (someExpression)
isData1 = true;

publish(someString);

///// some code .....
///// some code .....

models[0] = model1;
models[1] = model2;

return models;
}

@Override
protected void process(List<String> chunks) {

for (String row : chunks) {
if (isData1) {
model1.addElement(row);
isData1 = false;
}
else
model2.addElement(row);

}
}

那么如何只使用一个 SwingWorker 来填充多个组合框(可能包含在不同的面板中)?

顺便说一下,对于上述示例,我从我的面板之一(扩展 JPanel 的类)调用 ExcelReader。在第一种情况下,调用 worker 的面板只有一个组合框,第二个有 2 个。虽然第一个示例工作正常,但这是更新 gui 中组合框的正确方法还是应该从其他地方调用 worker ?

最佳答案

  • 将您的模型映射到逻辑名称,以便您可以将 Excel 中的数据附加到 UI 的逻辑部分。
  • 将您想与之交互的 UI 元素(在本例中为模型)传递给工作人员
  • 尽快离开 UI 线程(在本例中为操作)并让 SwingWorker为您同步 UI 更新。
  • SwingWorker为您批量更新,同时将它们映射到 UI 中的逻辑功能。

  • 代码:
    import java.awt.event.ActionEvent;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    import javax.swing.AbstractAction;
    import javax.swing.BoxLayout;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingWorker;

    public class TestPanel extends JPanel {

    private TestPanel() {
    super();
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

    Map<String, DefaultComboBoxModel> map = new HashMap<String, DefaultComboBoxModel>();
    for (int i = 0; i < 5; i++) {
    JComboBox combo = new JComboBox();
    add(combo);
    map.put("combo" + i, (DefaultComboBoxModel) combo.getModel());
    }

    add(new JButton(new AbstractAction("fill me") {

    @Override
    public void actionPerformed(ActionEvent e) {
    new MyWorker(map).run();
    }
    }));

    }

    private class MyWorker extends SwingWorker<Void, String[]> {

    private final Map<String, DefaultComboBoxModel> map;

    public MyWorker(Map<String, DefaultComboBoxModel> map) {
    this.map = map;
    }

    @Override
    protected Void doInBackground() throws Exception {
    for (int i = 0; i < 20; i++) {
    String[] cell = new String[2];
    cell[0] = "combo" + i % 5;
    cell[1] = "value " + i;
    publish(cell);
    }
    return null;
    }

    @Override
    protected void process(List<String[]> chunks) {
    for (String[] chunk : chunks) {
    map.get(chunk[0]).addElement(chunk[1]);
    }
    }

    };

    /**
    * Create the GUI and show it. For thread safety,
    * this method should be invoked from the
    * event-dispatching thread.
    */
    private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("SwingWorker");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new TestPanel();
    frame.setContentPane(panel);

    // Display the window.
    frame.setSize(200, 300);
    frame.setVisible(true);
    }

    public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
    createAndShowGUI();
    }
    });
    }
    }

    关于java - SwingWorker 更新多个面板中的多个组合框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12028016/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com