📄 titledborder.java
字号:
* {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP}, * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM}, * or {@link #DEFAULT_POSITION}. * * @param titleFont the font for the title text, or <code>null</code> * to use a default from the current look and feel. * * @throws IllegalArgumentException if <code>titleJustification</code> * or <code>titlePosition</code> have an unsupported value. */ public TitledBorder(Border border, String title, int titleJustification, int titlePosition, Font titleFont) { this(border, title, titleJustification, titlePosition, titleFont, /* titleColor */ null); } /** * Constructs a TitledBorder given its border, title text, horizontal * alignment, vertical position, font, and color. * * @param border the border underneath the title, or <code>null</code> * to use a default from the current look and feel. * * @param title the title text, or <code>null</code> to use no title * text. * * @param titleJustification the horizontal alignment of the title * text in relation to the border. The value must be one of * {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, {@link #LEADING}, * {@link #TRAILING}, or {@link #DEFAULT_JUSTIFICATION}. * * @param titlePosition the vertical position of the title text * in relation to the border. The value must be one of * {@link #ABOVE_TOP}, {@link #TOP}, {@link #BELOW_TOP}, * {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, {@link #BELOW_BOTTOM}, * or {@link #DEFAULT_POSITION}. * * @param titleFont the font for the title text, or <code>null</code> * to use a default from the current look and feel. * * @param titleColor the color for the title text, or <code>null</code> * to use a default from the current look and feel. * * @throws IllegalArgumentException if <code>titleJustification</code> * or <code>titlePosition</code> have an unsupported value. */ public TitledBorder(Border border, String title, int titleJustification, int titlePosition, Font titleFont, Color titleColor) { this.border = border; this.title = title; /* Invoking the setter methods ensures that the newly constructed * TitledBorder has valid property values. */ setTitleJustification(titleJustification); setTitlePosition(titlePosition); this.titleFont = titleFont; this.titleColor = titleColor; } /** * Paints the border and the title text. * * @param c the component whose border is to be painted. * @param g the graphics for painting. * @param x the horizontal position for painting the border. * @param y the vertical position for painting the border. * @param width the width of the available area for painting the border. * @param height the height of the available area for painting the border. */ public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Measurements mes = getMeasurements(c); Font oldFont = g.getFont(); Color oldColor = g.getColor(); /** * A local helper class for painting the border without changing * any pixels inside the rectangle of the title text. */ class BorderPainter { private Component c; private Border b; private int x, y, width, height; /** * Constructs a BorderPainter. * * @param c the component whose border is being painted. * @param b the border object. * @param x the x coordinate of the rectangle delimiting the border. * @param y the y coordinate of the rectangle delimiting the border. * @param width the width of the rectangle delimiting the border. * @param height the width of the rectangle delimiting the border. */ public BorderPainter(Component c, Border b, int x, int y, int width, int height) { this.c = c; this.b = b; this.x = x; this.y = y; this.width = width; this.height = height; } /** * Paints the entire border. */ public void paint(Graphics g) { if (b != null) b.paintBorder(c, g, x, y, width - 1, height - 1); } /** * Paints the border, clipping the drawing operation to a * given rectangular area. */ private void paint(Graphics g, int clipX, int clipY, int clipWidth, int clipHeight) { Shape oldClip = g.getClip(); try { g.clipRect(clipX, clipY, clipWidth, clipHeight); paint(g); } finally { g.setClip(oldClip); } } /** * Paints the border without affecting a given rectangular area. * This is used for painting the border without drawing anything * underneath the title text. * * <p>Since we do not want to introduce unnecessary dependencies * on Java 2D, we perform the clipping without constructive geometry * (provided by java.awt.geom.Area). Instead, the border’s * bounding rectangle is split into smaller parts, which are then * clipped and painted individually.: * * <p><pre> * +--------------------+ +--------------------+ * | | | 1 | * | +--------+ | +---+--------+-------+ * | | hole | | |====> | 2 | hole | 3 | * | +--------+ | |---+--------+-------+ * | | | 4 | * +--------------------+ +--------------------+</pre> * */ public void paintExcept(Graphics g, int holeX, int holeY, int holeWidth, int holeHeight) { int stripeHeight; stripeHeight = holeY - y; if (stripeHeight > 0) paint(g, x, y, width, stripeHeight); // patch #1 in the image above stripeHeight = holeHeight; if (stripeHeight > 0) { paint(g, x, holeY, holeX - x, stripeHeight); // patches #2 and #3 paint(g, holeX + holeWidth, holeY, width - (holeX + holeWidth), stripeHeight); } stripeHeight = height - (holeY - y + holeHeight); if (stripeHeight > 0) paint(g, x, y + height - stripeHeight, width, stripeHeight); // #4 } }; BorderPainter bp; int textX, textY, borderWidth, borderHeight; borderWidth = width - (mes.borderSpacing.left + mes.borderSpacing.right); borderHeight = height - (mes.borderSpacing.top + mes.borderSpacing.bottom); bp = new BorderPainter(c, getBorder(), x + mes.borderSpacing.left, y + mes.borderSpacing.top, borderWidth, borderHeight); switch (getRealTitleJustification(c)) { case LEFT: textX = x + TEXT_INSET_H; break; case CENTER: textX = x + (borderWidth - mes.textWidth) / 2; break; case RIGHT: textX = x + borderWidth - (mes.textWidth + TEXT_INSET_H); break; default: throw new IllegalStateException(); } switch (titlePosition) { case ABOVE_TOP: textY = y; break; case TOP: case DEFAULT_POSITION: default: textY = y + mes.borderSpacing.top + mes.borderInsets.top - mes.textAscent; break; case BELOW_TOP: textY = y + mes.borderSpacing.top + mes.borderInsets.top + TEXT_SPACING; break; case ABOVE_BOTTOM: textY = y + height - mes.borderSpacing.bottom - mes.borderInsets.bottom - TEXT_SPACING - (mes.textAscent + mes.textDescent); break; case BOTTOM: case BELOW_BOTTOM: textY = y + height - (mes.textAscent + mes.textDescent); break; } if (mes.trimmedText == null) bp.paint(g); else { try { g.setFont(mes.font); g.setColor(getTitleColor()); g.drawString(mes.trimmedText, textX, textY + mes.textAscent); } finally { g.setFont(oldFont); g.setColor(oldColor); } bp.paintExcept(g, textX - 2, textY, mes.textWidth + 2, mes.textAscent + mes.textDescent); } } /** * Measures the width of this border. * * @param c the component whose border is to be measured. * * @return an Insets object whose <code>left</code>, <code>right</code>, * <code>top</code> and <code>bottom</code> fields indicate the * width of the border at the respective edge. * * @see #getBorderInsets(java.awt.Component, java.awt.Insets) */ public Insets getBorderInsets(Component c) { return getBorderInsets(c, new Insets(0, 0, 0, 0)); } /** * Measures the width of this border, storing the results into a * pre-existing Insets object. * * @param insets an Insets object for holding the result values. * After invoking this method, the <code>left</code>, * <code>right</code>, <code>top</code> and * <code>bottom</code> fields indicate the width of the * border at the respective edge. * * @return the same object that was passed for <code>insets</code>. * * @see #getBorderInsets() */ public Insets getBorderInsets(Component c, Insets insets) { return getMeasurements(c).getContentInsets(insets); } /** * Returns <code>false</code>, indicating that there are pixels inside * the area of this border where the background shines through. * * @return <code>false</code>. */ public boolean isBorderOpaque() { /* Note that the AbstractBorder.isBorderOpaque would also return * false, so there is actually no need to override the inherited * implementation. However, GNU Classpath strives for exact * compatibility with the Sun reference implementation, which * overrides isBorderOpaque for unknown reasons. */ return false; } /** * Returns the text of the title. * * @return the title text, or <code>null</code> if no title is * displayed. */ public String getTitle() { return title; } /** * Retrieves the border underneath the title. If no border has been * set, or if it has been set to<code>null</code>, the current * {@link javax.swing.LookAndFeel} will be asked for a border * using the key <code>"TitledBorder.border"</code>. * * @return a border, or <code>null</code> if the current LookAndFeel * does not provide a border for the key * <code>"TitledBorder.border"</code>. * * @see javax.swing.UIManager#getBorder(Object) */ public Border getBorder() { if (border != null) return border; return UIManager.getBorder("TitledBorder.border"); } /** * Returns the vertical position of the title text in relation * to the border. * * @return one of the values {@link #ABOVE_TOP}, {@link #TOP}, * {@link #BELOW_TOP}, {@link #ABOVE_BOTTOM}, {@link #BOTTOM}, * {@link #BELOW_BOTTOM}, or {@link #DEFAULT_POSITION}. */ public int getTitlePosition() { return titlePosition; } /** * Returns the horizontal alignment of the title text in relation to * the border. * * @return one of the values {@link #LEFT}, {@link #CENTER}, {@link * #RIGHT}, {@link #LEADING}, {@link #TRAILING}, or {@link * #DEFAULT_JUSTIFICATION}. */ public int getTitleJustification() { return titleJustification; } /** * Retrieves the font for displaying the title text. If no font has * been set, or if it has been set to<code>null</code>, the current * {@link javax.swing.LookAndFeel} will be asked for a font * using the key <code>"TitledBorder.font"</code>. * * @return a font, or <code>null</code> if the current LookAndFeel * does not provide a font for the key
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -