SwingWorker и JComboBox - PullRequest
       23

SwingWorker и JComboBox

2 голосов
/ 18 октября 2011

У меня есть приложение с записями овец на JTable.Овец можно сделать потомками других овец, выбрав идентификатор в редакторе JComboBox столбца родительского идентификатора в JTable.Для этого родительский идентификатор JComboBox должен отсканировать идентификаторы других овец, исключить некоторые из них, как ожидалось, и показать их вместе в popup.

Это не длительный процесс;но, по моему мнению, в будущем, если количество овец возрастет, это может привести к тому, что GUI перестанет отвечать на запросы.Вот почему я хотел использовать SwingWorker для процесса сканирования.Было бы хорошо, если бы он сканировал идентификаторы в методе doInBackground и возвращал эти идентификаторы в метод done.

Так что JComboBox покажет любые возможные родительские идентификаторы.Хотя метод doInBackground хорошо работает в методе done, когда я добавляю число к JComboBox, я предполагаю, что popup становится невидимым.

Из-за этого всякий раз, когда я щелкаю ячейку родительского идентификатора, JComboBox pupup появляется и быстро исчезает, не показывая никаких родительских идентификаторов.Но это должно показать родительские идентификаторы.Есть ли способ сделать это?

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sheepfarm.tools;

import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Vector;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.TableCellEditor;
import org.joda.time.Interval;
import java.util.Date;
import javax.swing.DefaultComboBoxModel;
import javax.swing.SwingWorker;

/**
 *
 * @author Personal Computer
 */
public class JParentIDCellEditor extends AbstractCellEditor implements TableCellEditor {

    private JComboBox jComboBox = new JComboBox();
    private boolean cellEditingStopped = false;

    @Override
    public Object getCellEditorValue() {
        return jComboBox.getSelectedItem();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(Integer.parseInt(value.toString()));

        jComboBox = new JComboBox();
        ParentIDCellWorker worker = new ParentIDCellWorker(table, jComboBox, row, value);
        worker.execute();

        jComboBox.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    fireEditingStopped();
                }
            }
        });
        jComboBox.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                cellEditingStopped = false;
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                cellEditingStopped = true;
                fireEditingCanceled();

            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        });
        return jComboBox;
    }

    public class ParentIDCellWorker extends SwingWorker<Vector, Vector> {

        private JTable table;
        private JComboBox jComboBox;
        private int row;
        private Object value;

        public ParentIDCellWorker(JTable table, JComboBox jComboBox, int row, Object value) {
            this.table = table;
            this.jComboBox = jComboBox;
            this.row = row;
            this.value = value;
        }

        @Override
        protected Vector doInBackground() throws Exception {
            Vector vector = new Vector();
            vector.add(0);
            for (int i = 0; i < table.getRowCount(); i++) {
                try {
                    Interval interval = new Interval(((Date) table.getValueAt(i, 2)).getTime(), new Date().getTime());
                    interval = new Interval(((Date) table.getValueAt(i, 2)).getTime(), ((Date) table.getValueAt(row, 2)).getTime());
                    String gender = table.getValueAt(i, 3).toString();
                    if (!vector.contains(table.getValueAt(i, 0)) && gender.equals("Sheep")) {
                        vector.add(table.getValueAt(i, 0));
                    }
                } catch (IllegalArgumentException exp) {
                }
            }
            String[] rowsToRemove = getChildren(Integer.parseInt(table.getValueAt(row, 0).toString()), table).split("-");
            for (int i = 0; i < rowsToRemove.length; i++) {
                vector.removeElement((Object) (Integer.parseInt(rowsToRemove[i])));
            }
            return vector;
        }

        public String getChildren(int id, JTable jTable) {
            String id_map = "";
            for (int i = 0; i < jTable.getRowCount(); i++) {
                if (Integer.parseInt(jTable.getValueAt(i, 1).toString()) == id) {
                    id_map += getChildren(Integer.parseInt(jTable.getValueAt(i, 0).toString()), jTable);
                }
            }
            return id + "-" + id_map;
        }

        @Override
        protected void done() {
            try {
                for (Object i : get()) {
                    jComboBox.addItem(i);

                }
                jComboBox.setSelectedItem(value);
            } catch (InterruptedException ex) {
                Logger.getLogger(JParentIDCellEditor.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ExecutionException ex) {
                Logger.getLogger(JParentIDCellEditor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public boolean stopCellEditing() {
        return cellEditingStopped;
    }
}

1 Ответ

1 голос
/ 18 октября 2011

Я не уверен, но ждать, пока пользователь нажмет на всплывающее окно, может быть слишком поздно. Вместо этого вы можете запустить SwingWorker для создания List<ComboBoxModel> до вызова getTableCellEditorComponent, возможно, когда вы создаете модель родительской таблицы. Таким образом, ваш метод getTableCellEditorComponent может просто установить правильную модель для этой строки. Я полагаю, вам нужно будет обновлять List в редакторе, но это кажется намного проще.

...