/** * Provides a way to determine the next visually represented model location at which one might * place a caret. Some views may not be visible, they might not be in the same order found in the * model, or they just might not allow access to some of the locations in the model. * * @param pos the position to convert >= 0 * @param a the allocated region in which to render * @param direction the direction from the current position that can be thought of as the arrow * keys typically found on a keyboard. This will be one of the following values: * <ul> * <li>SwingConstants.WEST * <li>SwingConstants.EAST * <li>SwingConstants.NORTH * <li>SwingConstants.SOUTH * </ul> * * @return the location within the model that best represents the next location visual position * @exception BadLocationException * @exception IllegalArgumentException if <code>direction</code> doesn't have one of the legal * values above */ public int getNextVisualPositionFrom( int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet) throws BadLocationException { biasRet[0] = Position.Bias.Forward; switch (direction) { case NORTH: case SOUTH: { if (pos == -1) { pos = (direction == NORTH) ? Math.max(0, getEndOffset() - 1) : getStartOffset(); break; } JTextComponent target = (JTextComponent) getContainer(); Caret c = (target != null) ? target.getCaret() : null; // YECK! Ideally, the x location from the magic caret position // would be passed in. Point mcp; if (c != null) { mcp = c.getMagicCaretPosition(); } else { mcp = null; } int x; if (mcp == null) { Rectangle loc = target.modelToView(pos); x = (loc == null) ? 0 : loc.x; } else { x = mcp.x; } if (direction == NORTH) { pos = Utilities.getPositionAbove(target, pos, x); } else { pos = Utilities.getPositionBelow(target, pos, x); } } break; case WEST: if (pos == -1) { pos = Math.max(0, getEndOffset() - 1); } else { pos = Math.max(0, pos - 1); } break; case EAST: if (pos == -1) { pos = getStartOffset(); } else { pos = Math.min(pos + 1, getDocument().getLength()); } break; default: throw new IllegalArgumentException("Bad direction: " + direction); } return pos; }
/** * Converts an offset in a line into an x co-ordinate. This is a fast version that should only be * used if no changes were made to the text since the last repaint. * * @param line The line * @param offset The offset, from the start of the line */ public int _offsetToX(int line, int offset) { TokenMarker tokenMarker = getTokenMarker(); /* Use painter's cached info for speed */ FontMetrics fm = painter.getFontMetrics(); getLineText(line, lineSegment); int segmentOffset = lineSegment.offset; int x = horizontalOffset; /* If syntax coloring is disabled, do simple translation */ if (tokenMarker == null) { lineSegment.count = offset; return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); } /* If syntax coloring is enabled, we have to do this because * tokens can vary in width */ else { Token tokens; if (painter.currentLineIndex == line && painter.currentLineTokens != null) tokens = painter.currentLineTokens; else { painter.currentLineIndex = line; tokens = painter.currentLineTokens = tokenMarker.markTokens(lineSegment, line); } Toolkit toolkit = painter.getToolkit(); Font defaultFont = painter.getFont(); SyntaxStyle[] styles = painter.getStyles(); for (; ; ) { byte id = tokens.id; if (id == Token.END) { return x; } if (id == Token.NULL) fm = painter.getFontMetrics(); else fm = styles[id].getFontMetrics(defaultFont); int length = tokens.length; if (offset + segmentOffset < lineSegment.offset + length) { lineSegment.count = offset - (lineSegment.offset - segmentOffset); return x + Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); } else { lineSegment.count = length; x += Utilities.getTabbedTextWidth(lineSegment, fm, x, painter, 0); lineSegment.offset += length; } tokens = tokens.next; } } }
private void end(StringBuilder ans, Pretty pretty, String indent) { if (endEncloser == null) return; if (!pretty.pretty) ans.append(endEncloser); else { Utilities.assureEndsWithNewLine(ans); ans.append(indent + endEncloser); if (pretty.comments && endComment.length() > 0) ans.append("#" + endComment); Utilities.assureEndsWithNewLine(ans); } }
/** * 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 >= 0. 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. */ public float getPreferredSpan(int axis) { switch (axis) { case View.X_AXIS: Segment buff = SegmentCache.getSharedSegment(); Document doc = getDocument(); int width; try { FontMetrics fm = getFontMetrics(); doc.getText(0, doc.getLength(), buff); width = Utilities.getTabbedTextWidth(buff, fm, 0, this, 0); if (buff.count > 0) { Component c = getContainer(); firstLineOffset = sun.swing.SwingUtilities2.getLeftSideBearing( (c instanceof JComponent) ? (JComponent) c : null, fm, buff.array[buff.offset]); firstLineOffset = Math.max(0, -firstLineOffset); } else { firstLineOffset = 0; } } catch (BadLocationException bl) { width = 0; } SegmentCache.releaseSharedSegment(buff); return width + firstLineOffset; default: return super.getPreferredSpan(axis); } }
/** * Returns the next visual position for the cursor, in either the east or west direction. * * @param pos the position to convert >= 0 * @param b a bias value of either <code>Position.Bias.Forward</code> or <code> * Position.Bias.Backward</code> * @param a the allocated region to render into * @param direction the direction from the current position that can be thought of as the arrow * keys typically found on a keyboard; this may be one of the following: * <ul> * <li><code>SwingConstants.WEST</code> * <li><code>SwingConstants.EAST</code> * </ul> * * @param biasRet an array containing the bias that was checked * @return the location within the model that best represents the next west or east location * @exception BadLocationException for a bad location within a document model * @exception IllegalArgumentException if <code>direction</code> is invalid * @see #getNextVisualPositionFrom */ protected int getNextEastWestVisualPositionFrom( int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet) throws BadLocationException { if (pos < -1 || pos > getDocument().getLength()) { throw new BadLocationException("invalid position", pos); } return Utilities.getNextVisualPositionFrom(this, pos, b, a, direction, biasRet); }
void doKids(StringBuilder ans, Pretty pretty, String indent) { if (kids == null) return; for (Rope kid : kids) { if (!pretty.pretty) { kid.toString(ans, pretty, ""); } else { kid.toString(ans, pretty, indent + getKidIndentIncrement(kid, pretty)); Utilities.assureEndsWithNewLine(ans); } } }
private void start(StringBuilder ans, Pretty pretty, String indent) { if (startEncloser == null) return; if (!pretty.pretty) { ans.append(startEncloser); } else { String comment; if (pretty.comments && startComment.length() > 0) comment = " #" + startComment; else comment = ""; ans.append(indent + startEncloser + comment); Utilities.assureEndsWithNewLine(ans); } }
@Override public Component getListCellRendererComponent( JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel) (super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)); if (value instanceof TypeColorEntry) { TypeColorEntry entry = (TypeColorEntry) value; Token.Type type = entry.getType(); Color color = entry.getColor(); label.setText(Utilities.normalize(type.toString())); if ((type == Token.Type.MATCHED_BRACKET) || (type == Token.Type.UNMATCHED_BRACKET)) { label.setBackground(color); label.setForeground(Color.BLACK); } else { label.setForeground(color); } } return label; }
/** * 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; } } }
/** * Adjusts the allocation given to the view to be a suitable allocation for a text field. If the * view has been allocated more than the preferred span vertically, the allocation is changed to * be centered vertically. Horizontally the view is adjusted according to the horizontal alignment * property set on the associated JTextField (if that is the type of the hosting component). * * @param a the allocation given to the view, which may need to be adjusted. * @return the allocation that the superclass should use. */ protected Shape adjustAllocation(Shape a) { if (a != null) { Rectangle bounds = a.getBounds(); int vspan = (int) getPreferredSpan(Y_AXIS); int hspan = (int) getPreferredSpan(X_AXIS); if (bounds.height != vspan) { int slop = bounds.height - vspan; bounds.y += slop / 2; bounds.height -= slop; } // horizontal adjustments Component c = getContainer(); if (c instanceof JTextField) { JTextField field = (JTextField) c; BoundedRangeModel vis = field.getHorizontalVisibility(); int max = Math.max(hspan, bounds.width); int value = vis.getValue(); int extent = Math.min(max, bounds.width - 1); if ((value + extent) > max) { value = max - extent; } vis.setRangeProperties(value, extent, vis.getMinimum(), max, false); if (hspan < bounds.width) { // horizontally align the interior int slop = bounds.width - 1 - hspan; int align = ((JTextField) c).getHorizontalAlignment(); if (Utilities.isLeftToRight(c)) { if (align == LEADING) { align = LEFT; } else if (align == TRAILING) { align = RIGHT; } } else { if (align == LEADING) { align = RIGHT; } else if (align == TRAILING) { align = LEFT; } } switch (align) { case SwingConstants.CENTER: bounds.x += slop / 2; bounds.width -= slop; break; case SwingConstants.RIGHT: bounds.x += slop; bounds.width -= slop; break; } } else { // adjust the allocation to match the bounded range. bounds.width = hspan; bounds.x -= vis.getValue(); } } return bounds; } return null; }
public AboutDialog(JConsole jConsole) { super(jConsole, Resources.getText("Help.AboutDialog.title"), false); setAccessibleDescription(this, getText("Help.AboutDialog.accessibleDescription")); setDefaultCloseOperation(HIDE_ON_CLOSE); setResizable(false); JComponent cp = (JComponent) getContentPane(); createActions(); JLabel mastheadLabel = new JLabel(mastheadIcon); setAccessibleName(mastheadLabel, getText("Help.AboutDialog.masthead.accessibleName")); JPanel mainPanel = new TPanel(0, 0); mainPanel.add(mastheadLabel, NORTH); String jConsoleVersion = Version.getVersion(); String vmName = System.getProperty("java.vm.name"); String vmVersion = System.getProperty("java.vm.version"); String urlStr = getText("Help.AboutDialog.userGuideLink.url"); if (isBrowseSupported()) { urlStr = "<a style='color:#35556b' href=\"" + urlStr + "\">" + urlStr + "</a>"; } JPanel infoAndLogoPanel = new JPanel(new BorderLayout(10, 10)); infoAndLogoPanel.setBackground(bgColor); String colorStr = String.format("%06x", textColor.getRGB() & 0xFFFFFF); JEditorPane helpLink = new JEditorPane( "text/html", "<html><font color=#" + colorStr + ">" + getText("Help.AboutDialog.jConsoleVersion", jConsoleVersion) + "<p>" + getText("Help.AboutDialog.javaVersion", (vmName + ", " + vmVersion)) + "<p>" + getText("Help.AboutDialog.userGuideLink", urlStr) + "</html>"); helpLink.setOpaque(false); helpLink.setEditable(false); helpLink.setForeground(textColor); mainPanel.setBorder(BorderFactory.createLineBorder(borderColor)); infoAndLogoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); helpLink.addHyperlinkListener( new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { browse(e.getDescription()); } } }); infoAndLogoPanel.add(helpLink, NORTH); ImageIcon brandLogoIcon = new ImageIcon(getClass().getResource("resources/brandlogo.png")); JLabel brandLogo = new JLabel(brandLogoIcon, JLabel.LEADING); JButton closeButton = new JButton(closeAction); JPanel bottomPanel = new TPanel(0, 0); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING)); buttonPanel.setOpaque(false); mainPanel.add(infoAndLogoPanel, CENTER); cp.add(bottomPanel, SOUTH); infoAndLogoPanel.add(brandLogo, SOUTH); buttonPanel.setBorder(new EmptyBorder(2, 12, 2, 12)); buttonPanel.add(closeButton); bottomPanel.add(buttonPanel, NORTH); statusBar = new JLabel(" "); bottomPanel.add(statusBar, SOUTH); cp.add(mainPanel, NORTH); pack(); setLocationRelativeTo(jConsole); Utilities.updateTransparency(this); }