Java Swing - Динамическое изменение JList с помощью TransferHandler

У меня есть небольшое приложение Java swingui, где я показываю JList, и пользователь может вырезать, копировать, вставлять и сортировать список.

Я использую custom TransferHandler, чтобы разрешить перетаскивание в этом Jlist. Вот код в построении JList, он в основном строит его из ArrayList. "lstScripts" - это JList.

ListTransferHandler lh = new ListTransferHandler();
...
 DefaultListModel listModelScripts = new DefaultListModel();
 for(Script s : scripts) {
 listModelScripts.addElement(s.getName());
 }
 this.lstScripts = new JList(listModelScripts);
 this.lstScripts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 this.lstScripts.addListSelectionListener(this);
 JScrollPane sp = new JScrollPane(this.lstScripts);
 sp.setPreferredSize(new Dimension(400,100));
 this.lstScripts.setDragEnabled(true);
 this.lstScripts.setTransferHandler(lh);
 this.lstScripts.setDropMode(DropMode.ON_OR_INSERT);
 setMappings(this.lstScripts);
...

В моем классе TransferHandler у меня есть процедура importData, работающая так, чтобы она обрабатывала копию/вставку/вырезание/сортировку.

public boolean importData(TransferHandler.TransferSupport info) {
 String scriptname = null; // The script name on the list

 //If we can't handle the import, bail now.
 if (!canImport(info)) {
 return false;
 }

 JList list = (JList)info.getComponent();
 DefaultListModel model = (DefaultListModel)list.getModel();
 //Fetch the scriptname -- bail if this fails
 try {
 scriptname = (String)info.getTransferable().getTransferData(DataFlavor.stringFlavor);
 } catch (UnsupportedFlavorException ufe) {
 System.out.println("importData: unsupported data flavor");
 return false;
 } catch (IOException ioe) {
 System.out.println("importData: I/O exception");
 return false;
 }

 if (info.isDrop()) { //This is a drop
 JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
 int index = dl.getIndex();
 model.add(index, scriptname);
 return true;
 } else { //This is a paste
 int index = list.getSelectedIndex();
 // if there is a valid selection,
 // insert scriptname after the selection
 if (index >= 0) {
 model.add(list.getSelectedIndex()+1, scriptname);
 // else append to the end of the list
 } else {
 model.addElement(scriptname);
 }
 return true;
 }
}

Таким образом, до сих пор все работает отлично, насколько GUI. Но моя проблема в том, что мне нужно, чтобы исходный JList "lstScripts" автоматически обновлялся с изменениями пользовательского интерфейса. Например, если пользователь сокращает или переупорядочивает список, я хочу, чтобы он отображался в "lstScripts".

Я не вижу, как установить эту связь между TransferHandler и оригинальным GUI-контроллером, где находится "lstScripts".

1 ответ

@kleopatra - ты помог мне! извините, я не понимал, как работает модель.

Поэтому в контроллере я создаю JList "lstScripts" и добавляю его в свою панель (это первый блок моего кода выше).

pnlScripts.add(lstScripts, BorderLayout.WEST);

И, как показал мой код выше, у listScripts JList был установлен собственный настраиваемый механизм переноса:

this.lstScripts.setTransferHandler(lh);

Таким образом, передатчик выполняет все действия пользователя dnd (drag and drop). В контроллере я могу получить обновленный список, выполнив:

DefaultListModel model = (DefaultListModel)lstScripts.getModel();
 for (int i = 0; i < model.getSize(); i++){
 scriptnames += model.getElementAt(i).toString() + ",";
 }

В переменной scriptnames String теперь содержится обновленный список.

Благодарю!

licensed under cc by-sa 3.0 with attribution.