Package quarkninja.mode.xqmode

Source Code of quarkninja.mode.xqmode.ErrorWindow$DockTool2Base

package quarkninja.mode.xqmode;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import processing.app.Base;
import processing.app.Editor;
import processing.app.SketchCode;

/**
* Error Window that displays a tablular list of errors. Clicking on an error
* scrolls to its location in the code.
*
* @author Manindra Moharana
*
*/
public class ErrorWindow extends JFrame {

  private JPanel contentPane;
  /**
   * The table displaying the errors
   */
  public JTable errorTable;
  /**
   * Scroll pane that contains the Error Table
   */
  private JScrollPane scrollPane;
  public Editor thisEditor;
  private JFrame thisErrorWindow;
  private DockTool2Base Docker;
  public ErrorCheckerService errorCheckerService;

  public static final String[] columnNames = { "Problem", "Tab", "Line" };

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          ErrorWindow frame = new ErrorWindow(null, null);
          frame.setVisible(true);
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  public ErrorWindow(Editor editor, ErrorCheckerService syncheck) {
    thisErrorWindow = this;
    errorCheckerService = syncheck;
    thisEditor = editor;
    setTitle("Problems");
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
      e.printStackTrace();
    }
    prepareFrame();
  }

  /**
   * Sets up ErrorWindow
   */
  private void prepareFrame() { // Not createAndShowGUI().
    Base.setIcon(this);
    setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    // Default size: setBounds(100, 100, 458, 160);
    setBounds(100, 100, 458, 160);
    contentPane = new JPanel();
    contentPane.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        handlePause(e);
        if (e.getButton() == MouseEvent.BUTTON3) {
          // TODO: Remove this later. For stopping syntax
          // checker.
          errorCheckerService.stopThread();
          System.out.println("Syntax checker thread paused.");
        }
      }
    });

    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(new BorderLayout(0, 0));

    scrollPane = new JScrollPane();
    contentPane.add(scrollPane);

    scrollPane.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        handlePause(e);
        if (e.getButton() == MouseEvent.BUTTON3) {
          // TODO: Remove this later. For stopping syntax
          // checker.
          errorCheckerService.stopThread();
          System.out.println("Syntax checker thread paused.");
        }
      }
    });

    errorTable = new JTable() {
      public boolean isCellEditable(int rowIndex, int colIndex) {
        return false; // Disallow the editing of any cell
      }
    };
    errorTable.setModel(new DefaultTableModel(new Object[][] {},
        columnNames));
    // errorTable.getColumnModel().getColumn(0).setPreferredWidth(300);
    // errorTable.getColumnModel().getColumn(1).setPreferredWidth(40);

    errorTable.getColumnModel().getColumn(0).setPreferredWidth(300);
    errorTable.getColumnModel().getColumn(1).setPreferredWidth(100);
    errorTable.getColumnModel().getColumn(2).setPreferredWidth(50);
    errorTable.getTableHeader().setReorderingAllowed(false);
    scrollPane.setViewportView(errorTable);

    try {
      Docker = new DockTool2Base();
      addListeners();
    } catch (Exception e) {
      System.out.println("addListeners() acted silly.");
      e.printStackTrace();
    }

    if (thisEditor != null) {
      setLocation(new Point(thisEditor.getLocation().x
          + thisEditor.getWidth(), thisEditor.getLocation().y));
    }

  }

  /**
   * Converts offsets returned by Eclipse Parser to PDE offset so that text
   * can be selected in the editor window. Not being used presently because of
   * unbalanced offset issue.
   */
  protected int normalizeOffset(int offset) {
    int finalOffset = 0, codeIndex = 0;
    System.out.println("OF: " + offset);
    for (SketchCode sc : thisEditor.getSketch().getCode()) {

      // + 1 for \n at end of each tab
      int scOffset = sc.getProgram().length() + 1;
      System.out.println(codeIndex + ".Offset " + scOffset);
      if (offset > scOffset) {
        offset -= scOffset;
      } else {
        finalOffset = offset;
        thisEditor.getSketch().setCurrentCode(codeIndex);
        break;
      }
      codeIndex++;
    }
    System.out.println("FO: " + finalOffset);
    return finalOffset;
  }

  /**
   * Updates the error table with new data(Table Model). Called from Syntax
   * Checker Service.
   *
   * @param tableModel
   *            - Table Model
   * @return True - If error table was updated successfully.
   */
  @SuppressWarnings("rawtypes")
  synchronized public boolean updateTable(final TableModel tableModel) {

    /*
     * SwingWorker - The dirty side of Swing. Turns out that if you update a
     * swing component outside of the swing event thread, all sort of weird
     * exceptions are thrown. The worse part is, these exception don't get
     * caught easily either.
     *
     * The 'correct' way of updating swing components is therefore, to do
     * the updating through a SwingWorker, inside done(). The updating then
     * takes place in a thread safe manner.
     */

    SwingWorker worker = new SwingWorker() {

      protected Object doInBackground() throws Exception {
        return null;
      }

      protected void done() {

        try {
          errorTable.setModel(tableModel);
          errorTable.getColumnModel().getColumn(0)
              .setPreferredWidth(300);
          errorTable.getColumnModel().getColumn(1)
              .setPreferredWidth(100);
          errorTable.getColumnModel().getColumn(2)
              .setPreferredWidth(50);
          errorTable.getTableHeader().setReorderingAllowed(false);
          errorTable.validate();
          errorTable.updateUI();
          errorTable.repaint();
        } catch (Exception e) {
          System.out.println("Exception at updatTable " + e);
          // e.printStackTrace();
        }
        // errorTable.getModel()

      }
    };
    try {
      worker.execute();
    } catch (Exception e) {
      System.out.println("Errorwindow updateTable Worker's slacking."
          + e.getMessage());
      // e.printStackTrace();
    }
    return true;
  }

  /**
   * Adds various listeners to components of EditorWindow and also to the
   * Editor window
   */
  private void addListeners() {

    if (thisErrorWindow == null)
      System.out.println("ERW null");
    errorTable.addMouseListener(new MouseAdapter() {
      // TODO: synchronized or Swing Worker ?

      /**
       * Clicking on an error in the list scrolls to its location. This is
       * the funcition that handles it all. Now this might look really
       * messy. But it's just getting two offsets(line start and line end)
       * and then switching to the appropriate tab, and then selecting the
       * line. I tried to select the exact point of the error in the line,
       * but it is never accurate because of processing's syntax which
       * deviates from pure Jave like #ffffff is actually 0xffffffff, int(
       * is actually (int)(, color is an int, etc.
       */
      synchronized public void mouseReleased(MouseEvent e) {

        handlePause(e);
        try {
          errorCheckerService.scrollToErrorLine(errorTable
              .getSelectedRow());
          // System.out.print("Row clicked: "
          // + (errorTable.getSelectedRow()));
        } catch (Exception e1) {
          System.out.println("Exception EW mouseReleased " + e);
        }
      }
    });

    thisErrorWindow.addComponentListener(new ComponentListener() {

      @Override
      public void componentShown(ComponentEvent e) {

      }

      @Override
      public void componentResized(ComponentEvent e) {
        Docker.tryDocking();
      }

      @Override
      public void componentMoved(ComponentEvent e) {
        Docker.tryDocking();
      }

      @Override
      public void componentHidden(ComponentEvent e) {

      }
    });

    thisErrorWindow.addWindowListener(new WindowListener() {

      public void windowOpened(WindowEvent e) {

      }

      @Override
      public void windowClosing(WindowEvent e) {
      }

      @Override
      public void windowClosed(WindowEvent e) {
      }

      @Override
      public void windowIconified(WindowEvent e) {

      }

      @Override
      public void windowDeiconified(WindowEvent e) {
        thisEditor.setExtendedState(Editor.NORMAL);
      }

      @Override
      public void windowActivated(WindowEvent e) {
        if (e.getOppositeWindow() != thisEditor) {
          thisEditor.requestFocus();
          thisErrorWindow.requestFocus();
        }
      }

      @Override
      public void windowDeactivated(WindowEvent e) {

      }
    });

    if (thisEditor == null) {
      System.out.println("Editor null");
      return;
    }

    thisEditor.addWindowListener(new WindowListener() {

      @Override
      public void windowClosing(WindowEvent e) {

      }

      @Override
      public void windowClosed(WindowEvent e) {
        errorCheckerService.pauseThread = true;
        errorCheckerService.stopThread(); // Bye bye thread.
        thisErrorWindow.dispose();
      }

      @Override
      public void windowIconified(WindowEvent e) {
        thisErrorWindow.setExtendedState(Frame.ICONIFIED);
      }

      @Override
      public void windowDeiconified(WindowEvent e) {
        thisErrorWindow.setExtendedState(Frame.NORMAL);
      }

      @Override
      public void windowActivated(WindowEvent e) {
        if (e.getOppositeWindow() != thisErrorWindow) {
          thisErrorWindow.requestFocus();
          thisEditor.requestFocus();
        }
      }

      @Override
      public void windowOpened(WindowEvent e) {

      }

      @Override
      public void windowDeactivated(WindowEvent e) {

      }

    });

    thisEditor.addComponentListener(new ComponentListener() {

      @Override
      public void componentShown(ComponentEvent e) {

      }

      @Override
      public void componentResized(ComponentEvent e) {
        if (Docker.isDocked()) {
          Docker.dock();
        } else {
          Docker.tryDocking();
        }
      }

      @Override
      public void componentMoved(ComponentEvent e) {

        if (Docker.isDocked()) {
          Docker.dock();
        } else {
          Docker.tryDocking();
        }

      }

      @Override
      public void componentHidden(ComponentEvent e) {
        System.out.println("ed hidden");
      }
    });

  }

  public void handlePause(MouseEvent e) {

    if (e.isControlDown()) {
      errorCheckerService.pauseThread = !errorCheckerService.pauseThread;
      if (errorCheckerService.pauseThread)
        System.out.println(thisEditor.getSketch().getName()
            + " - Error Checker paused.");
      else
        System.out.println(thisEditor.getSketch().getName()
            + " - Error Checker resumed.");
    }
  }

  /**
   * Implements the docking feature of the tool - The frame sticks to the
   * editor and once docked, moves along with it as the editor is resized,
   * moved, maximized, minimized or closed.
   *
   * This class has been borrowed from Tab Manager tool by Thomas Diewald. It
   * has been slightly modified and used here.
   *
   * @author: Thomas Diewald
   */
  private class DockTool2Base {

    private int docking_border = 0;
    private int dock_on_editor_y_offset_ = 0;
    private int dock_on_editor_x_offset_ = 0;

    // ///////////////////////////////
    // ____2____
    // | |
    // | |
    // 0 | editor | 1
    // | |
    // |_________|
    // 3
    // ///////////////////////////////

    // public void reset() {
    // dock_on_editor_y_offset_ = 0;
    // dock_on_editor_x_offset_ = 0;
    // docking_border = 0;
    // }

    public boolean isDocked() {
      return (docking_border >= 0);
    }

    private final int MAX_GAP_ = 20;

    //
    public void tryDocking() {
      if (thisEditor == null)
        return;
      Editor editor = thisEditor;
      Frame frame = thisErrorWindow;

      int ex = editor.getX();
      int ey = editor.getY();
      int ew = editor.getWidth();
      int eh = editor.getHeight();

      int fx = frame.getX();
      int fy = frame.getY();
      int fw = frame.getWidth();
      int fh = frame.getHeight();

      if (((fy > ey) && (fy < ey + eh))
          || ((fy + fh > ey) && (fy + fh < ey + eh))) {
        int dis_border_left = Math.abs(ex - (fx + fw));
        int dis_border_right = Math.abs((ex + ew) - (fx));

        if (dis_border_left < MAX_GAP_ || dis_border_right < MAX_GAP_) {
          docking_border = (dis_border_left < dis_border_right) ? 0
              : 1;
          dock_on_editor_y_offset_ = fy - ey;
          dock();
          return;
        }
      }

      if (((fx > ex) && (fx < ex + ew))
          || ((fx + fw > ey) && (fx + fw < ex + ew))) {
        int dis_border_top = Math.abs(ey - (fy + fh));
        int dis_border_bot = Math.abs((ey + eh) - (fy));

        if (dis_border_top < MAX_GAP_ || dis_border_bot < MAX_GAP_) {
          docking_border = (dis_border_top < dis_border_bot) ? 2 : 3;
          dock_on_editor_x_offset_ = fx - ex;
          dock();
          return;
        }
      }
      docking_border = -1;
    }

    public void dock() {
      if (thisEditor == null)
        return;
      Editor editor = thisEditor;
      Frame frame = thisErrorWindow;

      int ex = editor.getX();
      int ey = editor.getY();
      int ew = editor.getWidth();
      int eh = editor.getHeight();

      // int fx = frame.getX();
      // int fy = frame.getY();
      int fw = frame.getWidth();
      int fh = frame.getHeight();

      int x = 0, y = 0;
      if (docking_border == -1) {
        return;
      }

      if (docking_border == 0) {
        x = ex - fw;
        y = ey + dock_on_editor_y_offset_;
      }
      if (docking_border == 1) {
        x = ex + ew;
        y = ey + dock_on_editor_y_offset_;
      }

      if (docking_border == 2) {
        x = ex + dock_on_editor_x_offset_;
        y = ey - fh;
      }
      if (docking_border == 3) {
        x = ex + dock_on_editor_x_offset_;
        y = ey + eh;
      }
      frame.setLocation(x, y);
    }

  }
}
TOP

Related Classes of quarkninja.mode.xqmode.ErrorWindow$DockTool2Base

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.