1871 lines · 69.6 KB · Java
RawDownload
                 * Calculate the width on screen, obtain a TextLayout with                 * advances for the printer graphics FRC, and then justify                 * it to fit in the screen width. This distributes the spacing                 * more evenly than directly laying out to the screen advances.                 */                float screenWidth = (float)                   g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth();                TextLayout layout = createTextLayout(c, text, g2d.getFont(),                                                   g2d.getFontRenderContext());                 layout = layout.getJustifiedLayout(screenWidth);                /* Use alternate print color if specified */                Color col = g2d.getColor();                if (col instanceof PrintColorUIResource) {                    g2d.setColor(((PrintColorUIResource)col).getPrintColor());                }                 layout.draw(g2d, x, y);                 g2d.setColor(col);                 return;            }        }         // If we get here we're not printing        AATextInfo info = drawTextAntialiased(c);        if (info != null && (g instanceof Graphics2D)) {            Graphics2D g2 = (Graphics2D)g;             Object oldContrast = null;            Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);            if (info.aaHint != oldAAValue) {                g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);            } else {                oldAAValue = null;            }            if (info.lcdContrastHint != null) {                oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);                if (info.lcdContrastHint.equals(oldContrast)) {                    oldContrast = null;                } else {                    g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,                                        info.lcdContrastHint);                }            }             boolean needsTextLayout = ((c != null) &&                (c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));            if (needsTextLayout) {                synchronized(charsBufferLock) {                    int length = syncCharsBuffer(text);                    needsTextLayout = isComplexLayout(charsBuffer, 0, length);                }            }            if (needsTextLayout) {                TextLayout layout = createTextLayout(c, text, g2.getFont(),                                                    g2.getFontRenderContext());                layout.draw(g2, x, y);            } else {                g.drawString(text, x, y);            }             if (oldAAValue != null) {                g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);            }            if (oldContrast != null) {                g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);            }        }        else {            g.drawString(text, x, y);        }    }      /**     * Draws the string at the specified location underlining the specified     * character.     *     * @param c JComponent that will display the string, may be null     * @param g Graphics to draw the text to     * @param text String to display     * @param underlinedIndex Index of a character in the string to underline     * @param x X coordinate to draw the text at     * @param y Y coordinate to draw the text at     */    public static void drawStringUnderlineCharAt(JComponent c,Graphics g,                           String text, int underlinedIndex, int x,int y) {        if (text == null || text.length() <= 0) {            return;        }        SwingUtilities2.drawString(c, g, text, x, y);        int textLength = text.length();        if (underlinedIndex >= 0 && underlinedIndex < textLength ) {            int underlineRectY = y;            int underlineRectHeight = 1;            int underlineRectX = 0;            int underlineRectWidth = 0;            boolean isPrinting = isPrinting(g);            boolean needsTextLayout = isPrinting;            if (!needsTextLayout) {                synchronized (charsBufferLock) {                    syncCharsBuffer(text);                    needsTextLayout =                        isComplexLayout(charsBuffer, 0, textLength);                }            }            if (!needsTextLayout) {                FontMetrics fm = g.getFontMetrics();                underlineRectX = x +                    SwingUtilities2.stringWidth(c,fm,                                        text.substring(0,underlinedIndex));                underlineRectWidth = fm.charWidth(text.                                                  charAt(underlinedIndex));            } else {                Graphics2D g2d = getGraphics2D(g);                if (g2d != null) {                    TextLayout layout =                        createTextLayout(c, text, g2d.getFont(),                                       g2d.getFontRenderContext());                    if (isPrinting) {                        float screenWidth = (float)g2d.getFont().                            getStringBounds(text, DEFAULT_FRC).getWidth();                        layout = layout.getJustifiedLayout(screenWidth);                    }                    TextHitInfo leading =                        TextHitInfo.leading(underlinedIndex);                    TextHitInfo trailing =                        TextHitInfo.trailing(underlinedIndex);                    Shape shape =                        layout.getVisualHighlightShape(leading, trailing);                    Rectangle rect = shape.getBounds();                    underlineRectX = x + rect.x;                    underlineRectWidth = rect.width;                }            }            g.fillRect(underlineRectX, underlineRectY + 1,                       underlineRectWidth, underlineRectHeight);        }    }      /**     * A variation of locationToIndex() which only returns an index if the     * Point is within the actual bounds of a list item (not just in the cell)     * and if the JList has the "List.isFileList" client property set.     * Otherwise, this method returns -1.     * This is used to make WindowsL&F JFileChooser act like native dialogs.     */    public static int loc2IndexFileList(JList list, Point point) {        int index = list.locationToIndex(point);        if (index != -1) {            Object bySize = list.getClientProperty("List.isFileList");            if (bySize instanceof Boolean && ((Boolean)bySize).booleanValue() &&                !pointIsInActualBounds(list, index, point)) {                index = -1;            }        }        return index;    }      /**     * Returns true if the given point is within the actual bounds of the     * JList item at index (not just inside the cell).     */    private static boolean pointIsInActualBounds(JList list, int index,                                                Point point) {        ListCellRenderer renderer = list.getCellRenderer();        ListModel dataModel = list.getModel();        Object value = dataModel.getElementAt(index);        Component item = renderer.getListCellRendererComponent(list,                          value, index, false, false);        Dimension itemSize = item.getPreferredSize();        Rectangle cellBounds = list.getCellBounds(index, index);        if (!item.getComponentOrientation().isLeftToRight()) {            cellBounds.x += (cellBounds.width - itemSize.width);        }        cellBounds.width = itemSize.width;         return cellBounds.contains(point);    }      /**     * Returns true if the given point is outside the preferredSize of the     * item at the given row of the table.  (Column must be 0).     * Does not check the "Table.isFileList" property. That should be checked     * before calling this method.     * This is used to make WindowsL&F JFileChooser act like native dialogs.     */    public static boolean pointOutsidePrefSize(JTable table, int row, int column, Point p) {        if (table.convertColumnIndexToModel(column) != 0 || row == -1) {            return true;        }        TableCellRenderer tcr = table.getCellRenderer(row, column);        Object value = table.getValueAt(row, column);        Component cell = tcr.getTableCellRendererComponent(table, value, false,                false, row, column);        Dimension itemSize = cell.getPreferredSize();        Rectangle cellBounds = table.getCellRect(row, column, false);        cellBounds.width = itemSize.width;        cellBounds.height = itemSize.height;         // See if coords are inside        // ASSUME: mouse x,y will never be < cell's x,y        assert (p.x >= cellBounds.x && p.y >= cellBounds.y);        return p.x > cellBounds.x + cellBounds.width ||                p.y > cellBounds.y + cellBounds.height;    }     /**     * Set the lead and anchor without affecting selection.     */    public static void setLeadAnchorWithoutSelection(ListSelectionModel model,                                                     int lead, int anchor) {        if (anchor == -1) {            anchor = lead;        }        if (lead == -1) {            model.setAnchorSelectionIndex(-1);            model.setLeadSelectionIndex(-1);        } else {            if (model.isSelectedIndex(lead)) {                model.addSelectionInterval(lead, lead);            } else {                model.removeSelectionInterval(lead, lead);            }            model.setAnchorSelectionIndex(anchor);        }    }     /**     * Ignore mouse events if the component is null, not enabled, the event     * is not associated with the left mouse button, or the event has been     * consumed.     */    public static boolean shouldIgnore(MouseEvent me, JComponent c) {        return c == null || !c.isEnabled()                         || !SwingUtilities.isLeftMouseButton(me)                         || me.isConsumed();    }     /**     * Request focus on the given component if it doesn't already have it     * and <code>isRequestFocusEnabled()</code> returns true.     */    public static void adjustFocus(JComponent c) {        if (!c.hasFocus() && c.isRequestFocusEnabled()) {            c.requestFocus();        }    }     /**     * The following draw functions have the same semantic as the     * Graphics methods with the same names.     *     * this is used for printing     */    public static int drawChars(JComponent c, Graphics g,                                 char[] data,                                 int offset,                                 int length,                                 int x,                                 int y) {        if ( length <= 0 ) { //no need to paint empty strings            return x;        }        int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length);        if (isPrinting(g)) {            Graphics2D g2d = getGraphics2D(g);            if (g2d != null) {                FontRenderContext deviceFontRenderContext = g2d.                    getFontRenderContext();                FontRenderContext frc = getFontRenderContext(c);                if (frc != null &&                    !isFontRenderContextPrintCompatible                    (deviceFontRenderContext, frc)) {                    TextLayout layout =                        createTextLayout(c, new String(data, offset, length),                                       g2d.getFont(),                                       deviceFontRenderContext);                    float screenWidth = (float)g2d.getFont().                        getStringBounds(data, offset, offset + length, frc).                        getWidth();                    layout = layout.getJustifiedLayout(screenWidth);                     /* Use alternate print color if specified */                    Color col = g2d.getColor();                    if (col instanceof PrintColorUIResource) {                        g2d.setColor(((PrintColorUIResource)col).getPrintColor());                    }                     layout.draw(g2d,x,y);                     g2d.setColor(col);                     return nextX;                }            }        }        // Assume we're not printing if we get here, or that we are invoked        // via Swing text printing which is laid out for the printer.        AATextInfo info = drawTextAntialiased(c);        if (info != null && (g instanceof Graphics2D)) {            Graphics2D g2 = (Graphics2D)g;             Object oldContrast = null;            Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);            if (info.aaHint != null && info.aaHint != oldAAValue) {                g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);            } else {                oldAAValue = null;            }            if (info.lcdContrastHint != null) {                oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);                if (info.lcdContrastHint.equals(oldContrast)) {                    oldContrast = null;                } else {                    g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,                                        info.lcdContrastHint);                }            }             g.drawChars(data, offset, length, x, y);             if (oldAAValue != null) {                g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);            }            if (oldContrast != null) {                g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);            }        }        else {            g.drawChars(data, offset, length, x, y);        }        return nextX;    }     /*     * see documentation for drawChars     * returns the advance     */    public static float drawString(JComponent c, Graphics g,                                   AttributedCharacterIterator iterator,                                   int x,                                   int y) {         float retVal;        boolean isPrinting = isPrinting(g);        Color col = g.getColor();         if (isPrinting) {            /* Use alternate print color if specified */            if (col instanceof PrintColorUIResource) {                g.setColor(((PrintColorUIResource)col).getPrintColor());            }        }         Graphics2D g2d = getGraphics2D(g);        if (g2d == null) {            g.drawString(iterator,x,y); //for the cases where advance                                        //matters it should not happen            retVal = x;         } else {            FontRenderContext frc;            if (isPrinting) {                frc = getFontRenderContext(c);                if (frc.isAntiAliased() || frc.usesFractionalMetrics()) {                    frc = new FontRenderContext(frc.getTransform(), false, false);                }            } else if ((frc = getFRCProperty(c)) != null) {                /* frc = frc; ! */            } else {                frc = g2d.getFontRenderContext();            }            TextLayout layout = new TextLayout(iterator, frc);            if (isPrinting) {                FontRenderContext deviceFRC = g2d.getFontRenderContext();                if (!isFontRenderContextPrintCompatible(frc, deviceFRC)) {                    float screenWidth = layout.getAdvance();                    layout = new TextLayout(iterator, deviceFRC);                    layout = layout.getJustifiedLayout(screenWidth);                }            }            layout.draw(g2d, x, y);            retVal = layout.getAdvance();        }         if (isPrinting) {            g.setColor(col);        }         return retVal;    }     private static TextLayout createTextLayout(JComponent c, String s,                                            Font f, FontRenderContext frc) {        Object shaper = (c == null ?                    null : c.getClientProperty(TextAttribute.NUMERIC_SHAPING));        if (shaper == null) {            return new TextLayout(s, f, frc);        } else {            Map<TextAttribute, Object> a = new HashMap<TextAttribute, Object>();            a.put(TextAttribute.FONT, f);            a.put(TextAttribute.NUMERIC_SHAPING, shaper);            return new TextLayout(s, a, frc);        }    }     /*     * Checks if two given FontRenderContexts are compatible for printing.     * We can't just use equals as we want to exclude from the comparison :     * + whether AA is set as irrelevant for printing and shouldn't affect     * printed metrics anyway     * + any translation component in the transform of either FRC, as it     * does not affect metrics.     * Compatible means no special handling needed for text painting     */    private static boolean        isFontRenderContextPrintCompatible(FontRenderContext frc1,                                           FontRenderContext frc2) {         if (frc1 == frc2) {            return true;        }         if (frc1 == null || frc2 == null) { // not supposed to happen            return false;        }         if (frc1.getFractionalMetricsHint() !=            frc2.getFractionalMetricsHint()) {            return false;        }         /* If both are identity, return true */        if (!frc1.isTransformed() && !frc2.isTransformed()) {            return true;        }         /* That's the end of the cheap tests, need to get and compare         * the transform matrices. We don't care about the translation         * components, so return true if they are otherwise identical.         */        double[] mat1 = new double[4];        double[] mat2 = new double[4];        frc1.getTransform().getMatrix(mat1);        frc2.getTransform().getMatrix(mat2);        return            mat1[0] == mat2[0] &&            mat1[1] == mat2[1] &&            mat1[2] == mat2[2] &&            mat1[3] == mat2[3];    }     /*     * Tries it best to get Graphics2D out of the given Graphics     * returns null if can not derive it.     */    public static Graphics2D getGraphics2D(Graphics g) {        if (g instanceof Graphics2D) {            return (Graphics2D) g;        } else if (g instanceof ProxyPrintGraphics) {            return (Graphics2D)(((ProxyPrintGraphics)g).getGraphics());        } else {            return null;        }    }     /*     * Returns FontRenderContext associated with Component.     * FontRenderContext from Component.getFontMetrics is associated     * with the component.     *     * Uses Component.getFontMetrics to get the FontRenderContext from.     * see JComponent.getFontMetrics and TextLayoutStrategy.java     */    public static FontRenderContext getFontRenderContext(Component c) {        assert c != null;        if (c == null) {            return DEFAULT_FRC;        } else {            return c.getFontMetrics(c.getFont()).getFontRenderContext();        }    }     /**     * A convenience method to get FontRenderContext.     * Returns the FontRenderContext for the passed in FontMetrics or     * for the passed in Component if FontMetrics is null     */    private static FontRenderContext getFontRenderContext(Component c, FontMetrics fm) {        assert fm != null || c!= null;        return (fm != null) ? fm.getFontRenderContext()            : getFontRenderContext(c);    } 

Lines 501–1000 of 1871. Previous lines