Example usage for java.awt Graphics2D getFontMetrics

List of usage examples for java.awt Graphics2D getFontMetrics

Introduction

In this page you can find the example usage for java.awt Graphics2D getFontMetrics.

Prototype

public abstract FontMetrics getFontMetrics(Font f);

Source Link

Document

Gets the font metrics for the specified font.

Usage

From source file:net.pms.util.GenericIcons.java

/**
 * Add the format(container) name of the media to the generic icon image.
 *
 * @param image BufferdImage to be the label added
 * @param label the media container name to be added as a label
 * @param renderer the renderer configuration
 *
 * @return the generic icon with the container label added and scaled in accordance with renderer setting
 *///from   w w  w .ja  va2s. c om
private DLNAThumbnail addFormatLabelToImage(String label, ImageFormat imageFormat, IconType iconType)
        throws IOException {

    BufferedImage image;
    switch (iconType) {
    case AUDIO:
        image = genericAudioIcon;
        break;
    case IMAGE:
        image = genericImageIcon;
        break;
    case VIDEO:
        image = genericVideoIcon;
        break;
    default:
        image = genericUnknownIcon;
    }

    if (image != null) {
        // Make a copy
        ColorModel colorModel = image.getColorModel();
        image = new BufferedImage(colorModel, image.copyData(null), colorModel.isAlphaPremultiplied(), null);
    }

    ByteArrayOutputStream out = null;

    if (label != null && image != null) {
        out = new ByteArrayOutputStream();
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        try {
            int size = 40;
            Font font = new Font(Font.SANS_SERIF, Font.BOLD, size);
            FontMetrics metrics = g.getFontMetrics(font);
            while (size > 7 && metrics.stringWidth(label) > 135) {
                size--;
                font = new Font(Font.SANS_SERIF, Font.BOLD, size);
                metrics = g.getFontMetrics(font);
            }
            // Text center point 127x, 49y - calculate centering coordinates
            int x = 127 - metrics.stringWidth(label) / 2;
            int y = 46 + metrics.getAscent() / 2;
            g.drawImage(image, 0, 0, null);
            g.setColor(Color.WHITE);
            g.setFont(font);
            g.drawString(label, x, y);

            ImageIO.setUseCache(false);
            ImageIOTools.imageIOWrite(image, imageFormat.toString(), out);
        } finally {
            g.dispose();
        }
    }
    return out != null ? DLNAThumbnail.toThumbnail(out.toByteArray(), 0, 0, ScaleType.MAX, imageFormat, false)
            : null;
}

From source file:com.igormaznitsa.mindmap.swing.panel.MindMapPanel.java

private static void drawErrorText(final Graphics2D gfx, final Dimension fullSize, final String error) {
    final Font font = new Font(Font.DIALOG, Font.BOLD, 24);
    final FontMetrics metrics = gfx.getFontMetrics(font);
    final Rectangle2D textBounds = metrics.getStringBounds(error, gfx);
    gfx.setFont(font);//from ww w . ja v a2  s. c  o  m
    gfx.setColor(Color.DARK_GRAY);
    gfx.fillRect(0, 0, fullSize.width, fullSize.height);
    final int x = (int) (fullSize.width - textBounds.getWidth()) / 2;
    final int y = (int) (fullSize.height - textBounds.getHeight()) / 2;
    gfx.setColor(Color.BLACK);
    gfx.drawString(error, x + 5, y + 5);
    gfx.setColor(Color.RED.brighter());
    gfx.drawString(error, x, y);
}

From source file:org.jfree.experimental.chart.plot.dial.DialValueIndicator.java

/**
 * Draws the background to the specified graphics device.  If the dial
 * frame specifies a window, the clipping region will already have been 
 * set to this window before this method is called.
 *
 * @param g2  the graphics device (<code>null</code> not permitted).
 * @param plot  the plot (ignored here).
 * @param frame  the dial frame (ignored here).
 * @param view  the view rectangle (<code>null</code> not permitted). 
 *///from w  ww  .  j  av a 2s .  com
public void draw(Graphics2D g2, DialPlot plot, Rectangle2D frame, Rectangle2D view) {

    // work out the anchor point
    Rectangle2D f = DialPlot.rectangleByRadius(frame, this.radius, this.radius);
    Arc2D arc = new Arc2D.Double(f, this.angle, 0.0, Arc2D.OPEN);
    Point2D pt = arc.getStartPoint();

    // calculate the bounds of the template value
    FontMetrics fm = g2.getFontMetrics(this.font);
    String s = this.formatter.format(this.templateValue);
    Rectangle2D tb = TextUtilities.getTextBounds(s, g2, fm);

    // align this rectangle to the frameAnchor
    Rectangle2D bounds = RectangleAnchor.createRectangle(new Size2D(tb.getWidth(), tb.getHeight()), pt.getX(),
            pt.getY(), this.frameAnchor);

    // add the insets
    Rectangle2D fb = this.insets.createOutsetRectangle(bounds);

    // draw the background
    g2.setPaint(this.backgroundPaint);
    g2.fill(fb);

    // draw the border
    g2.setStroke(this.outlineStroke);
    g2.setPaint(this.outlinePaint);
    g2.draw(fb);

    // now find the text anchor point
    double value = plot.getValue(this.datasetIndex);
    String valueStr = this.formatter.format(value);
    Point2D pt2 = RectangleAnchor.coordinates(bounds, this.valueAnchor);
    g2.setPaint(this.paint);
    g2.setFont(this.font);
    TextUtilities.drawAlignedString(valueStr, g2, (float) pt2.getX(), (float) pt2.getY(), this.textAnchor);

}

From source file:net.sf.mzmine.modules.visualization.scatterplot.scatterplotchart.ScatterPlotRenderer.java

/**
 * Draws an item label./*from   w  w  w  .  j  a  v  a 2 s  . c o  m*/
 * 
 * @param g2
 *            the graphics device.
 * @param orientation
 *            the orientation.
 * @param dataset
 *            the dataset.
 * @param series
 *            the series index (zero-based).
 * @param item
 *            the item index (zero-based).
 * @param x
 *            the x coordinate (in Java2D space).
 * @param y
 *            the y coordinate (in Java2D space).
 * @param negative
 *            indicates a negative value (which affects the item label
 *            position).
 */
protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation, XYDataset dataset, int series,
        int item, double x, double y, boolean negative) {

    XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
    Font labelFont = getItemLabelFont(series, item);
    g2.setFont(labelFont);
    String label = generator.generateLabel(dataset, series, item);

    if ((label == null) || (label.length() == 0))
        return;

    // get the label position..
    ItemLabelPosition position = null;
    if (!negative) {
        position = getPositiveItemLabelPosition(series, item);
    } else {
        position = getNegativeItemLabelPosition(series, item);
    }

    // work out the label anchor point...
    Point2D anchorPoint = calculateLabelAnchorPoint(position.getItemLabelAnchor(), x, y, orientation);

    FontMetrics metrics = g2.getFontMetrics(labelFont);
    int width = SwingUtilities.computeStringWidth(metrics, label) + 2;
    int height = metrics.getHeight();

    int X = (int) (anchorPoint.getX() - (width / 2));
    int Y = (int) (anchorPoint.getY() - (height));

    g2.setPaint(searchColor);
    g2.fillRect(X, Y, width, height);

    super.drawItemLabel(g2, orientation, dataset, series, item, x, y, negative);

}

From source file:com.att.aro.ui.view.waterfalltab.WaterfallPanel.java

/**
 * @return the timeAxis//from ww w.  j a v  a 2  s  . co  m
 */
private NumberAxis getTimeAxis() {
    if (timeAxis == null) {
        timeAxis = new NumberAxis(ResourceBundleHelper.getMessageString("waterfall.time")) {
            private static final long serialVersionUID = 1L;

            /**
             * This override prevents the tick units from changing
             * as the timeline is scrolled to numbers with more digits
             */
            @Override
            protected double estimateMaximumTickLabelWidth(Graphics2D g2d, TickUnit unit) {

                if (isVerticalTickLabels()) {
                    return super.estimateMaximumTickLabelWidth(g2d, unit);
                } else {
                    RectangleInsets tickLabelInsets = getTickLabelInsets();
                    double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();

                    // look at lower and upper bounds...
                    FontMetrics fMetrics = g2d.getFontMetrics(getTickLabelFont());
                    double upper = traceDuration;
                    String upperStr = "";
                    NumberFormat formatter = getNumberFormatOverride();
                    if (formatter == null) {
                        upperStr = unit.valueToString(upper);
                    } else {
                        upperStr = formatter.format(upper);
                    }
                    double width2 = fMetrics.stringWidth(upperStr);
                    result += width2;
                    return result;
                }

            }

        };
        timeAxis.setRange(new Range(0, DEFAULT_TIMELINE));
        timeAxis.setStandardTickUnits(units);
    }
    return timeAxis;
}

From source file:org.hyperic.image.chart.Chart.java

protected void initFonts() {
    // Initialize FontMetrics
    Image img = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
    Graphics2D g = (Graphics2D) img.getGraphics();
    m_metricsLabel = g.getFontMetrics(this.font);
    m_metricsLegend = g.getFontMetrics(this.legendFont);
    g.dispose();/*from w  w  w  . j  a v  a 2 s  .  c  o  m*/
}

From source file:org.yccheok.jstock.gui.charting.InvestmentFlowLayerUI.java

private void drawBusyBox(Graphics2D g2, JXLayer<? extends V> layer) {
    final Font oldFont = g2.getFont();
    final Font font = oldFont;
    final FontMetrics fontMetrics = g2.getFontMetrics(font);

    // Not sure why. Draw GIF image on JXLayer, will cause endless setDirty
    // being triggered by system.
    //final Image image = ((ImageIcon)Icons.BUSY).getImage();
    //final int imgWidth = Icons.BUSY.getIconWidth();
    //final int imgHeight = Icons.BUSY.getIconHeight();
    //final int imgMessageWidthMargin = 5;
    final int imgWidth = 0;
    final int imgHeight = 0;
    final int imgMessageWidthMargin = 0;

    final String message = MessagesBundle.getString("info_message_retrieving_latest_stock_price");
    final int maxWidth = imgWidth + imgMessageWidthMargin + fontMetrics.stringWidth(message);
    final int maxHeight = Math.max(imgHeight, fontMetrics.getHeight());

    final int padding = 5;
    final int width = maxWidth + (padding << 1);
    final int height = maxHeight + (padding << 1);
    final int x = (int) this.drawArea.getX() + (((int) this.drawArea.getWidth() - width) >> 1);
    final int y = (int) this.drawArea.getY() + (((int) this.drawArea.getHeight() - height) >> 1);

    final Object oldValueAntiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
    final Composite oldComposite = g2.getComposite();
    final Color oldColor = g2.getColor();

    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(COLOR_BORDER);//w w w. ja  v  a  2  s. co m
    g2.drawRoundRect(x - 1, y - 1, width + 1, height + 1, 15, 15);
    g2.setColor(COLOR_BACKGROUND);
    g2.setComposite(Utils.makeComposite(0.75f));
    g2.fillRoundRect(x, y, width, height, 15, 15);
    g2.setComposite(oldComposite);
    g2.setColor(oldColor);

    //g2.drawImage(image, x + padding, y + ((height - imgHeight) >> 1), layer.getView());

    g2.setFont(font);
    g2.setColor(COLOR_BLUE);

    int yy = y + ((height - fontMetrics.getHeight()) >> 1) + fontMetrics.getAscent();
    g2.setFont(font);
    g2.setColor(COLOR_BLUE);
    g2.drawString(message, x + padding + imgWidth + imgMessageWidthMargin, yy);
    g2.setColor(oldColor);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldValueAntiAlias);
    g2.setFont(oldFont);
}

From source file:au.com.gaiaresources.bdrs.controller.test.TestDataCreator.java

private byte[] createImage(int width, int height, String text) throws IOException {
    if (width < 0) {
        width = random.nextInt(DEFAULT_MAX_IMAGE_WIDTH - DEFAULT_MIN_IMAGE_WIDTH) + DEFAULT_MIN_IMAGE_WIDTH;
    }// w ww  .  ja  v a 2s .  com
    if (height < 0) {
        height = random.nextInt(DEFAULT_MAX_IMAGE_HEIGHT - DEFAULT_MIN_IMAGE_HEIGHT) + DEFAULT_MIN_IMAGE_HEIGHT;
    }

    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2 = (Graphics2D) img.getGraphics();
    g2.setBackground(new Color(220, 220, 220));

    Dimension size;
    float fontSize = g2.getFont().getSize();
    // Make the text as large as possible.
    do {
        g2.setFont(g2.getFont().deriveFont(fontSize));
        FontMetrics metrics = g2.getFontMetrics(g2.getFont());
        int hgt = metrics.getHeight();
        int adv = metrics.stringWidth(text);
        size = new Dimension(adv + 2, hgt + 2);
        fontSize = fontSize + 1f;
    } while (size.width < Math.round(0.9 * width) && size.height < Math.round(0.9 * height));

    g2.setColor(Color.DARK_GRAY);
    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g2.drawString(text, (width - size.width) / 2, (height - size.height) / 2);
    g2.setColor(Color.LIGHT_GRAY);
    g2.drawRect(0, 0, width - 1, height - 1);

    ByteArrayOutputStream baos = new ByteArrayOutputStream(width * height);
    ImageIO.write(img, "png", baos);
    baos.flush();
    byte[] rawBytes = baos.toByteArray();
    baos.close();

    return rawBytes;
}

From source file:org.yccheok.jstock.gui.charting.InvestmentFlowLayerUI.java

private void updateInvestInformationBox(Graphics2D g2) {
    final Font oldFont = g2.getFont();
    final Font paramFont = oldFont;
    final FontMetrics paramFontMetrics = g2.getFontMetrics(paramFont);
    final Font valueFont = oldFont.deriveFont(oldFont.getStyle() | Font.BOLD, (float) oldFont.getSize() + 1);
    final FontMetrics valueFontMetrics = g2.getFontMetrics(valueFont);
    final Font dateFont = oldFont.deriveFont((float) oldFont.getSize() - 1);
    final FontMetrics dateFontMetrics = g2.getFontMetrics(dateFont);

    final Activities activities = this.investmentFlowChartJDialog.getInvestActivities(this.investPointIndex);

    this.investValues.clear();
    this.investParams.clear();
    this.totalInvestValue = 0.0;

    final DecimalPlace decimalPlace = JStock.instance().getJStockOptions().getDecimalPlace();

    for (int i = 0, size = activities.size(); i < size; i++) {
        final Activity activity = activities.get(i);
        // Buy only.
        this.investParams.add(activity.getType() + " "
                + org.yccheok.jstock.portfolio.Utils.toQuantity(activity.get(Activity.Param.Quantity)) + " "
                + ((StockInfo) activity.get(Activity.Param.StockInfo)).symbol);

        if (activity.getType() == Activity.Type.Buy) {
            final StockInfo stockInfo = (StockInfo) activity.get(Activity.Param.StockInfo);

            final double amount = convertToPoundIfNecessary(stockInfo.code, activity.getAmount());
            this.totalInvestValue += amount;
            this.investValues
                    .add(org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace, amount));
        } else {//from w ww  . ja v a 2  s  .c om
            assert (false);
        }
    }

    final boolean isTotalNeeded = this.investParams.size() > 1;
    final String totalParam = GUIBundle.getString("InvestmentFlowLayerUI_Total_Invest");
    final String totalValue = org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace,
            this.totalInvestValue);
    /* This is the height for "total" information. */
    int totalHeight = 0;

    assert (this.investValues.size() == this.investParams.size());

    int index = 0;
    final int paramValueWidthMargin = 10;
    final int paramValueHeightMargin = 0;
    int maxInfoWidth = -1;
    // paramFontMetrics will always "smaller" than valueFontMetrics.
    int totalInfoHeight = Math.max(paramFontMetrics.getHeight(), valueFontMetrics.getHeight())
            * this.investValues.size() + paramValueHeightMargin * (this.investValues.size() - 1);
    for (String param : this.investParams) {
        final String value = this.investValues.get(index++);
        final int paramStringWidth = paramFontMetrics.stringWidth(param + ":") + paramValueWidthMargin
                + valueFontMetrics.stringWidth(value);
        if (maxInfoWidth < paramStringWidth) {
            maxInfoWidth = paramStringWidth;
        }
    }

    if (isTotalNeeded) {
        final int tmp = paramFontMetrics.stringWidth(totalParam + ":") + paramValueWidthMargin
                + valueFontMetrics.stringWidth(totalValue);
        if (maxInfoWidth < tmp) {
            maxInfoWidth = tmp;
        }
        totalHeight = Math.max(paramFontMetrics.getHeight(), valueFontMetrics.getHeight());
    }

    final Date date = activities.getDate().getTime();
    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
    final String dateString = simpleDateFormat.format(date);
    final int dateStringWidth = dateFontMetrics.stringWidth(dateString);
    final int dateStringHeight = dateFontMetrics.getHeight();
    final int maxStringWidth = Math.max(dateStringWidth, maxInfoWidth);
    final int dateInfoHeightMargin = 5;
    final int infoTotalHeightMargin = 5;
    final int maxStringHeight = isTotalNeeded
            ? (dateStringHeight + dateInfoHeightMargin + totalInfoHeight + infoTotalHeightMargin + totalHeight)
            : (dateStringHeight + dateInfoHeightMargin + totalInfoHeight);

    // Now, We have a pretty good information on maxStringWidth and maxStringHeight.

    final int padding = 5;
    final int boxPointMargin = 8;
    final int width = maxStringWidth + (padding << 1);
    final int height = maxStringHeight + (padding << 1);
    // On left side of the ball.
    final int suggestedX = (int) (this.investPoint.getX() - width - boxPointMargin);
    final int suggestedY = (int) (this.investPoint.getY() - (height >> 1));
    final int x = suggestedX > this.drawArea.getX()
            ? (suggestedX + width) < (this.drawArea.getX() + this.drawArea.getWidth()) ? suggestedX
                    : (int) (this.drawArea.getX() + this.drawArea.getWidth() - width - boxPointMargin)
            : (int) (investPoint.getX() + boxPointMargin);
    final int y = suggestedY > this.drawArea.getY()
            ? (suggestedY + height) < (this.drawArea.getY() + this.drawArea.getHeight()) ? suggestedY
                    : (int) (this.drawArea.getY() + this.drawArea.getHeight() - height - boxPointMargin)
            : (int) (this.drawArea.getY() + boxPointMargin);

    this.investRect.setRect(x, y, width, height);
}

From source file:org.yccheok.jstock.gui.charting.InvestmentFlowLayerUI.java

private void updateROIInformationBox(Graphics2D g2) {
    final Font oldFont = g2.getFont();
    final Font paramFont = oldFont;
    final FontMetrics paramFontMetrics = g2.getFontMetrics(paramFont);
    final Font valueFont = oldFont.deriveFont(oldFont.getStyle() | Font.BOLD, (float) oldFont.getSize() + 1);
    final FontMetrics valueFontMetrics = g2.getFontMetrics(valueFont);
    final Font dateFont = oldFont.deriveFont((float) oldFont.getSize() - 1);
    final FontMetrics dateFontMetrics = g2.getFontMetrics(dateFont);

    final Activities activities = this.investmentFlowChartJDialog.getROIActivities(this.ROIPointIndex);

    this.ROIValues.clear();
    this.ROIParams.clear();
    this.totalROIValue = 0.0;

    final DecimalPlace decimalPlace = JStock.instance().getJStockOptions().getDecimalPlace();

    for (int i = 0, size = activities.size(); i < size; i++) {
        final Activity activity = activities.get(i);
        // Buy, Sell or Dividend only.
        if (activity.getType() == Activity.Type.Buy) {
            final double quantity = (Double) activity.get(Activity.Param.Quantity);
            final StockInfo stockInfo = (StockInfo) activity.get(Activity.Param.StockInfo);
            this.ROIParams.add(GUIBundle.getString("InvestmentFlowLayerUI_Own") + " "
                    + org.yccheok.jstock.portfolio.Utils.toQuantity(quantity) + " " + stockInfo.symbol);
            final double amount = convertToPoundIfNecessary(stockInfo.code,
                    quantity * this.investmentFlowChartJDialog.getStockPrice(stockInfo.code));
            this.totalROIValue += amount;
            this.ROIValues.add(org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace, amount));
        } else if (activity.getType() == Activity.Type.Sell) {
            final double quantity = (Double) activity.get(Activity.Param.Quantity);
            final StockInfo stockInfo = (StockInfo) activity.get(Activity.Param.StockInfo);
            this.ROIParams.add(activity.getType() + " "
                    + org.yccheok.jstock.portfolio.Utils.toQuantity(quantity) + " " + stockInfo.symbol);
            final double amount = convertToPoundIfNecessary(stockInfo.code, activity.getAmount());
            this.totalROIValue += amount;
            this.ROIValues.add(org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace, amount));
        } else if (activity.getType() == Activity.Type.Dividend) {
            final StockInfo stockInfo = (StockInfo) activity.get(Activity.Param.StockInfo);
            this.ROIParams.add(activity.getType() + " " + stockInfo.symbol);
            final double amount = activity.getAmount();
            this.totalROIValue += amount;
            this.ROIValues.add(org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace, amount));
        } else {//from   w  ww.ja  v a2  s.c o m
            assert (false);
        }
    }

    final boolean isTotalNeeded = this.ROIParams.size() > 1;
    final String totalParam = GUIBundle.getString("InvestmentFlowLayerUI_Total_Return");
    final String totalValue = org.yccheok.jstock.portfolio.Utils.toCurrencyWithSymbol(decimalPlace,
            this.totalROIValue);
    /* This is the height for "total" information. */
    int totalHeight = 0;

    assert (this.ROIParams.size() == this.ROIValues.size());

    int index = 0;
    final int paramValueWidthMargin = 10;
    final int paramValueHeightMargin = 0;
    int maxInfoWidth = -1;
    // paramFontMetrics will always "smaller" than valueFontMetrics.
    int totalInfoHeight = Math.max(paramFontMetrics.getHeight(), valueFontMetrics.getHeight())
            * this.ROIValues.size() + paramValueHeightMargin * (this.ROIValues.size() - 1);
    for (String param : this.ROIParams) {
        final String value = this.ROIValues.get(index++);
        final int paramStringWidth = paramFontMetrics.stringWidth(param + ":") + paramValueWidthMargin
                + valueFontMetrics.stringWidth(value);
        if (maxInfoWidth < paramStringWidth) {
            maxInfoWidth = paramStringWidth;
        }
    }

    if (isTotalNeeded) {
        final int tmp = paramFontMetrics.stringWidth(totalParam + ":") + paramValueWidthMargin
                + valueFontMetrics.stringWidth(totalValue);
        if (maxInfoWidth < tmp) {
            maxInfoWidth = tmp;
        }
        totalHeight = Math.max(paramFontMetrics.getHeight(), valueFontMetrics.getHeight());
    }

    final Date date = activities.getDate().getTime();
    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
    final String dateString = simpleDateFormat.format(date);
    final int dateStringWidth = dateFontMetrics.stringWidth(dateString);
    final int dateStringHeight = dateFontMetrics.getHeight();
    final int maxStringWidth = Math.max(dateStringWidth, maxInfoWidth);
    final int dateInfoHeightMargin = 5;
    final int infoTotalHeightMargin = 5;
    final int maxStringHeight = isTotalNeeded
            ? (dateStringHeight + dateInfoHeightMargin + totalInfoHeight + infoTotalHeightMargin + totalHeight)
            : (dateStringHeight + dateInfoHeightMargin + totalInfoHeight);

    // Now, We have a pretty good information on maxStringWidth and maxStringHeight.

    final int padding = 5;
    final int boxPointMargin = 8;
    final int width = maxStringWidth + (padding << 1);
    final int height = maxStringHeight + (padding << 1);

    final int borderWidth = width + 2;
    final int borderHeight = height + 2;
    // On left side of the ball.
    final double suggestedBorderX = this.ROIPoint.getX() - borderWidth - boxPointMargin;
    final double suggestedBorderY = this.ROIPoint.getY() - (borderHeight >> 1);
    final double bestBorderX = suggestedBorderX > this.drawArea.getX()
            ? (suggestedBorderX + borderWidth) < (this.drawArea.getX() + this.drawArea.getWidth())
                    ? suggestedBorderX
                    : this.drawArea.getX() + this.drawArea.getWidth() - borderWidth - boxPointMargin
            : this.ROIPoint.getX() + boxPointMargin;
    final double bestBorderY = suggestedBorderY > this.drawArea.getY()
            ? (suggestedBorderY + borderHeight) < (this.drawArea.getY() + this.drawArea.getHeight())
                    ? suggestedBorderY
                    : this.drawArea.getY() + this.drawArea.getHeight() - borderHeight - boxPointMargin
            : this.drawArea.getY() + boxPointMargin;

    final double x = bestBorderX + 1;
    final double y = bestBorderY + 1;

    this.ROIRect.setRect(x, y, width, height);
}