/** @see javax.swing.plaf.basic.BasicTextUI#getPreferredSize(javax.swing.JComponent) */
  public Dimension getPreferredSize(JComponent c) {
    // The following code has been derived from BasicTextUI.
    Document doc = ((JTextComponent) c).getDocument();
    Insets i = c.getInsets();
    Dimension d = c.getSize();
    View rootView = getRootView((JTextComponent) c);

    if (doc instanceof AbstractDocument) {
      ((AbstractDocument) doc).readLock();
    }

    try {
      if ((d.width > (i.left + i.right)) && (d.height > (i.top + i.bottom))) {
        rootView.setSize(d.width - i.left - i.right, d.height - i.top - i.bottom);
      } else if (d.width == 0 && d.height == 0) {
        // Probably haven't been layed out yet, force some sort of
        // initial sizing.
        rootView.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
      }

      d.width =
          (int)
              Math.min(
                  (long) rootView.getPreferredSpan(View.X_AXIS) + (long) i.left + (long) i.right,
                  Integer.MAX_VALUE);
      d.height =
          (int)
              Math.min(
                  (long) rootView.getPreferredSpan(View.Y_AXIS) + (long) i.top + (long) i.bottom,
                  Integer.MAX_VALUE);
    } finally {
      if (doc instanceof AbstractDocument) {
        ((AbstractDocument) doc).readUnlock();
      }
    }

    // Fix: The preferred width is always two pixels too small on a Mac.
    d.width += 2;

    // We'd like our heights to be odd by default.
    if ((d.height & 1) == 0) {
      d.height--;
    }

    return d;
  }
Example #2
0
 public Dimension getMaximumSize(JComponent c) {
   Dimension d = getPreferredSize(c);
   View v = (View) c.getClientProperty(BasicHTML.propertyKey);
   if (v != null) {
     d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
   }
   return d;
 }
  /**
   * Returns the preferred span of the View used to display the alt text, or 0 if the view does not
   * exist.
   */
  private float getPreferredSpanFromAltView(int axis) {
    if (getImage() == null) {
      View view = getAltView();

      if (view != null) {
        return view.getPreferredSpan(axis);
      }
    }
    return 0f;
  }
Example #4
0
    /**
     * Adjusts the given row if possible to fit within the layout span. By default this will try to
     * find the highest break weight possible nearest the end of the row. If a forced break is
     * encountered, the break will be positioned there.
     *
     * @param rowIndex the row to adjust to the current layout span.
     * @param desiredSpan the current layout span >= 0
     * @param x the location r starts at.
     */
    protected void adjustRow(FlowView fv, int rowIndex, int desiredSpan, int x) {
      final int flowAxis = fv.getFlowAxis();
      View r = fv.getView(rowIndex);
      int n = r.getViewCount();
      int span = 0;
      int bestWeight = BadBreakWeight;
      int bestSpan = 0;
      int bestIndex = -1;
      int bestOffset = 0;
      View v;
      for (int i = 0; i < n; i++) {
        v = r.getView(i);
        int spanLeft = desiredSpan - span;

        int w = v.getBreakWeight(flowAxis, x + span, spanLeft);
        if ((w >= bestWeight) && (w > BadBreakWeight)) {
          bestWeight = w;
          bestIndex = i;
          bestSpan = span;
          if (w >= ForcedBreakWeight) {
            // it's a forced break, so there is
            // no point in searching further.
            break;
          }
        }
        span += v.getPreferredSpan(flowAxis);
      }
      if (bestIndex < 0) {
        // there is nothing that can be broken, leave
        // it in it's current state.
        return;
      }

      // Break the best candidate view, and patch up the row.
      int spanLeft = desiredSpan - bestSpan;
      v = r.getView(bestIndex);
      v = v.breakView(flowAxis, v.getStartOffset(), x + bestSpan, spanLeft);
      View[] va = new View[1];
      va[0] = v;
      View lv = getLogicalView(fv);
      for (int i = bestIndex; i < n; i++) {
        View tmpView = r.getView(i);
        if (contains(lv, tmpView)) {
          tmpView.setParent(lv);
        } else if (tmpView.getViewCount() > 0) {
          recursiveReparent(tmpView, lv);
        }
      }
      r.replace(bestIndex, n - bestIndex, va);
    }
Example #5
0
 /**
  * Determines the preferred span for this view along an axis.
  *
  * @param axis may be either View.X_AXIS or View.Y_AXIS
  * @return the span the view would like to be rendered into. Typically the view is told to
  *     render into the span that is returned, although there is no guarantee. The parent may
  *     choose to resize or break the view.
  * @see View#getPreferredSpan
  */
 public float getPreferredSpan(int axis) {
   float maxpref = 0;
   float pref = 0;
   int n = getViewCount();
   for (int i = 0; i < n; i++) {
     View v = getView(i);
     pref += v.getPreferredSpan(axis);
     if (v.getBreakWeight(axis, 0, Short.MAX_VALUE) >= ForcedBreakWeight) {
       maxpref = Math.max(maxpref, pref);
       pref = 0;
     }
   }
   maxpref = Math.max(maxpref, pref);
   return maxpref;
 }
Example #6
0
 /**
  * Gets the alignment.
  *
  * @param axis may be either X_AXIS or Y_AXIS
  * @return the alignment
  */
 public float getAlignment(int axis) {
   switch (axis) {
     case View.X_AXIS:
       return 0;
     case View.Y_AXIS:
       if (getViewCount() == 0) {
         return 0;
       }
       float span = getPreferredSpan(View.Y_AXIS);
       View v = getView(0);
       float above = v.getPreferredSpan(View.Y_AXIS);
       float a = (((int) span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span : 0;
       return a;
     default:
       throw new IllegalArgumentException("Invalid axis: " + axis);
   }
 }
Example #7
0
 /** Returns the baseline for single line text components, like <code>JTextField</code>. */
 private static int getSingleLineTextBaseline(JTextComponent textComponent, int h) {
   View rootView = textComponent.getUI().getRootView(textComponent);
   if (rootView.getViewCount() > 0) {
     Insets insets = textComponent.getInsets();
     int height = h - insets.top - insets.bottom;
     int y = insets.top;
     View fieldView = rootView.getView(0);
     int vspan = (int) fieldView.getPreferredSpan(View.Y_AXIS);
     if (height != vspan) {
       int slop = height - vspan;
       y += slop / 2;
     }
     FontMetrics fm = textComponent.getFontMetrics(textComponent.getFont());
     y += fm.getAscent();
     return y;
   }
   return -1;
 }
Example #8
0
 /**
  * Determines the minimum span for this view along an axis. The is implemented to find the
  * minimum unbreakable span.
  *
  * @param axis may be either View.X_AXIS or View.Y_AXIS
  * @return the span the view would like to be rendered into. Typically the view is told to
  *     render into the span that is returned, although there is no guarantee. The parent may
  *     choose to resize or break the view.
  * @see View#getPreferredSpan
  */
 public float getMinimumSpan(int axis) {
   float maxmin = 0;
   float min = 0;
   boolean nowrap = false;
   int n = getViewCount();
   for (int i = 0; i < n; i++) {
     View v = getView(i);
     if (v.getBreakWeight(axis, 0, Short.MAX_VALUE) == BadBreakWeight) {
       min += v.getPreferredSpan(axis);
       nowrap = true;
     } else if (nowrap) {
       maxmin = Math.max(min, maxmin);
       nowrap = false;
       min = 0;
     }
   }
   maxmin = Math.max(maxmin, min);
   return maxmin;
 }
  /**
   * Determines the preferred span for this view along an axis.
   *
   * @param axis may be either X_AXIS or Y_AXIS
   * @return the span the view would like to be rendered into; typically the view is told to render
   *     into the span that is returned, although there is no guarantee; the parent may choose to
   *     resize or break the view
   */
  @Override
  public float getPreferredSpan(int axis) {
    sync();

    // If the attributes specified a width/height, always use it!
    if (axis == View.X_AXIS && (state & WIDTH_FLAG) == WIDTH_FLAG) {
      getPreferredSpanFromAltView(axis);
      return width + leftInset + rightInset;
    }
    if (axis == View.Y_AXIS && (state & HEIGHT_FLAG) == HEIGHT_FLAG) {
      getPreferredSpanFromAltView(axis);
      return height + topInset + bottomInset;
    }

    Image image = getImage();

    if (image != null) {
      switch (axis) {
        case View.X_AXIS:
          return width + leftInset + rightInset;
        case View.Y_AXIS:
          return height + topInset + bottomInset;
        default:
          throw new IllegalArgumentException("Invalid axis: " + axis);
      }
    } else {
      View view = getAltView();
      float retValue = 0f;

      if (view != null) {
        retValue = view.getPreferredSpan(axis);
      }
      switch (axis) {
        case View.X_AXIS:
          return retValue + (width + leftInset + rightInset);
        case View.Y_AXIS:
          return retValue + (height + topInset + bottomInset);
        default:
          throw new IllegalArgumentException("Invalid axis: " + axis);
      }
    }
  }
Example #10
0
 protected int getPreferredRowHeight(JTable table, SymbolEditorComponent editorComponent) {
   View v =
       editorComponent.getTextComponent().getUI().getRootView(editorComponent.getTextComponent());
   v.setSize(table.getWidth(), Integer.MAX_VALUE);
   return (int) v.getPreferredSpan(View.Y_AXIS);
 }
Example #11
0
    /**
     * Creates a row of views that will fit within the layout span of the row. This is called by the
     * layout method. This is implemented to fill the row by repeatedly calling the createView
     * method until the available span has been exhausted, a forced break was encountered, or the
     * createView method returned null. If the remaining span was exhaused, the adjustRow method
     * will be called to perform adjustments to the row to try and make it fit into the given span.
     *
     * @param rowIndex the index of the row to fill in with views. The row is assumed to be empty on
     *     entry.
     * @param pos The current position in the children of this views element from which to start.
     * @return the position to start the next row
     */
    protected int layoutRow(FlowView fv, int rowIndex, int pos) {
      View row = fv.getView(rowIndex);
      int x = fv.getFlowStart(rowIndex);
      int spanLeft = fv.getFlowSpan(rowIndex);
      int end = fv.getEndOffset();
      TabExpander te = (fv instanceof TabExpander) ? (TabExpander) fv : null;

      // Indentation.
      int preX = x;
      int availableSpan = spanLeft;
      preX = x;

      final int flowAxis = fv.getFlowAxis();
      boolean forcedBreak = false;
      while (pos < end && spanLeft > 0) {
        View v = createView(fv, pos, spanLeft, rowIndex);
        if (v == null) {
          break;
        }

        int chunkSpan;
        if ((flowAxis == X_AXIS) && (v instanceof TabableView)) {
          chunkSpan = (int) ((TabableView) v).getTabbedSpan(x, te);
        } else {
          chunkSpan = (int) v.getPreferredSpan(flowAxis);
        }

        // If a forced break is necessary, break
        if (v.getBreakWeight(flowAxis, pos, spanLeft) >= ForcedBreakWeight) {
          int n = row.getViewCount();
          if (n > 0) {
            /* If this is a forced break and it's not the only view
             * the view should be replaced with a call to breakView.
             * If it's it only view, it should be used directly.  In
             * either case no more children should be added beyond this
             * view.
             */
            v = v.breakView(flowAxis, pos, x, spanLeft);
            if (v != null) {
              if ((flowAxis == X_AXIS) && (v instanceof TabableView)) {
                chunkSpan = (int) ((TabableView) v).getTabbedSpan(x, te);
              } else {
                chunkSpan = (int) v.getPreferredSpan(flowAxis);
              }
            } else {
              chunkSpan = 0;
            }
          }
          forcedBreak = true;
        }

        spanLeft -= chunkSpan;
        x += chunkSpan;
        if (v != null) {
          row.append(v);
          pos = v.getEndOffset();
        }
        if (forcedBreak) {
          break;
        }
      }
      if (spanLeft < 0) {
        // This row is too long and needs to be adjusted.
        adjustRow(fv, rowIndex, availableSpan, preX);
      } else if (row.getViewCount() == 0) {
        // Impossible spec... put in whatever is left.
        View v = createView(fv, pos, Integer.MAX_VALUE, rowIndex);
        row.append(v);
      }
      return row.getEndOffset();
    }