/** * Sets the receiver's text. * * <p>The string can contain both regular text and hyperlinks. A hyperlink is delimited by an * anchor tag, <A> and </A>. Within an anchor, a single HREF attribute is supported. * When a hyperlink is selected, the text field of the selection event contains either the text of * the hyperlink or the value of its HREF, if one was specified. In the rare case of identical * hyperlinks within the same string, the HREF attribute can be used to distinguish between them. * The string may include the mnemonic character and line delimiters. The only delimiter the HREF * attribute supports is the quotation mark ("). * * <p>Mnemonics are indicated by an '&' that causes the next character to be the mnemonic. The * receiver can have a mnemonic in the text preceding each link. When the user presses a key * sequence that matches the mnemonic, focus is assigned to the link that follows the text. * Mnemonics in links and in the trailing text are ignored. On most platforms, the mnemonic * appears underlined but may be emphasised in a platform specific manner. The mnemonic indicator * character '&' can be escaped by doubling it in the string, causing a single '&' to be * displayed. * * @param string the new text * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the text is null * </ul> * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public void setText(String string) { checkWidget(); if (string == null) error(SWT.ERROR_NULL_ARGUMENT); if (string.equals(text)) return; text = string; layout.setText(parse(string)); focusIndex = offsets.length > 0 ? 0 : -1; selection.x = selection.y = -1; boolean enabled = (state & DISABLED) == 0; TextStyle linkStyle = new TextStyle(null, enabled ? linkColor : disabledColor, null); linkStyle.underline = true; int[] bidiSegments = new int[offsets.length * 2]; for (int i = 0; i < offsets.length; i++) { Point point = offsets[i]; layout.setStyle(linkStyle, point.x, point.y); bidiSegments[i * 2] = point.x; bidiSegments[i * 2 + 1] = point.y + 1; } layout.setSegments(bidiSegments); TextStyle mnemonicStyle = new TextStyle(null, null, null); mnemonicStyle.underline = true; for (int i = 0; i < mnemonics.length; i++) { int mnemonic = mnemonics[i]; if (mnemonic != -1) { layout.setStyle(mnemonicStyle, mnemonic, mnemonic); } } redraw(); }
/** * Shorten the given text <code>t</code> so that its length doesn't exceed the given width. The * default implementation replaces characters in the center of the original string with an * ellipsis ("..."). Override if you need a different strategy. * * @param gc the gc to use for text measurement * @param t the text to shorten * @param width the width to shorten the text to, in pixels * @return the shortened text */ protected String shortenText(GC gc, String t, int width) { if (t == null) return null; int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x; if (width <= w) return t; int l = t.length(); int max = l / 2; int min = 0; int mid = (max + min) / 2 - 1; if (mid <= 0) return t; TextLayout layout = new TextLayout(getDisplay()); layout.setText(t); mid = validateOffset(layout, mid); while (min < mid && mid < max) { String s1 = t.substring(0, mid); String s2 = t.substring(validateOffset(layout, l - mid), l); int l1 = gc.textExtent(s1, DRAW_FLAGS).x; int l2 = gc.textExtent(s2, DRAW_FLAGS).x; if (l1 + w + l2 > width) { max = mid; mid = validateOffset(layout, (max + min) / 2); } else if (l1 + w + l2 < width) { min = mid; mid = validateOffset(layout, (max + min) / 2); } else { min = max; } } String result = mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l - mid), l); layout.dispose(); return result; }
/** * Sets the receiver's text. * * <p>The string can contain both regular text and hyperlinks. A hyperlink is delimited by an * anchor tag, <A> and </A>. Within an anchor, a single HREF attribute is supported. * When a hyperlink is selected, the text field of the selection event contains either the text of * the hyperlink or the value of its HREF, if one was specified. In the rare case of identical * hyperlinks within the same string, the HREF attribute can be used to distinguish between them. * The string may include the mnemonic character and line delimiters. The only delimiter the HREF * attribute supports is the quotation mark ("). * * <p>Mnemonics are indicated by an '&' that causes the next character to be the mnemonic. The * receiver can have a mnemonic in the text preceding each link. When the user presses a key * sequence that matches the mnemonic, focus is assigned to the link that follows the text. * Mnemonics in links and in the trailing text are ignored. On most platforms, the mnemonic * appears underlined but may be emphasised in a platform specific manner. The mnemonic indicator * character '&' can be escaped by doubling it in the string, causing a single '&' to be * displayed. * * @param string the new text * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the text is null * </ul> * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public void setText(String string) { checkWidget(); if (string == null) error(SWT.ERROR_NULL_ARGUMENT); if (string.equals(text)) return; text = string; if (OS.COMCTL32_MAJOR >= 6) { boolean enabled = OS.IsWindowEnabled(handle); /* * Bug in Windows. For some reason, when SetWindowText() * is used to set the text of a link control to the empty * string, the old text remains. The fix is to set the * text to a space instead. */ if (string.length() == 0) string = " "; // $NON-NLS-1$ TCHAR buffer = new TCHAR(getCodePage(), string, true); OS.SetWindowText(handle, buffer); parse(text); enableWidget(enabled); } else { layout.setText(parse(text)); focusIndex = offsets.length > 0 ? 0 : -1; selection.x = selection.y = -1; int bits = OS.GetWindowLong(handle, OS.GWL_STYLE); if (offsets.length > 0) { bits |= OS.WS_TABSTOP; } else { bits &= ~OS.WS_TABSTOP; } OS.SetWindowLong(handle, OS.GWL_STYLE, bits); boolean enabled = OS.IsWindowEnabled(handle); TextStyle linkStyle = new TextStyle(null, enabled ? linkColor : disabledColor, null); linkStyle.underline = true; for (int i = 0; i < offsets.length; i++) { Point point = offsets[i]; layout.setStyle(linkStyle, point.x, point.y); } TextStyle mnemonicStyle = new TextStyle(null, null, null); mnemonicStyle.underline = true; for (int i = 0; i < mnemonics.length; i++) { int mnemonic = mnemonics[i]; if (mnemonic != -1) { layout.setStyle(mnemonicStyle, mnemonic, mnemonic); } } redraw(); } }
public static void main(String[] args) { Display display = new Display(); final Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED); shell.setText("Underline, Strike Out"); Font font = shell.getFont(); String text = "Here is some text that is underlined or struck out or both."; final TextLayout layout = new TextLayout(display); layout.setText(text); TextStyle style1 = new TextStyle(font, null, null); style1.underline = true; layout.setStyle(style1, 26, 35); TextStyle style2 = new TextStyle(font, null, null); style2.strikeout = true; layout.setStyle(style2, 40, 49); TextStyle style3 = new TextStyle(font, null, null); style3.underline = true; style3.strikeout = true; layout.setStyle(style3, 54, 57); shell.addListener( SWT.Paint, new Listener() { @Override public void handleEvent(Event event) { Point point = new Point(10, 10); int width = shell.getClientArea().width - 2 * point.x; layout.setWidth(width); layout.draw(event.gc, point.x, point.y); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } layout.dispose(); display.dispose(); }