Пример #1
0
  // ------------------------------------------------------------------
  // from Java Swing 1.2 Orielly - Robert Eckstein
  // ------------------------------------------------------------------
  protected JTextComponent updateKeymapForWord(JTextComponent textComp) {
    // create a new child keymap
    Keymap map = JTextComponent.addKeymap("NslmMap", textComp.getKeymap());

    // define the keystrokeds to be added
    KeyStroke next = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK, false);
    // add the new mappings used DefaultEditorKit actions
    map.addActionForKeyStroke(next, getAction(DefaultEditorKit.nextWordAction));

    KeyStroke prev = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(prev, getAction(DefaultEditorKit.previousWordAction));

    KeyStroke selNext =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(selNext, getAction(DefaultEditorKit.selectionNextWordAction));
    KeyStroke selPrev =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_LEFT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(selPrev, getAction(DefaultEditorKit.selectionPreviousWordAction));

    KeyStroke find = KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(find, getAction("find"));

    KeyStroke findAgain = KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(findAgain, getAction("findAgain"));

    // set the keymap for the text component
    textComp.setKeymap(map);
    return (textComp);
  } // end updateKeymapForWord
Пример #2
0
  /*
   *  We need to know if the caret is currently positioned on the line we
   *  are about to paint so the line number can be highlighted.
   */
  private boolean isCurrentLine(int rowStartOffset) {
    int caretPosition = component.getCaretPosition();
    Element root = component.getDocument().getDefaultRootElement();

    if (root.getElementIndex(rowStartOffset) == root.getElementIndex(caretPosition)) return true;
    else return false;
  }
Пример #3
0
  /**
   * Provides a way to determine the next visually represented model location at which one might
   * place a caret. Some views may not be visible, they might not be in the same order found in the
   * model, or they just might not allow access to some of the locations in the model.
   *
   * @param pos the position to convert >= 0
   * @param a the allocated region in which to render
   * @param direction the direction from the current position that can be thought of as the arrow
   *     keys typically found on a keyboard. This will be one of the following values:
   *     <ul>
   *       <li>SwingConstants.WEST
   *       <li>SwingConstants.EAST
   *       <li>SwingConstants.NORTH
   *       <li>SwingConstants.SOUTH
   *     </ul>
   *
   * @return the location within the model that best represents the next location visual position
   * @exception BadLocationException
   * @exception IllegalArgumentException if <code>direction</code> doesn't have one of the legal
   *     values above
   */
  public int getNextVisualPositionFrom(
      int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet)
      throws BadLocationException {

    biasRet[0] = Position.Bias.Forward;
    switch (direction) {
      case NORTH:
      case SOUTH:
        {
          if (pos == -1) {
            pos = (direction == NORTH) ? Math.max(0, getEndOffset() - 1) : getStartOffset();
            break;
          }
          JTextComponent target = (JTextComponent) getContainer();
          Caret c = (target != null) ? target.getCaret() : null;
          // YECK! Ideally, the x location from the magic caret position
          // would be passed in.
          Point mcp;
          if (c != null) {
            mcp = c.getMagicCaretPosition();
          } else {
            mcp = null;
          }
          int x;
          if (mcp == null) {
            Rectangle loc = target.modelToView(pos);
            x = (loc == null) ? 0 : loc.x;
          } else {
            x = mcp.x;
          }
          if (direction == NORTH) {
            pos = Utilities.getPositionAbove(target, pos, x);
          } else {
            pos = Utilities.getPositionBelow(target, pos, x);
          }
        }
        break;
      case WEST:
        if (pos == -1) {
          pos = Math.max(0, getEndOffset() - 1);
        } else {
          pos = Math.max(0, pos - 1);
        }
        break;
      case EAST:
        if (pos == -1) {
          pos = getStartOffset();
        } else {
          pos = Math.min(pos + 1, getDocument().getLength());
        }
        break;
      default:
        throw new IllegalArgumentException("Bad direction: " + direction);
    }
    return pos;
  }
Пример #4
0
  /**
   * Create a line number component for a text component.
   *
   * @param argComponent the related text component
   * @param argMinimumDisplayDigits the number of digits used to calculate the minimum width of the
   *     component.
   */
  public TextLineNumber(JTextComponent argComponent, int argMinimumDisplayDigits) {
    component = argComponent;

    setFont(argComponent.getFont());

    setBorderGap(5);
    setCurrentLineForeground(Color.RED);
    setDigitAlignment(RIGHT);
    setMinimumDisplayDigits(argMinimumDisplayDigits);

    argComponent.getDocument().addDocumentListener(this);
    argComponent.addCaretListener(this);
    argComponent.addPropertyChangeListener("font", this);
  }
Пример #5
0
  //
  //  Implement CaretListener interface
  //
  @Override
  public void caretUpdate(CaretEvent e) {
    //  Get the line the caret is positioned on

    int caretPosition = component.getCaretPosition();
    Element root = component.getDocument().getDefaultRootElement();
    int currentLine = root.getElementIndex(caretPosition);

    //  Need to repaint so the correct line number can be highlighted
    if (lastLine != currentLine) {
      repaint();
      lastLine = currentLine;
    }
  }
 /**
  * Determines whether the image is selected, and if it's the only thing selected.
  *
  * @return 0 if not selected, 1 if selected, 2 if exclusively selected. "Exclusive" selection is
  *     only returned when editable.
  */
 protected int getSelectionState() {
   int p0 = fElement.getStartOffset();
   int p1 = fElement.getEndOffset();
   if (fContainer instanceof JTextComponent) {
     JTextComponent textComp = (JTextComponent) fContainer;
     int start = textComp.getSelectionStart();
     int end = textComp.getSelectionEnd();
     if (start <= p0 && end >= p1) {
       if (start == p0 && end == p1 && isEditable()) return 2;
       else return 1;
     }
   }
   return 0;
 }
Пример #7
0
  //    public static final String showElementTreeAction = "showElementTree";
  // -------------------------------------------------------------
  public void openFile(String currDirStr, String currFileStr) {

    if (fileDialog == null) {
      fileDialog = new FileDialog(this);
    }
    fileDialog.setMode(FileDialog.LOAD);
    if (!(currDirStr.equals(""))) {
      fileDialog.setDirectory(currDirStr);
    }
    if (!(currFileStr.equals(""))) {
      fileDialog.setFile(currFileStr);
    }
    fileDialog.show();

    String file = fileDialog.getFile(); // cancel pushed
    if (file == null) {
      return;
    }
    String directory = fileDialog.getDirectory();
    File f = new File(directory, file);
    if (f.exists()) {
      Document oldDoc = getEditor().getDocument();
      if (oldDoc != null)
        // oldDoc.removeUndoableEditListener(undoHandler);
        /*
          if (elementTreePanel != null) {
          elementTreePanel.setEditor(null);
          }
        */
        getEditor().setDocument(new PlainDocument());
      fileDialog.setTitle(file);
      Thread loader = new FileLoader(f, editor1.getDocument());
      loader.start();
    }
  }
Пример #8
0
  /*
   *	Get the line number to be drawn. The empty string will be returned
   *  when a line of text has wrapped.
   */
  protected String getTextLineNumber(int rowStartOffset) {
    Element root = component.getDocument().getDefaultRootElement();
    int index = root.getElementIndex(rowStartOffset);
    Element line = root.getElement(index);

    if (line.getStartOffset() == rowStartOffset) return String.valueOf(index + 1);
    else return "";
  }
 /** Select or grow image when clicked. */
 public void mousePressed(MouseEvent e) {
   Dimension size = fComponent.getSize();
   if (e.getX() >= size.width - 7 && e.getY() >= size.height - 7 && getSelectionState() == 2) {
     // Click in selected grow-box:
     if (DEBUG) System.out.println("ImageView: grow!!! Size=" + fWidth + "x" + fHeight);
     Point loc = fComponent.getLocationOnScreen();
     fGrowBase = new Point(loc.x + e.getX() - fWidth, loc.y + e.getY() - fHeight);
     fGrowProportionally = e.isShiftDown();
   } else {
     // Else select image:
     fGrowBase = null;
     JTextComponent comp = (JTextComponent) fContainer;
     int start = fElement.getStartOffset();
     int end = fElement.getEndOffset();
     int mark = comp.getCaret().getMark();
     int dot = comp.getCaret().getDot();
     if (e.isShiftDown()) {
       // extend selection if shift key down:
       if (mark <= start) comp.moveCaretPosition(end);
       else comp.moveCaretPosition(start);
     } else {
       // just select image, without shift:
       if (mark != start) comp.setCaretPosition(start);
       if (dot != end) comp.moveCaretPosition(end);
     }
   }
 }
Пример #10
0
  /*
   *  Determine the Y offset for the current row
   */
  private int getOffsetY(int rowStartOffset, FontMetrics fontMetrics) throws BadLocationException {
    //  Get the bounding rectangle of the row

    Rectangle r = component.modelToView(rowStartOffset);
    int lineHeight = fontMetrics.getHeight();
    int y = r.y + r.height;
    int descent = 0;

    //  The text needs to be positioned above the bottom of the bounding
    //  rectangle based on the descent of the font(s) contained on the row.
    if (r.height == lineHeight) {
      // default font is being used
      descent = fontMetrics.getDescent();
    } else {
      // We need to check all the attributes for font changes
      if (fonts == null) {
        fonts = new HashMap<String, FontMetrics>();
      }

      Element root = component.getDocument().getDefaultRootElement();
      int index = root.getElementIndex(rowStartOffset);
      Element line = root.getElement(index);

      for (int i = 0; i < line.getElementCount(); i++) {
        Element child = line.getElement(i);
        AttributeSet as = child.getAttributes();
        String fontFamily = (String) as.getAttribute(StyleConstants.FontFamily);
        Integer fontSize = (Integer) as.getAttribute(StyleConstants.FontSize);
        String key = fontFamily + fontSize;

        FontMetrics fm = fonts.get(key);

        if (fm == null) {
          Font font = new Font(fontFamily, Font.PLAIN, fontSize);
          fm = component.getFontMetrics(font);
          fonts.put(key, fm);
        }

        descent = Math.max(descent, fm.getDescent());
      }
    }

    return y - descent;
  }
Пример #11
0
  /*
   *  A document change may affect the number of displayed lines of text.
   *  Therefore the lines numbers will also change.
   */
  private void documentChanged() {
    //  View of the component has not been updated at the time
    //  the DocumentEvent is fired

    SwingUtilities.invokeLater(
        () -> {
          try {
            int endPos = component.getDocument().getLength();
            Rectangle rect = component.modelToView(endPos);

            if (rect != null && rect.y != lastHeight) {
              setPreferredWidth();
              repaint();
              lastHeight = rect.y;
            }
          } catch (BadLocationException ex) {
            /* nothing to do */
          }
        });
  }
Пример #12
0
  /**
   * Draw the line numbers
   *
   * @param g
   */
  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    ((Graphics2D) g)
        .setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    //	Determine the width of the space available to draw the line number

    FontMetrics fontMetrics = component.getFontMetrics(component.getFont());
    Insets insets = getInsets();
    int availableWidth = getSize().width - insets.left - insets.right;

    //  Determine the rows to draw within the clipped bounds.

    Rectangle clip = g.getClipBounds();
    int rowStartOffset = component.viewToModel(new Point(0, clip.y));
    int endOffset = component.viewToModel(new Point(0, clip.y + clip.height));

    while (rowStartOffset <= endOffset) {
      try {
        if (isCurrentLine(rowStartOffset)) g.setColor(getCurrentLineForeground());
        else g.setColor(getForeground());

        //  Get the line number as a string and then determine the
        //  "X" and "Y" offsets for drawing the string.

        String lineNumber = getTextLineNumber(rowStartOffset);
        int stringWidth = fontMetrics.stringWidth(lineNumber);
        int x = getOffsetX(availableWidth, stringWidth) + insets.left;
        int y = getOffsetY(rowStartOffset, fontMetrics);
        g.drawString(lineNumber, x, y);

        //  Move to the next row

        rowStartOffset = Utilities.getRowEnd(component, rowStartOffset) + 1;
      } catch (Exception e) {
        break;
      }
    }
  }
Пример #13
0
  /** Calculate the width needed to display the maximum line number */
  private void setPreferredWidth() {
    Element root = component.getDocument().getDefaultRootElement();
    int lines = root.getElementCount();
    int digits = Math.max(String.valueOf(lines).length(), minimumDisplayDigits);

    //  Update sizes when number of digits in the line number changes
    if (lastDigits != digits) {
      lastDigits = digits;
      FontMetrics fontMetrics = getFontMetrics(getFont());
      int width = fontMetrics.charWidth('0') * digits;
      Insets insets = getInsets();
      int preferredWidth = insets.left + insets.right + width;

      Dimension d = getPreferredSize();
      d.setSize(preferredWidth, HEIGHT);
      setPreferredSize(d);
      setSize(d);
    }
  }
Пример #14
0
 /** Create an editor to represent the given document. */
 protected JTextComponent createEditor() {
   JTextComponent c = new JTextArea();
   c.setDragEnabled(true);
   c.setFont(new Font("monospaced", Font.PLAIN, 12));
   return c;
 }
Пример #15
0
  // ------------------------------------------------------------------
  // from Java Swing 1.2 Orielly - Robert Eckstein
  // ------------------------------------------------------------------
  protected JTextComponent updateKeymapForEmacs(JTextComponent textComp) {
    // note: it does not look like a key can do more than one action
    // thus no modes.
    // todo: not all of these are correct. such as ctrlK
    // todo: add saving - ctrlXS

    // create a new child keymap
    Keymap map = JTextComponent.addKeymap("NslmMap", textComp.getKeymap());

    KeyStroke selNext =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(selNext, getAction(DefaultEditorKit.selectionNextWordAction));

    KeyStroke selPrev =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_LEFT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(selPrev, getAction(DefaultEditorKit.selectionPreviousWordAction));

    KeyStroke next = KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(next, getAction(DefaultEditorKit.forwardAction));
    KeyStroke prev = KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(prev, getAction(DefaultEditorKit.backwardAction));

    KeyStroke selectionDown = KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(selectionDown, getAction(DefaultEditorKit.downAction));
    KeyStroke selectionUp = KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(selectionUp, getAction(DefaultEditorKit.upAction));

    KeyStroke pageDown = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(pageDown, getAction(DefaultEditorKit.pageDownAction));

    KeyStroke pageUp = KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(pageUp, getAction(DefaultEditorKit.pageUpAction));

    KeyStroke endDoc =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_GREATER, InputEvent.META_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(endDoc, getAction(DefaultEditorKit.endAction));
    KeyStroke beginingDoc =
        KeyStroke.getKeyStroke(
            KeyEvent.VK_LESS, InputEvent.META_MASK | InputEvent.SHIFT_MASK, false);
    map.addActionForKeyStroke(beginingDoc, getAction(DefaultEditorKit.beginAction));

    // the VK_SPACE and VK_W not working as in Emacs - space deleting
    // KeyStroke
    // selectionStart=KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,InputEvent.CTRL_MASK,false);
    // map.addActionForKeyStroke(selectionStart,getAction(DefaultEditorKit.selectionForwardAction));
    // //todo: setCharPosAction
    // this is doing nothing because only one char to can be assigned to cut
    // KeyStroke cut1=KeyStroke.getKeyStroke(KeyEvent.VK_W,InputEvent.CTRL_MASK,false);
    // map.addActionForKeyStroke(cut1,getAction(DefaultEditorKit.cutAction));

    // if we do save as XS, this will have to change
    KeyStroke cut = KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(cut, getAction(DefaultEditorKit.cutAction));

    KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(paste, getAction(DefaultEditorKit.pasteAction));

    KeyStroke moveToEndLine = KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(moveToEndLine, getAction(DefaultEditorKit.endLineAction));

    // not emacs like
    KeyStroke selWord = KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(selWord, getAction(DefaultEditorKit.selectWordAction));

    KeyStroke selLine = KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(selLine, getAction(DefaultEditorKit.selectLineAction));

    KeyStroke delNext = KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(delNext, getAction(DefaultEditorKit.deleteNextCharAction));

    KeyStroke insertLine = KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(insertLine, getAction(DefaultEditorKit.insertBreakAction));

    KeyStroke searchBackward = KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(searchBackward, getAction("findAgain"));

    KeyStroke searchForward = KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK, false);
    map.addActionForKeyStroke(searchForward, getAction("findAgain"));

    // set the keymap for the text component
    textComp.setKeymap(map);
    return (textComp);
  } // end updateKeymapForEmacs
Пример #16
0
 /** Returns the text editor's highlight color. */
 protected Color getHighlightColor() {
   JTextComponent textComp = (JTextComponent) fContainer;
   return textComp.getSelectionColor();
 }