public void paint(Graphics g) { m_fm = g.getFontMetrics(); g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight()); g.setColor(getForeground()); g.setFont(getFont()); m_insets = getInsets(); int x = m_insets.left; int y = m_insets.top + m_fm.getAscent(); StringTokenizer st = new StringTokenizer(getText(), "\t"); while (st.hasMoreTokens()) { String sNext = st.nextToken(); g.drawString(sNext, x, y); x += m_fm.stringWidth(sNext); if (!st.hasMoreTokens()) break; int index = 0; while (x >= getTab(index)) index++; x = getTab(index); } }
@Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { textLabel.setFont(table.getFont()); textLabel.setText(Objects.toString(value, "")); textLabel.setBorder(hasFocus ? focusCellHighlightBorder : noFocusBorder); FontMetrics fm = table.getFontMetrics(table.getFont()); Insets i = textLabel.getInsets(); int swidth = iconLabel.getPreferredSize().width + fm.stringWidth(textLabel.getText()) + i.left + i.right; int cwidth = table.getColumnModel().getColumn(column).getWidth(); dim.width = swidth > cwidth ? cwidth : swidth; if (isSelected) { textLabel.setOpaque(true); textLabel.setForeground(table.getSelectionForeground()); textLabel.setBackground(table.getSelectionBackground()); iconLabel.setIcon(sicon); } else { textLabel.setOpaque(false); textLabel.setForeground(table.getForeground()); textLabel.setBackground(table.getBackground()); iconLabel.setIcon(nicon); } return panel; }
private static int getAquaTabbedPaneBaseline(JTabbedPane tp, int height) { Font font = tp.getFont(); FontMetrics metrics = tp.getFontMetrics(font); int ascent = metrics.getAscent(); int offset; switch (tp.getTabPlacement()) { case JTabbedPane.TOP: offset = 5; if (tp.getFont().getSize() > 12) { offset = 6; } int yOffset = 20 - metrics.getHeight(); yOffset /= 2; return offset + yOffset + ascent - 1; case JTabbedPane.BOTTOM: if (tp.getFont().getSize() > 12) { offset = 6; } else { offset = 4; } return height - (20 - ((20 - metrics.getHeight()) / 2 + ascent)) - offset; case JTabbedPane.LEFT: case JTabbedPane.RIGHT: // Aqua rotates left/right text, so that there isn't a good // baseline. return -1; } return -1; }
/** Returns the baseline for buttons. */ private static int getButtonBaseline(AbstractButton button, int height) { FontMetrics fm = button.getFontMetrics(button.getFont()); resetRects(button, height); String text = button.getText(); if (text != null && text.startsWith("<html>")) { return -1; } // NOTE: that we use "a" here to make sure we get a valid value, if // we were to pass in an empty string or null we would not get // back the right thing. SwingUtilities.layoutCompoundLabel( button, fm, "a", button.getIcon(), button.getVerticalAlignment(), button.getHorizontalAlignment(), button.getVerticalTextPosition(), button.getHorizontalTextPosition(), viewRect, iconRect, textRect, text == null ? 0 : button.getIconTextGap()); if (isAqua()) { return textRect.y + fm.getAscent() + 1; } return textRect.y + fm.getAscent(); }
public void paintComponent(Graphics g) { g.setColor(new Color(96, 96, 96)); image.paintIcon(this, g, 1, 1); FontMetrics fm = g.getFontMetrics(); String[] args = {jEdit.getVersion()}; String version = jEdit.getProperty("about.version", args); g.drawString(version, (getWidth() - fm.stringWidth(version)) / 2, getHeight() - 5); g = g.create((getWidth() - maxWidth) / 2, TOP, maxWidth, getHeight() - TOP - BOTTOM); int height = fm.getHeight(); int firstLine = scrollPosition / height; int firstLineOffset = height - scrollPosition % height; int lines = (getHeight() - TOP - BOTTOM) / height; int y = firstLineOffset; for (int i = 0; i <= lines; i++) { if (i + firstLine >= 0 && i + firstLine < text.size()) { String line = (String) text.get(i + firstLine); g.drawString(line, (maxWidth - fm.stringWidth(line)) / 2, y); } y += fm.getHeight(); } }
/** * As of Java 2 platform v 1.4 this method should not be used or overriden. Use the paintText * method which takes the AbstractButton argument. */ protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) { AbstractButton b = (AbstractButton) c; ButtonModel model = b.getModel(); FontMetrics fm = SwingUtilities2.getFontMetrics(c, g); int mnemonicIndex = b.getDisplayedMnemonicIndex(); /* Draw the Text */ if (model.isEnabled()) { /** * paint the text normally */ g.setColor(b.getForeground()); SwingUtilities2.drawStringUnderlineCharAt( c, g, text, mnemonicIndex, textRect.x + getTextShiftOffset(), textRect.y + fm.getAscent() + getTextShiftOffset()); } else { /** * paint the text disabled ** */ g.setColor(b.getBackground().brighter()); SwingUtilities2.drawStringUnderlineCharAt( c, g, text, mnemonicIndex, textRect.x, textRect.y + fm.getAscent()); g.setColor(b.getBackground().darker()); SwingUtilities2.drawStringUnderlineCharAt( c, g, text, mnemonicIndex, textRect.x - 1, textRect.y + fm.getAscent() - 1); } }
public Rectangle getVisualBounds(JComponent c, int type, int width, int height) { Rectangle bounds = new Rectangle(0, 0, width, height); if (type == VisuallyLayoutable.CLIP_BOUNDS) { return bounds; } AbstractButton b = (AbstractButton) c; if (type == VisuallyLayoutable.COMPONENT_BOUNDS && b.getBorder() != null && b.isBorderPainted()) { Border border = b.getBorder(); if (border instanceof BackgroundBorder) { border = ((BackgroundBorder) border).getBackgroundBorder(); if (border instanceof VisualMargin) { InsetsUtil.subtractInto(((VisualMargin) border).getVisualMargin(c), bounds); } else if (border instanceof QuaquaButtonBorder) { InsetsUtil.subtractInto(((QuaquaButtonBorder) border).getVisualMargin(c), bounds); } } return bounds; } String text = b.getText(); boolean isEmpty = (text == null || text.length() == 0); if (isEmpty) { text = " "; } Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon(); if ((icon == null) && (text == null)) { return null; } FontMetrics fm = c.getFontMetrics(c.getFont()); Insets insets = c.getInsets(viewInsets); viewR.x = insets.left; viewR.y = insets.top; viewR.width = width - (insets.left + insets.right); viewR.height = height - (insets.top + insets.bottom); iconR.x = iconR.y = iconR.width = iconR.height = 0; textR.x = textR.y = textR.width = textR.height = 0; String clippedText = layoutCL(b, fm, text, icon, viewR, iconR, textR); Rectangle textBounds = Fonts.getPerceivedBounds(text, c.getFont(), c); if (isEmpty) { textBounds.width = 0; } int ascent = fm.getAscent(); textR.x += textBounds.x; textR.width = textBounds.width; textR.y += ascent + textBounds.y; textR.height -= fm.getHeight() - textBounds.height; bounds.setBounds(textR); return bounds; }
/** * Method which renders the text of the current button. * * <p> * * @param g Graphics context * @param b Current button to render * @param textRect Bounding rectangle to render the text. * @param text String to render * @since 1.4 */ @Override protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { ButtonModel model = b.getModel(); FontMetrics fm = g.getFontMetrics(); int mnemonicIndex = Methods.invokeGetter(b, "getDisplayedMnemonicIndex", -1); boolean borderHasPressedCue = borderHasPressedCue(b); /* Draw the Text */ if (model.isPressed() && model.isArmed() && !borderHasPressedCue) { g.setColor(new Color(0xa0000000, true)); QuaquaUtilities.drawStringUnderlineCharAt( g, text, mnemonicIndex, textRect.x + getTextShiftOffset(), textRect.y + fm.getAscent() + getTextShiftOffset() + 1); } if (model.isEnabled()) { /** * paint the text normally */ g.setColor(b.getForeground()); } else { Color c = UIManager.getColor(getPropertyPrefix() + "disabledForeground"); g.setColor((c != null) ? c : b.getForeground()); } QuaquaUtilities.drawStringUnderlineCharAt( g, text, mnemonicIndex, textRect.x + getTextShiftOffset(), textRect.y + fm.getAscent() + getTextShiftOffset()); }
public ColorPane() { super(); Font font = new Font("Monospaced", Font.PLAIN, 12); FontMetrics fm = getFontMetrics(font); lineHeight = fm.getHeight(); setFont(font); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); }
/** * Returns the baseline. * * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @see javax.swing.JComponent#getBaseline(int, int) * @since 1.6 */ public int getBaseline(JComponent c, int width, int height) { super.getBaseline(c, width, height); AbstractButton b = (AbstractButton) c; String text = b.getText(); if (text == null || "".equals(text)) { return -1; } FontMetrics fm = b.getFontMetrics(b.getFont()); layout(b, fm, width, height); return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(), textRect.width, textRect.height); }
private static int getPanelBaseline(JPanel panel, int height) { Border border = panel.getBorder(); if (border instanceof TitledBorder) { TitledBorder titledBorder = (TitledBorder) border; if (titledBorder.getTitle() != null && !"".equals(titledBorder.getTitle())) { Font font = titledBorder.getTitleFont(); if (font == null) { font = panel.getFont(); if (font == null) { font = new Font("Dialog", Font.PLAIN, 12); } } Border border2 = titledBorder.getBorder(); Insets borderInsets; if (border2 != null) { borderInsets = border2.getBorderInsets(panel); } else { borderInsets = EMPTY_INSETS; } FontMetrics fm = panel.getFontMetrics(font); int fontHeight = fm.getHeight(); int descent = fm.getDescent(); int ascent = fm.getAscent(); int y = EDGE_SPACING; int h = height - EDGE_SPACING * 2; int diff; switch (((TitledBorder) border).getTitlePosition()) { case TitledBorder.ABOVE_TOP: diff = ascent + descent + (Math.max(EDGE_SPACING, TEXT_SPACING * 2) - EDGE_SPACING); return y + diff - (descent + TEXT_SPACING); case TitledBorder.TOP: case TitledBorder.DEFAULT_POSITION: diff = Math.max(0, ((ascent / 2) + TEXT_SPACING) - EDGE_SPACING); return (y + diff - descent) + (borderInsets.top + ascent + descent) / 2; case TitledBorder.BELOW_TOP: return y + borderInsets.top + ascent + TEXT_SPACING; case TitledBorder.ABOVE_BOTTOM: return (y + h) - (borderInsets.bottom + descent + TEXT_SPACING); case TitledBorder.BOTTOM: h -= fontHeight / 2; return ((y + h) - descent) + ((ascent + descent) - borderInsets.bottom) / 2; case TitledBorder.BELOW_BOTTOM: h -= fontHeight; return y + h + ascent + TEXT_SPACING; } } } return -1; }
public void run() { FontMetrics fm = getFontMetrics(getFont()); int max = (text.size() * fm.getHeight()); while (running) { scrollPosition += 2; if (scrollPosition > max) scrollPosition = -250; try { Thread.sleep(100); } catch (Exception e) { } repaint(getWidth() / 2 - maxWidth, TOP, maxWidth * 2, getHeight() - TOP - BOTTOM); } }
private static int getProgressBarBaseline(JProgressBar pb, int height) { if (pb.isStringPainted() && pb.getOrientation() == JProgressBar.HORIZONTAL) { FontMetrics metrics = pb.getFontMetrics(pb.getFont()); Insets insets = pb.getInsets(); int y = insets.top; if (isWindows() && isXP()) { if (pb.isIndeterminate()) { y = -1; height--; } else { y = 0; height -= 3; } } else if (isGTK()) { return (height - metrics.getAscent() - metrics.getDescent()) / 2 + metrics.getAscent(); } else if (isAqua()) { if (pb.isIndeterminate()) { // Aqua doesn't appear to support text on indeterminate // progress bars. return -1; } y -= 1; height -= (insets.top + insets.bottom); } else { height -= insets.top + insets.bottom; } return y + (height + metrics.getAscent() - metrics.getLeading() - metrics.getDescent()) / 2; } return -1; }
/** 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; }
private static int getSpinnerBaseline(JSpinner spinner, int height) { JComponent editor = spinner.getEditor(); if (editor instanceof JSpinner.DefaultEditor) { JSpinner.DefaultEditor defaultEditor = (JSpinner.DefaultEditor) editor; JTextField tf = defaultEditor.getTextField(); Insets spinnerInsets = spinner.getInsets(); Insets editorInsets = defaultEditor.getInsets(); int offset = spinnerInsets.top + editorInsets.top; height -= (offset + spinnerInsets.bottom + editorInsets.bottom); if (height <= 0) { return -1; } return offset + getSingleLineTextBaseline(tf, height); } Insets insets = spinner.getInsets(); FontMetrics fm = spinner.getFontMetrics(spinner.getFont()); return insets.top + fm.getAscent(); }
/* * 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; }
public Dimension minimumLayoutSize(Container c) { // Compute width. int width = 30; if (frame.isClosable()) { width += 21; } if (frame.isMaximizable()) { width += 16 + (frame.isClosable() ? 10 : 4); } if (frame.isIconifiable()) { width += 16 + (frame.isMaximizable() ? 2 : (frame.isClosable() ? 10 : 4)); } FontMetrics fm = frame.getFontMetrics(getFont()); String frameTitle = frame.getTitle(); int title_w = frameTitle != null ? SwingUtilities2.stringWidth(frame, fm, frameTitle) : 0; int title_length = frameTitle != null ? frameTitle.length() : 0; if (title_length > 2) { int subtitle_w = SwingUtilities2.stringWidth(frame, fm, frame.getTitle().substring(0, 2) + "..."); width += (title_w < subtitle_w) ? title_w : subtitle_w; } else { width += title_w; } // Compute height. int height = 0; if (isPalette) { height = paletteTitleHeight; } else { int fontHeight = fm.getHeight(); fontHeight += 7; Icon icon = frame.getFrameIcon(); int iconHeight = 0; if (icon != null) { // SystemMenuBar forces the icon to be 16x16 or less. iconHeight = Math.min(icon.getIconHeight(), 16); } iconHeight += 5; height = Math.max(fontHeight, iconHeight); } return new Dimension(width, height); }
/** 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); } }
private static int getComboBoxBaseline(JComboBox combobox, int height) { Insets insets = combobox.getInsets(); int y = insets.top; height -= (insets.top + insets.bottom); if (combobox.isEditable()) { ComboBoxEditor editor = combobox.getEditor(); if (editor != null && (editor.getEditorComponent() instanceof JTextField)) { JTextField tf = (JTextField) editor.getEditorComponent(); return y + getSingleLineTextBaseline(tf, height); } } // Use the renderer to calculate baseline if (isMetal()) { if (isOceanTheme()) { y += 2; height -= 4; } } else if (isWindows()) { // This doesn't guarantee an XP style will be active, // but we don't offer public API to detect if XP is active. String osVersion = System.getProperty("os.version"); if (osVersion != null) { Float version = Float.valueOf(osVersion); if (version.floatValue() > 4.0) { y += 2; height -= 4; } } } ListCellRenderer renderer = combobox.getRenderer(); if (renderer instanceof JLabel) { int baseline = y + getLabelBaseline((JLabel) renderer, height); if (isAqua()) { return baseline - 1; } return baseline; } // Renderer isn't a label, use metrics directly. FontMetrics fm = combobox.getFontMetrics(combobox.getFont()); return y + fm.getAscent(); }
/** * 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; } } }
private static int getLabelBaseline(JLabel label, int height) { Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon(); FontMetrics fm = label.getFontMetrics(label.getFont()); resetRects(label, height); SwingUtilities.layoutCompoundLabel( label, fm, "a", icon, label.getVerticalAlignment(), label.getHorizontalAlignment(), label.getVerticalTextPosition(), label.getHorizontalTextPosition(), viewRect, iconRect, textRect, label.getIconTextGap()); return textRect.y + fm.getAscent(); }
public void paintLogo(Component c, Graphics g, int x, int y, int w, int h) { if (hasLogo(c)) { Graphics2D g2D = (Graphics2D) g; Font savedFont = g2D.getFont(); g.setFont(logoFont); FontMetrics fm = JTattooUtilities.getFontMetrics((JComponent) c, g, c.getFont()); String logo = JTattooUtilities.getClippedText( AbstractLookAndFeel.getTheme().getLogoString(), fm, h - 16); AffineTransform savedTransform = g2D.getTransform(); Color fc = getLogoColorHi(); Color bc = getLogoColorLo(); if (JTattooUtilities.isLeftToRight(c)) { g2D.translate(fm.getAscent() + 1, h - shadowSize - 4); g2D.rotate(Math.toRadians(-90)); g2D.setColor(bc); JTattooUtilities.drawString((JComponent) c, g, logo, 0, 1); g2D.setColor(fc); JTattooUtilities.drawString((JComponent) c, g, logo, 1, 0); } else { g2D.translate(w - shadowSize - 4, h - shadowSize - 4); g2D.rotate(Math.toRadians(-90)); g2D.setColor(bc); JTattooUtilities.drawString((JComponent) c, g, logo, 0, 1); g2D.setColor(fc); JTattooUtilities.drawString((JComponent) c, g, logo, 1, 0); } g2D.setTransform(savedTransform); g2D.setFont(savedFont); } }
AboutPanel() { setFont(UIManager.getFont("Label.font")); fm = getFontMetrics(getFont()); setForeground(new Color(96, 96, 96)); image = new ImageIcon(getClass().getResource("/org/gjt/sp/jedit/icons/about.png")); setBorder(new MatteBorder(1, 1, 1, 1, Color.gray)); text = new Vector(50); StringTokenizer st = new StringTokenizer(jEdit.getProperty("about.text"), "\n"); while (st.hasMoreTokens()) { String line = st.nextToken(); text.addElement(line); maxWidth = Math.max(maxWidth, fm.stringWidth(line) + 10); } scrollPosition = -250; thread = new AnimationThread(); }
public void paintComponent(Graphics g) { if (isPalette) { paintPalette(g); return; } boolean leftToRight = MetalUtils.isLeftToRight(frame); boolean isSelected = frame.isSelected(); int width = getWidth(); int height = getHeight(); Color background = null; Color foreground = null; Color shadow = null; MetalBumps bumps; String gradientKey; if (isSelected) { if (!MetalLookAndFeel.usingOcean()) { closeButton.setContentAreaFilled(true); maxButton.setContentAreaFilled(true); iconButton.setContentAreaFilled(true); } if (selectedBackgroundKey != null) { background = UIManager.getColor(selectedBackgroundKey); } if (background == null) { background = MetalLookAndFeel.getWindowTitleBackground(); } if (selectedForegroundKey != null) { foreground = UIManager.getColor(selectedForegroundKey); } if (selectedShadowKey != null) { shadow = UIManager.getColor(selectedShadowKey); } if (shadow == null) { shadow = MetalLookAndFeel.getPrimaryControlDarkShadow(); } if (foreground == null) { foreground = MetalLookAndFeel.getWindowTitleForeground(); } activeBumps.setBumpColors( activeBumpsHighlight, activeBumpsShadow, UIManager.get("InternalFrame.activeTitleGradient") != null ? null : background); bumps = activeBumps; gradientKey = "InternalFrame.activeTitleGradient"; } else { if (!MetalLookAndFeel.usingOcean()) { closeButton.setContentAreaFilled(false); maxButton.setContentAreaFilled(false); iconButton.setContentAreaFilled(false); } background = MetalLookAndFeel.getWindowTitleInactiveBackground(); foreground = MetalLookAndFeel.getWindowTitleInactiveForeground(); shadow = MetalLookAndFeel.getControlDarkShadow(); bumps = inactiveBumps; gradientKey = "InternalFrame.inactiveTitleGradient"; } if (!MetalUtils.drawGradient(this, g, gradientKey, 0, 0, width, height, true)) { g.setColor(background); g.fillRect(0, 0, width, height); } g.setColor(shadow); g.drawLine(0, height - 1, width, height - 1); g.drawLine(0, 0, 0, 0); g.drawLine(width - 1, 0, width - 1, 0); int titleLength = 0; int xOffset = leftToRight ? 5 : width - 5; String frameTitle = frame.getTitle(); Icon icon = frame.getFrameIcon(); if (icon != null) { if (!leftToRight) xOffset -= icon.getIconWidth(); int iconY = ((height / 2) - (icon.getIconHeight() / 2)); icon.paintIcon(frame, g, xOffset, iconY); xOffset += leftToRight ? icon.getIconWidth() + 5 : -5; } if (frameTitle != null) { Font f = getFont(); g.setFont(f); FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g, f); int fHeight = fm.getHeight(); g.setColor(foreground); int yOffset = ((height - fm.getHeight()) / 2) + fm.getAscent(); Rectangle rect = new Rectangle(0, 0, 0, 0); if (frame.isIconifiable()) { rect = iconButton.getBounds(); } else if (frame.isMaximizable()) { rect = maxButton.getBounds(); } else if (frame.isClosable()) { rect = closeButton.getBounds(); } int titleW; if (leftToRight) { if (rect.x == 0) { rect.x = frame.getWidth() - frame.getInsets().right - 2; } titleW = rect.x - xOffset - 4; frameTitle = getTitle(frameTitle, fm, titleW); } else { titleW = xOffset - rect.x - rect.width - 4; frameTitle = getTitle(frameTitle, fm, titleW); xOffset -= SwingUtilities2.stringWidth(frame, fm, frameTitle); } titleLength = SwingUtilities2.stringWidth(frame, fm, frameTitle); SwingUtilities2.drawString(frame, g, frameTitle, xOffset, yOffset); xOffset += leftToRight ? titleLength + 5 : -5; } int bumpXOffset; int bumpLength; if (leftToRight) { bumpLength = width - buttonsWidth - xOffset - 5; bumpXOffset = xOffset; } else { bumpLength = xOffset - buttonsWidth - 5; bumpXOffset = buttonsWidth + 5; } int bumpYOffset = 3; int bumpHeight = getHeight() - (2 * bumpYOffset); bumps.setBumpArea(bumpLength, bumpHeight); bumps.paintIcon(this, g, bumpXOffset, bumpYOffset); }
@Override public void paintComponent(Graphics g) { super.paintComponent(g); int width = getWidth() - rightMargin - leftMargin - 10; int height = getHeight() - topMargin - bottomMargin; if (width <= 0 || height <= 0) { // not enough room to paint anything return; } Color oldColor = g.getColor(); Font oldFont = g.getFont(); Color fg = getForeground(); Color bg = getBackground(); boolean bgIsLight = (bg.getRed() > 200 && bg.getGreen() > 200 && bg.getBlue() > 200); ((Graphics2D) g) .setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (smallFont == null) { smallFont = oldFont.deriveFont(9.0F); } r.x = leftMargin - 5; r.y = topMargin - 8; r.width = getWidth() - leftMargin - rightMargin; r.height = getHeight() - topMargin - bottomMargin + 16; if (border == null) { // By setting colors here, we avoid recalculating them // over and over. border = new BevelBorder( BevelBorder.LOWERED, getBackground().brighter().brighter(), getBackground().brighter(), getBackground().darker().darker(), getBackground().darker()); } border.paintBorder(this, g, r.x, r.y, r.width, r.height); // Fill background color g.setColor(bgColor); g.fillRect(r.x + 2, r.y + 2, r.width - 4, r.height - 4); g.setColor(oldColor); long tMin = Long.MAX_VALUE; long tMax = Long.MIN_VALUE; long vMin = Long.MAX_VALUE; long vMax = 1; int w = getWidth() - rightMargin - leftMargin - 10; int h = getHeight() - topMargin - bottomMargin; if (times.size > 1) { tMin = Math.min(tMin, times.time(0)); tMax = Math.max(tMax, times.time(times.size - 1)); } long viewRangeMS; if (viewRange > 0) { viewRangeMS = viewRange * MINUTE; } else { // Display full time range, but no less than a minute viewRangeMS = Math.max(tMax - tMin, 1 * MINUTE); } // Calculate min/max values for (Sequence seq : seqs) { if (seq.size > 0) { for (int i = 0; i < seq.size; i++) { if (seq.size == 1 || times.time(i) >= tMax - viewRangeMS) { long val = seq.value(i); if (val > Long.MIN_VALUE) { vMax = Math.max(vMax, val); vMin = Math.min(vMin, val); } } } } else { vMin = 0L; } if (unit == Unit.BYTES || !seq.isPlotted) { // We'll scale only to the first (main) value set. // TODO: Use a separate property for this. break; } } // Normalize scale vMax = normalizeMax(vMax); if (vMin > 0) { if (vMax / vMin > 4) { vMin = 0; } else { vMin = normalizeMin(vMin); } } g.setColor(fg); // Axes // Draw vertical axis int x = leftMargin - 18; int y = topMargin; FontMetrics fm = g.getFontMetrics(); g.drawLine(x, y, x, y + h); int n = 5; if (("" + vMax).startsWith("2")) { n = 4; } else if (("" + vMax).startsWith("3")) { n = 6; } else if (("" + vMax).startsWith("4")) { n = 4; } else if (("" + vMax).startsWith("6")) { n = 6; } else if (("" + vMax).startsWith("7")) { n = 7; } else if (("" + vMax).startsWith("8")) { n = 8; } else if (("" + vMax).startsWith("9")) { n = 3; } // Ticks ArrayList<Long> tickValues = new ArrayList<Long>(); tickValues.add(vMin); for (int i = 0; i < n; i++) { long v = i * vMax / n; if (v > vMin) { tickValues.add(v); } } tickValues.add(vMax); n = tickValues.size(); String[] tickStrings = new String[n]; for (int i = 0; i < n; i++) { long v = tickValues.get(i); tickStrings[i] = getSizeString(v, vMax); } // Trim trailing decimal zeroes. if (decimals > 0) { boolean trimLast = true; boolean removedDecimalPoint = false; do { for (String str : tickStrings) { if (!(str.endsWith("0") || str.endsWith("."))) { trimLast = false; break; } } if (trimLast) { if (tickStrings[0].endsWith(".")) { removedDecimalPoint = true; } for (int i = 0; i < n; i++) { String str = tickStrings[i]; tickStrings[i] = str.substring(0, str.length() - 1); } } } while (trimLast && !removedDecimalPoint); } // Draw ticks int lastY = Integer.MAX_VALUE; for (int i = 0; i < n; i++) { long v = tickValues.get(i); y = topMargin + h - (int) (h * (v - vMin) / (vMax - vMin)); g.drawLine(x - 2, y, x + 2, y); String s = tickStrings[i]; if (unit == Unit.PERCENT) { s += "%"; } int sx = x - 6 - fm.stringWidth(s); if (y < lastY - 13) { if (checkLeftMargin(sx)) { // Wait for next repaint return; } g.drawString(s, sx, y + 4); } // Draw horizontal grid line g.setColor(Color.lightGray); g.drawLine(r.x + 4, y, r.x + r.width - 4, y); g.setColor(fg); lastY = y; } // Draw horizontal axis x = leftMargin; y = topMargin + h + 15; g.drawLine(x, y, x + w, y); long t1 = tMax; if (t1 <= 0L) { // No data yet, so draw current time t1 = System.currentTimeMillis(); } long tz = timeDF.getTimeZone().getOffset(t1); long tickInterval = calculateTickInterval(w, 40, viewRangeMS); if (tickInterval > 3 * HOUR) { tickInterval = calculateTickInterval(w, 80, viewRangeMS); } long t0 = tickInterval - (t1 - viewRangeMS + tz) % tickInterval; while (t0 < viewRangeMS) { x = leftMargin + (int) (w * t0 / viewRangeMS); g.drawLine(x, y - 2, x, y + 2); long t = t1 - viewRangeMS + t0; String str = formatClockTime(t); g.drawString(str, x, y + 16); // if (tickInterval > (1 * HOUR) && t % (1 * DAY) == 0) { if ((t + tz) % (1 * DAY) == 0) { str = formatDate(t); g.drawString(str, x, y + 27); } // Draw vertical grid line g.setColor(Color.lightGray); g.drawLine(x, topMargin, x, topMargin + h); g.setColor(fg); t0 += tickInterval; } // Plot values int start = 0; int nValues = 0; int nLists = seqs.size(); if (nLists > 0) { nValues = seqs.get(0).size; } if (nValues == 0) { g.setColor(oldColor); return; } else { Sequence seq = seqs.get(0); // Find starting point for (int p = 0; p < seq.size; p++) { if (times.time(p) >= tMax - viewRangeMS) { start = p; break; } } } // Optimization: collapse plot of more than four values per pixel int pointsPerPixel = (nValues - start) / w; if (pointsPerPixel < 4) { pointsPerPixel = 1; } // Draw graphs // Loop backwards over sequences because the first needs to be painted on top for (int i = nLists - 1; i >= 0; i--) { int x0 = leftMargin; int y0 = topMargin + h + 1; Sequence seq = seqs.get(i); if (seq.isPlotted && seq.size > 0) { // Paint twice, with white and with color for (int pass = 0; pass < 2; pass++) { g.setColor((pass == 0) ? Color.white : seq.color); int x1 = -1; long v1 = -1; for (int p = start; p < nValues; p += pointsPerPixel) { // Make sure we get the last value if (pointsPerPixel > 1 && p >= nValues - pointsPerPixel) { p = nValues - 1; } int x2 = (int) (w * (times.time(p) - (t1 - viewRangeMS)) / viewRangeMS); long v2 = seq.value(p); if (v2 >= vMin && v2 <= vMax) { int y2 = (int) (h * (v2 - vMin) / (vMax - vMin)); if (x1 >= 0 && v1 >= vMin && v1 <= vMax) { int y1 = (int) (h * (v1 - vMin) / (vMax - vMin)); if (y1 == y2) { // fillrect is much faster g.fillRect(x0 + x1, y0 - y1 - pass, x2 - x1, 1); } else { Graphics2D g2d = (Graphics2D) g; Stroke oldStroke = null; if (seq.transitionStroke != null) { oldStroke = g2d.getStroke(); g2d.setStroke(seq.transitionStroke); } g.drawLine(x0 + x1, y0 - y1 - pass, x0 + x2, y0 - y2 - pass); if (oldStroke != null) { g2d.setStroke(oldStroke); } } } } x1 = x2; v1 = v2; } } // Current value long v = seq.value(seq.size - 1); if (v >= vMin && v <= vMax) { if (bgIsLight) { g.setColor(seq.color); } else { g.setColor(fg); } x = r.x + r.width + 2; y = topMargin + h - (int) (h * (v - vMin) / (vMax - vMin)); // a small triangle/arrow g.fillPolygon(new int[] {x + 2, x + 6, x + 6}, new int[] {y, y + 3, y - 3}, 3); } g.setColor(fg); } } int[] valueStringSlots = new int[nLists]; for (int i = 0; i < nLists; i++) valueStringSlots[i] = -1; for (int i = 0; i < nLists; i++) { Sequence seq = seqs.get(i); if (seq.isPlotted && seq.size > 0) { // Draw current value // TODO: collapse values if pointsPerPixel >= 4 long v = seq.value(seq.size - 1); if (v >= vMin && v <= vMax) { x = r.x + r.width + 2; y = topMargin + h - (int) (h * (v - vMin) / (vMax - vMin)); int y2 = getValueStringSlot(valueStringSlots, y, 2 * 10, i); g.setFont(smallFont); if (bgIsLight) { g.setColor(seq.color); } else { g.setColor(fg); } String curValue = getFormattedValue(v, true); if (unit == Unit.PERCENT) { curValue += "%"; } int valWidth = fm.stringWidth(curValue); String legend = (displayLegend ? seq.name : ""); int legendWidth = fm.stringWidth(legend); if (checkRightMargin(valWidth) || checkRightMargin(legendWidth)) { // Wait for next repaint return; } g.drawString(legend, x + 17, Math.min(topMargin + h, y2 + 3 - 10)); g.drawString(curValue, x + 17, Math.min(topMargin + h + 10, y2 + 3)); // Maybe draw a short line to value if (y2 > y + 3) { g.drawLine(x + 9, y + 2, x + 14, y2); } else if (y2 < y - 3) { g.drawLine(x + 9, y - 2, x + 14, y2); } } g.setFont(oldFont); g.setColor(fg); } } g.setColor(oldColor); }
private int getTextWidth(String text) { return fmRef.stringWidth(text); }
private static int getSliderBaseline(JSlider slider, int height) { // We don't handle GTK as too much is hidden to be able to calculate it if (slider.getPaintLabels() && !isGTK()) { boolean isAqua = isAqua(); FontMetrics metrics = slider.getFontMetrics(slider.getFont()); Insets insets = slider.getInsets(); Insets focusInsets = (Insets) UIManager.get("Slider.focusInsets"); if (slider.getOrientation() == JSlider.HORIZONTAL) { int tickLength = 8; int contentHeight = height - insets.top - insets.bottom - focusInsets.top - focusInsets.bottom; int thumbHeight = 20; if (isMetal()) { tickLength = ((Integer) UIManager.get("Slider.majorTickLength")).intValue() + 5; thumbHeight = UIManager.getIcon("Slider.horizontalThumbIcon").getIconHeight(); } else if (isWindows() && isXP()) { // NOTE: this is not correct, this should come from // the skin (in >= 1.5), but short of reflection // hacks we don't have access to the real value. thumbHeight++; } int centerSpacing = thumbHeight; if (isAqua || slider.getPaintTicks()) { // centerSpacing += getTickLength(); centerSpacing += tickLength; } // Assume uniform labels. centerSpacing += metrics.getAscent() + metrics.getDescent(); int trackY = insets.top + focusInsets.top + (contentHeight - centerSpacing - 1) / 2; if (isAqua) { if (slider.getPaintTicks()) { int prefHeight = slider.getUI().getPreferredSize(slider).height; int prefDelta = height - prefHeight; if (prefDelta > 0) { trackY -= Math.min(1, prefDelta); } } else { trackY--; } } int trackHeight = thumbHeight; int tickY = trackY + trackHeight; int tickHeight = tickLength; if (!isAqua && !slider.getPaintTicks()) { tickHeight = 0; } int labelY = tickY + tickHeight; return labelY + metrics.getAscent(); } else { // vertical boolean inverted = slider.getInverted(); Integer value = inverted ? getMinSliderValue(slider) : getMaxSliderValue(slider); if (value != null) { int thumbHeight = 11; if (isMetal()) { thumbHeight = UIManager.getIcon("Slider.verticalThumbIcon").getIconHeight(); } int trackBuffer = Math.max(metrics.getHeight() / 2, thumbHeight / 2); int contentY = focusInsets.top + insets.top; int trackY = contentY + trackBuffer; int trackHeight = height - focusInsets.top - focusInsets.bottom - insets.top - insets.bottom - trackBuffer - trackBuffer; int maxValue = getMaxSliderValue(slider).intValue(); int min = slider.getMinimum(); int max = slider.getMaximum(); double valueRange = (double) max - (double) min; double pixelsPerValue = (double) trackHeight / (double) valueRange; int trackBottom = trackY + (trackHeight - 1); if (isAqua) { trackY -= 3; trackBottom += 6; } int yPosition = trackY; double offset; if (!inverted) { offset = pixelsPerValue * ((double) max - value.intValue()); } else { offset = pixelsPerValue * ((double) value.intValue() - min); } if (isAqua) { yPosition += Math.floor(offset); } else { yPosition += Math.round(offset); } yPosition = Math.max(trackY, yPosition); yPosition = Math.min(trackBottom, yPosition); if (isAqua) { return yPosition + metrics.getAscent(); } return yPosition - metrics.getHeight() / 2 + metrics.getAscent(); } } } return -1; }
private static int getTabbedPaneBaseline(JTabbedPane tp, int height) { if (tp.getTabCount() > 0) { if (isAqua()) { return getAquaTabbedPaneBaseline(tp, height); } Insets insets = tp.getInsets(); Insets contentBorderInsets = UIManager.getInsets("TabbedPane.contentBorderInsets"); Insets tabAreaInsets = rotateInsets(UIManager.getInsets("TabbedPane.tabAreaInsets"), tp.getTabPlacement()); FontMetrics metrics = tp.getFontMetrics(tp.getFont()); int maxHeight = getMaxTabHeight(tp); iconRect.setBounds(0, 0, 0, 0); textRect.setBounds(0, 0, 0, 0); viewRect.setBounds(0, 0, Short.MAX_VALUE, maxHeight); SwingUtilities.layoutCompoundLabel( tp, metrics, "A", null, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, viewRect, iconRect, textRect, 0); int baseline = textRect.y + metrics.getAscent(); switch (tp.getTabPlacement()) { case JTabbedPane.TOP: baseline += insets.top + tabAreaInsets.top; if (isWindows()) { if (tp.getTabCount() > 1) { baseline += 1; } else { baseline -= 1; } } return baseline; case JTabbedPane.BOTTOM: baseline = tp.getHeight() - insets.bottom - tabAreaInsets.bottom - maxHeight + baseline; if (isWindows()) { if (tp.getTabCount() > 1) { baseline += -1; } else { baseline += 1; } } return baseline; case JTabbedPane.LEFT: case JTabbedPane.RIGHT: if (isAqua()) { // Aqua rotates left/right text, so that there isn't a good // baseline. return -1; } baseline += insets.top + tabAreaInsets.top; if (isWindows()) { baseline += (maxHeight % 2); } return baseline; } } return -1; }
private int getFontHeight() { return fmRef.getHeight(); }
private static int getTextAreaBaseline(JTextArea text, int height) { Insets insets = text.getInsets(); FontMetrics fm = text.getFontMetrics(text.getFont()); return insets.top + fm.getAscent(); }