Index: DefaultJTasksStatusList.java
===================================================================
--- DefaultJTasksStatusList.java	(revision 2631)
+++ DefaultJTasksStatusList.java	(revision 2632)
@@ -1,7 +1,7 @@
 /**
  * gvSIG. Desktop Geographic Information System.
  *
- * Copyright (C) 2007-2013 gvSIG Association.
+ * Copyright (C) 2007-2021 gvSIG Association.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,17 +27,21 @@
 import java.awt.Component;
 import java.awt.Dimension;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
+import java.util.EventObject;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Objects;
 
-import javax.swing.BoxLayout;
-import javax.swing.JPanel;
+import javax.swing.JLabel;
 import javax.swing.JScrollPane;
+import javax.swing.JTable;
 import javax.swing.SwingUtilities;
+import javax.swing.event.CellEditorListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
 
 import org.gvsig.tools.observer.Observable;
 import org.gvsig.tools.observer.Observer;
@@ -47,25 +51,27 @@
 import org.gvsig.tools.swing.api.task.TaskStatusSwingManager;
 import org.gvsig.tools.task.TaskStatus;
 import org.gvsig.tools.task.TaskStatusManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Default implementation of the {@link JTasksStatusList}.
  * 
  * @author gvSIG Team
- * @version $Id$
  */
 public class DefaultJTasksStatusList extends JTasksStatusList implements
     Observer {
 
+    public static final Logger LOGGER = LoggerFactory.getLogger(DefaultJTasksStatusList.class);
+    
     private static final long serialVersionUID = 7740032506050392725L;
 
-    private TaskStatusManager manager;
-    private Map<String, JTaskStatus> taskControls;
-    private JPanel listPanel;
+    private final TaskStatusManager manager;
+    private JTable table;
 
+    @SuppressWarnings("LeakingThisInConstructor")
     public DefaultJTasksStatusList(TaskStatusManager manager) {
         this.manager = manager;
-        this.taskControls = new LinkedHashMap<>();
         this.makeUI();
         this.manager.addObserver(this);
     }
@@ -75,72 +81,141 @@
         return this.manager;
     }
 
+    
     private void makeUI() {
         this.setLayout(new BorderLayout());
-
-        listPanel = new JPanel();
-        listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
-        List<JTaskStatus> controlsToAdd = this.getControlsToAdd();
-        for (JTaskStatus taskStatus : controlsToAdd) {
-            listPanel.add(taskStatus);
-        }
-        listPanel.setAlignmentY(Component.TOP_ALIGNMENT);
-        JScrollPane scroller = new JScrollPane(listPanel);
+        TaskStatusSwingManager swingManager = ToolsSwingLocator.getTaskStatusSwingManager();
+        this.table = new JTable();
+        DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
+        TableColumn tableColumn = new TableColumn(
+                0,
+                300,
+                new TableCellRenderer() {
+                    JTaskStatus component = swingManager.createJTaskStatus();
+                    JLabel empty = new JLabel("???");
+                    @Override
+                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+                        if( value instanceof TaskStatus ) {
+                            this.component.bind((TaskStatus) value);
+                            return this.component;
+                        }
+                        this.empty.setText("??? "+Objects.toString(value));
+                        return this.empty;
+                    }
+                },
+                new TableCellEditor() {
+                    JTaskStatus component = swingManager.createJTaskStatus();
+                    JLabel empty = new JLabel("???");
+                    @Override
+                    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+                        if( value instanceof TaskStatus ) {
+                            this.component.bind((TaskStatus) value);
+                            return this.component;
+                        }
+                        this.empty.setText("??? "+Objects.toString(value));
+                        return this.empty;
+                    }
+                    
+                    @Override
+                    public Object getCellEditorValue() {
+                        return this.component.getTaskStatus();
+                    }
+                    
+                    @Override
+                    public boolean isCellEditable(EventObject anEvent) {
+                        return true;
+                    }
+                    
+                    @Override
+                    public boolean shouldSelectCell(EventObject anEvent) {
+                        return false;
+                    }
+                    
+                    @Override
+                    public boolean stopCellEditing() {
+                        return true;
+                    }
+                    
+                    @Override
+                    public void cancelCellEditing() {
+                    }
+                    
+                    @Override
+                    public void addCellEditorListener(CellEditorListener l) {
+                    }
+                    
+                    @Override
+                    public void removeCellEditorListener(CellEditorListener l) {
+                    }
+                }
+        );
+        JTaskStatus taskStatusHeight = swingManager.createJTaskStatus();
+        taskStatusHeight.setTitle("WWWMMMGGGgggqqqjjjttt");
+        taskStatusHeight.message("WWWMMMGGGgggqqqjjjttt");
+        columnModel.addColumn(tableColumn);
+        this.table.setColumnModel(columnModel);
+        this.table.setRowHeight(taskStatusHeight.getPreferredSize().height);
+        this.table.setAutoCreateColumnsFromModel(false);
+        this.table.setTableHeader(null);
+        this.table.setModel(this.createModel());
+        JScrollPane scroller = new JScrollPane(table);
+        
         scroller.setAlignmentY(Component.TOP_ALIGNMENT);
         scroller.setPreferredSize(new Dimension(300, 150));
         this.add(scroller, BorderLayout.CENTER);
     }
 
-    private List<JTaskStatus> getControlsToAdd() {
-        List<JTaskStatus> controlsToAdd = new ArrayList<>();
-        TaskStatusSwingManager manager =
-            ToolsSwingLocator.getTaskStatusSwingManager();
+    private TableModel createModel() {
+        List<TaskStatus> tasks = new ArrayList<>(this.manager.getAll().values());
+        return new AbstractTableModel() {
+            @Override
+            public int getRowCount() {
+                return tasks.size();
+            }
 
-        @SuppressWarnings("unchecked")
-        Map<String, TaskStatus> tasksStatus = this.manager.getAll();
+            @Override
+            public int getColumnCount() {
+                return 1;
+            }
 
-        Iterator<Entry<String, TaskStatus>> taskStatusIterator =
-            tasksStatus.entrySet().iterator();
-        while (taskStatusIterator.hasNext()) {
-            Entry<String, TaskStatus> entry = taskStatusIterator.next();
-            if (this.taskControls.get(entry.getKey()) == null) {
-                JTaskStatus control = manager.createJTaskStatus();
-                control.bind(entry.getValue());
-                controlsToAdd.add(control);
-                this.taskControls.put(entry.getKey(), control);
+            @Override
+            public String getColumnName(int columnIndex) {
+                return null;
             }
-        }
-        return controlsToAdd;
+
+            @Override
+            public Class<?> getColumnClass(int columnIndex) {
+                return TaskStatus.class;
+            }
+
+            @Override
+            public boolean isCellEditable(int rowIndex, int columnIndex) {
+                return true;
+            }
+
+            @Override
+            public Object getValueAt(int rowIndex, int columnIndex) {
+                return tasks.get(rowIndex);
+            }
+
+            @Override
+            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+            }
+        };
     }
-
+    
     @Override
     public void update(final Observable observable, final Object notification) {
         if (!(observable instanceof TaskStatusManager)) {
             return;
         }
         if( !SwingUtilities.isEventDispatchThread() ) {
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    update(observable, notification);
-                }
-            });
+            SwingUtilities.invokeLater(() -> { update(observable, notification); });
             return;
         }
-        if (notification == null || this.manager.isEmpty() ) {
-            // remove task
-            listPanel.removeAll();
-            this.taskControls.clear();
-            listPanel.revalidate();
+        if (this.table.isEditing()) {
+             this.table.editingCanceled(null);
         }
-        List<JTaskStatus> controlsToAdd = this.getControlsToAdd();
-        if( !controlsToAdd.isEmpty() ) {
-            listPanel.removeAll();
-            for (JTaskStatus taskStatus : this.taskControls.values()) {
-                taskStatus.setAlignmentY(Component.BOTTOM_ALIGNMENT);
-                listPanel.add(taskStatus);
-            }
-            listPanel.revalidate();
-        }
+        this.table.setModel(this.createModel());
     }
 }
