org.eclipse.swt.text, automatically truncate the text?
I have a org.eclipse.swt.text
widget. Sometimes the widget isn't big enough to display all the information in it, is there a way to change the way it displays the information without changing the actual content?
I.e, it should show "1234...4321"开发者_如何学JAVA, but when I do getText()
it should return the actual value "123456654321".
Or is there a different SWT widget that can handle this?
Unfortunately you can't do with the org.eclipse.swt.widgets.Text
because SWT actually works with the native widget set and on most OS the native text widget can have a single state i.e value.
The workaround is either you create org.eclipse.swt.widgets.Text
with SWT.MULTI|SWT.WRAP
flags or wrap the original text widget in an utility class.
>>Output
>>Sample Wrapper Code
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
public class MyText
{
private Text text;
private String value;
public MyText(Composite parent, int style) {
text = new Text(parent, style);
}
public Text getControl() {
return text;
}
public String getText() {
return value;
}
public void setText(String value) {
if(text != null && !text.isDisposed()){
this.value = value;
text.setText(shortenText(value, text.getParent()));
}
}
private String shortenText(String textValue, Control control)
{
if (textValue == null) {
return null;
}
GC gc = new GC(control);
int maxWidth = control.getBounds().width - 25;
int maxExtent = gc.textExtent(textValue).x;
System.out.println(maxWidth + "\n" + maxExtent);
if (maxExtent < maxWidth) {
gc.dispose();
return textValue;
}
int length = textValue.length();
int charsToClip = Math.round(0.95f*length * (1 - ((float)maxWidth/maxExtent)));
int pivot = length / 2;
int start = pivot - (charsToClip/2);
int end = pivot + (charsToClip/2) + 1;
while (start >= 0 && end < length) {
String s1 = textValue.substring(0, start);
String s2 = textValue.substring(end, length);
String s = s1 + "..." + s2;
int l = gc.textExtent(s).x;
if (l < maxWidth) {
gc.dispose();
return s;
}
start--;
end++;
}
gc.dispose();
return textValue;
}
}
Note the implementation of shortenText()
method.
>>Main
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class TextWidgetTest
{
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Text Widget Test");
shell.setLayout(new GridLayout());
shell.setSize(300, 200);
final MyText text = new MyText(shell, SWT.SINGLE|SWT.BORDER);
text.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
text.setText("A very very very very very very very very very very very very very very very very very very very very long text");
Button show = new Button(shell, SWT.PUSH);
show.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
show.setText("Show Actual Text");
final Text console = new Text(shell, SWT.BORDER|SWT.MULTI|SWT.WRAP|SWT.V_SCROLL);
console.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
show.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
console.setText(text.getText());
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
Would creating the control with the SWT.MULTI|SWT.WRAP flags set be a good option for you? This way, you get a multiline control that wraps text.
Here's how to do it:
Text myText = new Text(parent, SWT.MULTI|SWT.WRAP);
精彩评论