UI: add row numbers, create proper status and error messages
authorAlexander Marchuk <Alexander.Marchuk@jetbrains.com>
Thu, 18 Sep 2014 10:37:38 +0000 (14:37 +0400)
committerAlexander Marchuk <Alexander.Marchuk@jetbrains.com>
Thu, 18 Sep 2014 10:37:38 +0000 (14:37 +0400)
python/src/com/jetbrains/python/actions/view/array/ArrayTableForm.form
python/src/com/jetbrains/python/actions/view/array/ArrayTableForm.java
python/src/com/jetbrains/python/actions/view/array/Numpy2DArraySlice.java
python/src/com/jetbrains/python/actions/view/array/NumpyArrayValueProvider.java
python/src/com/jetbrains/python/actions/view/array/PyViewArrayAction.java
python/src/com/jetbrains/python/actions/view/array/RowNumberTable.java

index 99afc8c63b0af3064716f5ec047a8078dcb025c3..76452f94c15e34131a705bfcc29cc466f8d8ead1 100644 (file)
@@ -8,7 +8,7 @@
     <properties/>
     <border type="none"/>
     <children>
-      <scrollpane id="90774" class="com.intellij.ui.components.JBScrollPane" binding="myScrollPane">
+      <scrollpane id="90774" class="com.intellij.ui.components.JBScrollPane" binding="myScrollPane" custom-create="true">
         <constraints>
           <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
index 41bbb41d7e47f2c82edfb1167cd60bfbbdf81423..2176e272b40022ae63e976b59d5f271f2a4e87b7 100644 (file)
@@ -18,9 +18,10 @@ package com.jetbrains.python.actions.view.array;
 import com.intellij.ui.components.JBScrollPane;
 import com.intellij.ui.table.JBTable;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
-import javax.swing.table.DefaultTableModel;
+import java.awt.*;
 
 /**
  * @author amarch
@@ -34,13 +35,15 @@ public class ArrayTableForm {
   private JPanel myFormatPanel;
   private JPanel myMainPanel;
   public JBTable myTable;
+  private PyViewArrayAction.MyDialog myParentDialog;
 
 
   private static final String DATA_LOADING_IN_PROCESS = "Please wait, load array data.";
 
   private static final String NOT_APPLICABLE = "View not applicable for ";
 
-  public ArrayTableForm(){
+  public ArrayTableForm(PyViewArrayAction.MyDialog dialog) {
+    myParentDialog = dialog;
   }
 
   private void createUIComponents() {
@@ -51,6 +54,18 @@ public class ArrayTableForm {
     };
     myTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
     myTable.setRowSelectionAllowed(false);
+
+    myScrollPane = new JBScrollPane();
+    JTable rowTable = new RowNumberTable(myTable) {
+      @Override
+      protected void paintComponent(@NotNull Graphics g) {
+        getEmptyText().setText("");
+        super.paintComponent(g);
+      }
+    };
+    myScrollPane.setRowHeaderView(rowTable);
+    myScrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER,
+                           rowTable.getTableHeader());
   }
 
   public JTextField getSliceTextField() {
@@ -61,7 +76,7 @@ public class ArrayTableForm {
     return myFormatTextField;
   }
 
-  public JBTable getTable() {
+  public JTable getTable() {
     return myTable;
   }
 
@@ -69,32 +84,20 @@ public class ArrayTableForm {
     return myColoredCheckbox;
   }
 
-  private void setSpinnerText(String text) {
-    DefaultTableModel model = new DefaultTableModel(1, 1) {
-      @Override
-      public boolean isCellEditable(int row, int column) {
-        return false;
-      }
-    };
-    myTable.setModel(model);
-    myTable.setValueAt(text, 0, 0);
-  }
-
-  public void setDefaultSpinnerText() {
-    setSpinnerText(DATA_LOADING_IN_PROCESS);
+  public void setDefaultStatus() {
+    myTable.getEmptyText().setText(DATA_LOADING_IN_PROCESS);
   }
 
-  public void setErrorSpinnerText(Exception e) {
-    setSpinnerText(e.getMessage());
+  public void setErrorText(Exception e) {
+    setErrorText(e.getMessage());
   }
 
-  public void setErrorSpinnerText(String message) {
-    setSpinnerText(message);
+  public void setErrorText(String message) {
+    myParentDialog.setError(message);
   }
 
-
-  public void setNotApplicableSpinner(XValueNodeImpl node) {
-    setSpinnerText(NOT_APPLICABLE + node.getName());
+  public void setNotApplicableStatus(XValueNodeImpl node) {
+    myTable.getEmptyText().setText(NOT_APPLICABLE + node.getName());
   }
 
   public JComponent getMainPanel() {
index bbaf8f590b0bb23c486b7e784526f3910ca3b46f..92bb193cb4f44d074c3ebf407e3d165859d63173 100644 (file)
@@ -41,6 +41,10 @@ class Numpy2DArraySlice {
   private String mySlicePresentation;
   private NumpyArrayValueProvider myValueProvider;
   private DataEvaluator myDataEvaluator;
+  private int myRows = 0;
+  private int myColumns = 0;
+  private int myRowsOffset = 0;
+  private int myColumnsOffset = 0;
 
   public Numpy2DArraySlice(@NotNull String valueName,
                            @NotNull List<Pair<Integer, Integer>> fullSlice,
@@ -77,6 +81,12 @@ class Numpy2DArraySlice {
     if (!consistent) {
       throw new IllegalStateException("Illegal slice shape.");
     }
+
+    int size = myFullSlice.size();
+    myRows = myFullSlice.get(size - 2).getSecond() - myFullSlice.get(size - 2).getFirst();
+    myColumns = myFullSlice.get(size - 1).getSecond() - myFullSlice.get(size - 1).getFirst();
+    myRowsOffset = myFullSlice.get(size - 2).getFirst();
+    myColumnsOffset = myFullSlice.get(size - 1).getFirst();
   }
 
   public String getPresentation() {
@@ -91,16 +101,8 @@ class Numpy2DArraySlice {
     for (int index = 0; index < myFullSlice.size() - 2; index++) {
       mySlicePresentation += "[" + myFullSlice.get(index).getFirst() + "]";
     }
-    int size = myFullSlice.size();
-    mySlicePresentation += "[" +
-                           myFullSlice.get(size - 2).getFirst() +
-                           ":" +
-                           myFullSlice.get(size - 2).getSecond() +
-                           ", " +
-                           myFullSlice.get(size - 1).getFirst() +
-                           ":" +
-                           myFullSlice.get(size - 1).getSecond() +
-                           "]";
+    mySlicePresentation +=
+      "[" + myRowsOffset + ":" + (myRowsOffset + myRows) + ", " + myColumnsOffset + ":" + (myColumnsOffset + myColumns) + "]";
   }
 
   public void startFillData(Runnable callback) {
@@ -113,7 +115,6 @@ class Numpy2DArraySlice {
 
   private class DataEvaluator {
     private Object[][] myData;
-    private int myRows = 0;
     private int myFilledRows = 0;
     private int nextRow = 0;
 
@@ -129,12 +130,12 @@ class Numpy2DArraySlice {
     public void evaluateData(final Runnable callback) {
       final XDebuggerEvaluator.XEvaluationCallback computeChildrenCallback = new XDebuggerEvaluator.XEvaluationCallback() {
         @Override
-        public void evaluated(@NotNull XValue result) {
-          String name = ((PyDebugValue)result).getName();
-          final XValueNodeImpl node = new XValueNodeImpl(myValueProvider.getTree(), null, name, result);
+        public void evaluated(@NotNull final XValue result) {
+          final String name = ((PyDebugValue)result).getName();
           DebuggerUIUtil.invokeLater(new Runnable() {
             @Override
             public void run() {
+              XValueNodeImpl node = new XValueNodeImpl(myValueProvider.getTree(), null, name, result);
               node.startComputingChildren();
             }
           });
@@ -169,7 +170,7 @@ class Numpy2DArraySlice {
             }
             myFilledRows += 1;
           }
-          if (myFilledRows == myRows + myFullSlice.get(myFullSlice.size() - 2).getFirst()) {
+          if (myFilledRows == myRows) {
             node.getTree().removeTreeListener(this);
             callback.run();
           }
@@ -180,13 +181,11 @@ class Numpy2DArraySlice {
         }
       };
 
-      int size = myFullSlice.size();
       myData =
-        new Object[myFullSlice.get(size - 2).getSecond() - myFullSlice.get(size - 2).getFirst()]
-          [myFullSlice.get(size - 1).getSecond() - myFullSlice.get(size - 1).getFirst()];
+        new Object[myRows][myColumns];
       myRows = myData.length;
       myValueProvider.getTree().addTreeListener(treeListener);
-      nextRow = myFullSlice.get(size - 2).getFirst();
+      nextRow = myRowsOffset;
       startEvalNextRow(computeChildrenCallback);
     }
 
@@ -196,7 +195,7 @@ class Numpy2DArraySlice {
         evalRowCommand += "[" + nextRow + "]";
       }
       evalRowCommand +=
-        "[" + myFullSlice.get(myFullSlice.size() - 1).getFirst() + ":" + myFullSlice.get(myFullSlice.size() - 1).getSecond() + "])";
+        "[" + myColumnsOffset + ":" + (myColumnsOffset + myColumns) + "])";
       myValueProvider.getEvaluator().evaluate(evalRowCommand, callback, null);
     }
 
index 50d188b362c73e990614d73f7a8c3cd51a78be47..48fe6c98336f55f9392e6b2a5433b46cde71ebe8 100644 (file)
@@ -49,8 +49,8 @@ class NumpyArrayValueProvider extends ArrayValueProvider {
   private String myDtypeKind;
   private int[] myShape;
 
-  private final static int COLUMNS_IN_DEFAULT_SLICE = 100;
-  private final static int ROWS_IN_DEFAULT_SLICE = 100;
+  private final static int COLUMNS_IN_DEFAULT_SLICE = 50;
+  private final static int ROWS_IN_DEFAULT_SLICE = 50;
 
   public NumpyArrayValueProvider(@NotNull XValueNode node, @NotNull ArrayTableForm component, @NotNull Project project) {
     super(node);
@@ -269,7 +269,7 @@ class NumpyArrayValueProvider extends ArrayValueProvider {
 
           @Override
           public void errorOccurred(@NotNull String errorMessage) {
-            myComponent.setErrorSpinnerText(errorMessage);
+            myComponent.setErrorText(errorMessage);
           }
         }, null);
         super.doOKAction();
@@ -303,7 +303,7 @@ class NumpyArrayValueProvider extends ArrayValueProvider {
   }
 
   private void showError(String message) {
-    myComponent.setErrorSpinnerText(message);
+    myComponent.setErrorText(message);
   }
 
   public String getFormat() {
index 49f4337568dd058381503688bbdabd48b74732f0..f0939244ac6961f6c3c4f36d7401bc06b1e9cfea 100644 (file)
@@ -39,8 +39,7 @@ public class PyViewArrayAction extends XDebuggerTreeActionBase {
     dialog.show();
   }
 
-
-  private class MyDialog extends DialogWrapper {
+  protected class MyDialog extends DialogWrapper {
     public JTable myTable;
     private Project myProject;
     private ArrayTableForm myComponent;
@@ -53,34 +52,38 @@ public class PyViewArrayAction extends XDebuggerTreeActionBase {
 
       myProject = project;
 
-      myComponent = new ArrayTableForm();
+      myComponent = new ArrayTableForm(this);
       myTable = myComponent.getTable();
 
       init();
     }
 
-
     public void setValue(XValueNodeImpl node) {
 
       if (node.getValueContainer() instanceof PyDebugValue) {
         PyDebugValue debugValue = (PyDebugValue)node.getValueContainer();
         if ("ndarray".equals(debugValue.getType())) {
-          myComponent.setDefaultSpinnerText();
+          myComponent.setDefaultStatus();
           final NumpyArrayValueProvider valueProvider = new NumpyArrayValueProvider(node, myComponent, myProject);
           try {
             valueProvider.startFillTable();
           }
           catch (Exception e) {
-            myComponent.setErrorSpinnerText(e);
+            myComponent.setErrorText(e);
           }
         }
         else {
-          myComponent.setNotApplicableSpinner(node);
+          myComponent.setNotApplicableStatus(node);
           //this.close(CLOSE_EXIT_CODE);
         }
       }
     }
 
+    public void setError(String text){
+      //todo: think about this usage
+      setErrorText(text);
+    }
+
     @Override
     @NotNull
     protected Action[] createActions() {
index 50c2e55eae763c165f2d6100362c9ad834037c8e..c83a5c5b5c25c95f625ad5581da4941a418075f5 100644 (file)
@@ -15,6 +15,8 @@
  */
 package com.jetbrains.python.actions.view.array;
 
+import com.intellij.ui.table.JBTable;
+
 import javax.swing.*;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
@@ -32,7 +34,7 @@ import java.beans.PropertyChangeListener;
 *  This table must be added to the row header of the scrollpane that
 *  contains the main table.
 */
-public class RowNumberTable extends JTable
+public class RowNumberTable extends JBTable
   implements ChangeListener, PropertyChangeListener, TableModelListener {
   private JTable main;