Looking for resizable SWT (JFace) text area component with gripper - java

I would like to have a resizable text area in one of my Eclipse Plugins. It should have a gripper on the lower right corner that can be dragged to change the size of the text area, similar to following html example:
<!DOCTYPE html>
<html>
<body>
<textarea rows="4" cols="50">
This is a resizable html text area with a gripper at the lower right corner. How to create something similar with SWT JFace?</textarea>
</body>
</html>
Result as static image:
I am already able to create an SWT multi-line text:
Text textArea = toolkit.createText(parentContainer, "Default text", SWT.MULTI | SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
textArea.setEnabled(isEnabled());
textArea.setToolTipText("tooltip");
GridData areaData = new GridData();
areaData.grabExcessHorizontalSpace = true;
areaData.horizontalAlignment = GridData.FILL;
areaData.verticalAlignment = GridData.FILL;
areaData.grabExcessVerticalSpace = true;
areaData.heightHint = 80;
areaData.widthHint = 200;
textArea.setLayoutData(areaData);
Instead of the scroll bar I would like to have a gripper that is able to resize the text field vertically and horizontally.
The documentation for the Text element is here and I could not find a gripper option:
http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fwidgets%2FText.html
How can I add a gripper to the text?
Is there a resizable panel with a gripper that I can use to wrap the text?
A "Sash" only seems to be resizable in one direction:
Can you create a resizable control in SWT?
Is there a finished control that provides the functionality I am looking for? (I had a look at the nebula widgets but there does not seem to be a text area component with gripper.)

With the help of Baz I found following solution. Its not perfect but kind of working and may be useful as a starting point for others. Please not that the parent layout does not yet adapt to the new size. And the example below does not yet set min values for the rect sizes.
//toolkit
FormToolkit toolkit = new FormToolkit(Display.getCurrent());
//create content composite for label, text area and gripper
contentContainer = toolkit.createComposite(parent);
GridData fillHorizontal = new GridData();
fillHorizontal.grabExcessHorizontalSpace = true;
fillHorizontal.horizontalAlignment = GridData.FILL;
contentContainer.setLayoutData(fillHorizontal);
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.horizontalSpacing = 0;
gridLayout.verticalSpacing = 2;
gridLayout.marginHeight = 2;
gridLayout.marginWidth = 0;
contentContainer.setLayout(gridLayout);
//label
String currentLabel = getLabel();
toolkit.createLabel(contentContainer, currentLabel);
//text area
textArea = toolkit.createText(contentContainer, get(), SWT.MULTI | SWT.BORDER | SWT.WRAP);
textArea.setEnabled(isEnabled());
textArea.setToolTipText(tooltip);
GridData areaData = new GridData();
areaData.grabExcessHorizontalSpace = true;
areaData.grabExcessVerticalSpace = true;
areaData.horizontalAlignment = GridData.FILL;
areaData.verticalAlignment = GridData.FILL;
areaData.widthHint = 200;
areaData.heightHint = 80;
textArea.setLayoutData(areaData);
//gripper
org.eclipse.swt.widgets.Label gripper = toolkit.createLabel(contentContainer, "");
gripper.setImage(Activator.getImage("tracker.png"));
GridData tragData = new GridData();
tragData.horizontalAlignment = GridData.END;
gripper.setLayoutData(tragData);
Listener trackerListener = new Listener() {
#Override
public void handleEvent(Event e) {
Tracker tracker = new Tracker(contentContainer.getParent(), SWT.RESIZE | SWT.DOWN | SWT.RIGHT);
Rectangle maxRect = contentContainer.getParent().getBounds();
Rectangle rect = contentContainer.getBounds();
tracker.setRectangles(new Rectangle[] { rect });
if (tracker.open()) {
Rectangle after = tracker.getRectangles()[0];
Rectangle newRect = new Rectangle(
after.x,
after.y,
Math.min(after.width, maxRect.width - 10),
Math.min(after.height, maxRect.height - 10));
contentContainer.setBounds(newRect);
}
tracker.dispose();
}
};
gripper.addListener(SWT.MouseDown, trackerListener);

Related

How to create a Java SWT table with multiple columns without giving static column width

I'm currently developing an eclipse plugin and in that plugin, there is a form view as a design template. In that form view, I have added a Table and there should have two columns in width ratio of 1:2. And also I want that table to be responsive and dynamically change its column width in order to the formView page width.
The following code segment is the one I'm currently using.
Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.BORDER);
fd = new FormData();
fd.height = 200;
fd.top = new FormAttachment(removeTestCaseButton, 5);
fd.left = new FormAttachment(1);
fd.right = new FormAttachment(99);
table.setLayoutData(fd);
table.setLinesVisible(true);
table.setHeaderVisible(true);
TableColumn column1 = new TableColumn(testCaseTable, SWT.CENTER);
column.setText("column One");
TableColumn column2 = new TableColumn(testCaseTable, SWT.CENTER);
column2.setText("column Two");
form.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
Rectangle area = form.getBody().getClientArea();
int width = area.width;
column1.setWidth(width / 3);
column1.setWidth(width * 2 / 3);
}
});
But here the problem is when I open the FormView it works fine. But my table is inside a Section. Once I expand or collapse the Section the table width is getting increased with appearing the horizontal scrollbar.
I just want a solid solution for this.
This is much easier to do using the JFace TableViewer with the TableColumnLayout and ColumnWeightData, but you will have to rework your code to use JFace style content and label providers for the table.
TableColumnLayout tableLayout = new TableColumnLayout();
// A separate composite containing just the table viewer is required
Composite tableComp = new Composite(parent, SWT.NONE);
tableComp.setLayout(tableLayout);
TableViewer viewer = new TableViewer(tableComp, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
TableViewerColumn col1 = new TableViewerColumn(viewer, SWT.LEAD);
col1.getColumn().setText("Column 1");
col1.setLabelProvider(.... label provider for column 1 ....);
// Weight for column
tableLayout.setColumnData(col1.getColumn(), new ColumnWeightData(60));
TableViewerColumn col2 = new TableViewerColumn(viewer, SWT.LEAD);
col2.getColumn().setText("Column 2");
col2.setLabelProvider(....... label provider for column 2 .....);
// Weight for column
tableLayout.setColumnData(col2.getColumn(), new ColumnWeightData(40));
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setInput(.... input data for the viewer ....);

ClassCastException when placing RadioGroupFieldEditor in FormLayout

I am a newbie to SWT GUI development. I am using SWT for developing Eclipse plug-ins. Basically, I wanted two radio option groups and some textboxes beneath the second radio option group; something like below.
Heading1
. A radio button
. B radio button
Heading2
. C radio button
. D radio button
Textbox1 Textbox2 Textbox3
Since I needed those text boxes relative to each other,I used FormLayout. But it gives me exception:
Caused by: java.lang.ClassCastException: org.eclipse.swt.layout.FormData cannot be cast to org.eclipse.swt.layout.GridData*
But I haven't used GridData.
Exception occurs at line 129.
I am unable to add Textbox2 relative to Textbox1.My code is below.
Shell sh = new Shell(parent_shell,SWT.PRIMARY_MODAL | SWT.TRAIL | SWT.CASCADE);
System.out.println("execute");
FormLayout fL = new FormLayout();
sh.setLayout(fL);
sh.setText("Configure");
sh.setSize(330,300);
sh.setActive();
Composite composite = new Composite( sh, SWT.NONE );
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout( layout );
FormData fd = new FormData(); //line 100
fd.top = new FormAttachment(0,0);//line 101
fd.left = new FormAttachment(0,0);//line 102
//fd.right = new FormAttachment(26);//line 103
//fd.bottom = new FormAttachment(10);//line 104
composite.setLayoutData( fd );
RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor("User Choice",
"Heading1", 1, new String[][]{
{"A radio button","a"},{"B radio button","b"}
}, composite,false);
RadioGroupFieldEditor rgfe1 = new RadioGroupFieldEditor("User Choice1",
"Heading2", 1, new String[][]{
{"C radio button","c"},{"D radio button","d"}
}, composite,false);
Text ol = new Text(composite,SWT.READ_ONLY);
ol.setText("Output Location");
ol.setEnabled(false);
// FormData fd1 = new FormData();
// fd.top = new FormAttachment(fd);
// fd.left = new FormAttachment(1);
// fd.right = new FormAttachment(26);
// fd.bottom = new FormAttachment(10);
// ol.pack();
// ol.setLayoutData(fd1); //line 129 --> exception occurs
while (!sh.isDisposed()) {
if (!parent_display.readAndDispatch()) {
parent_display.sleep();
}
}
}
The RadioGroupFieldEditor assumes that its parent has a GridLayout set.
I suggest you embed the RadioGroupFieldEditor in a separate Composite that has a GridLayout set. Then you can attach FormData to the Composite to control its layout.
For example:
Composite composite = new Composite( sh, SWT.NONE );
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout( layout );
FormData compositeFormData = new FormData();
...
composite.setLayoutData( compositeFormData );
RadioGroupFieldEditor fieldEditor = new RadioGroupFieldEditor( ..., composite, ... );

How to design a Composite in SWT

I want to put 3 fixed size group in the composite in A side. And I want to place the image and the label middle of this group. My example image and code is below. The problem is the groups are resize according to label size in them and labels were written top of the group, but I want the place groups as equal fixed size to cover width of A side and labels should be vertically middle of the group.
private void designComposite() {
Section sectionA = toolkit.createSection(form.getBody(), Section.TITLE_BAR);
sectionA.setText("A");
Composite sectionClientA = toolkit.createComposite(sectionA);
sectionClientA.setLayout(new RowLayout());
Composite dynamicDataComp = toolkit.createComposite(sectionClientA);
dynamicDataComp.setLayout(new RowLayout());
Group group_incom = new Group(dynamicDataComp, SWT.NONE);
group_incom.setLayout(new RowLayout());
Label lbl_img_incom = new Label(group_incom, SWT.CENTER);
Image img_incom = new Image(lbl_img_incom.getDisplay(),
"<path>");
lbl_img_incom.setImage(img_incom);
group_incom.setText("# of Incoming Messages :");
Label lbl_incomMsg = toolkit.createLabel(group_incom, "99", SWT.CENTER | SWT.VERTICAL);
Font incomFont = new Font(lbl_incomMsg.getDisplay(), new FontData("Arial", 12, SWT.BOLD));
lbl_incomMsg.setFont(incomFont);
lbl_incomMsg.pack();
Group group_outgo = new Group(dynamicDataComp, SWT.NONE);
group_outgo.setLayout(new RowLayout());
Label lbl_img_outgo = new Label(group_outgo, SWT.CENTER);
Image img_outgo = new Image(lbl_img_outgo.getDisplay(),
"<path>");
lbl_img_outgo.setImage(img_outgo);
group_outgo.setText("# of Outgoing Messages :");
Label lbl_outgoMsg = toolkit.createLabel(group_outgo, "145639612", SWT.CENTER);
Font outgoFont = new Font(lbl_outgoMsg.getDisplay(), new FontData("Arial", 13, SWT.BOLD));
lbl_outgoMsg.setFont(outgoFont);
lbl_outgoMsg.pack();
Group group_error = new Group(dynamicDataComp, SWT.NONE);
group_error.setLayout(new RowLayout());
Label lbl_img_error = new Label(group_error, SWT.CENTER);
Image img_error = new Image(lbl_img_error.getDisplay(),
"<path>");
lbl_img_error.setImage(img_error);
group_error.setText("# of Error Messages :");
Label lbl_errorMsg = toolkit.createLabel(group_error, "345", SWT.CENTER);
Font errorFont = new Font(lbl_errorMsg.getDisplay(), new FontData("Arial", 13, SWT.BOLD));
lbl_errorMsg.setFont(errorFont);
lbl_errorMsg.pack();
sectionA.setClient(sectionClientA);
}
Use the GridLayout and set the columns equal width:
Composite dynamicDataComp = new Composite(parent, SWT.NONE);
dynamicDataComp.setLayout(new GridLayout(3, true));
dynamicDataComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Group group_incom = new Group(dynamicDataComp, SWT.NONE);
group_incom.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
group_incom.setLayout(new RowLayout());
//...
One way is to use GridLayout for the parent composite and tell it use 3 equal sized columns:
Composite dynamicDataComp = toolkit.createComposite(sectionClientA);
dynamicDataComp.setLayout(new GridLayout(3, true));

SWT - show multiple table items

Could anybody help me?
I have a table in SWT and simply I want to show some table items but the table only shows one item and the others with vertical scroll. I want to show everything, without scrolling. I tried with the option SWT_NO_SCROLL but is not working. I have a method that creates the table and other that populates it creating a new table item, they´re working good, the problem is that only shows the first item and the other are scrolling.
My code is:
private void createTable(Composite parent){
table = new Table (parent, SWT.BORDER);
TableColumn tcFile = new TableColumn(table, SWT.LEFT);
TableColumn tcStatus = new TableColumn(table, SWT.LEFT);
tcFile.setText("File");
tcStatus.setText("Status");
tcFile.setWidth(500);
tcStatus.setWidth(500);
table.setVisible(true);
table.setHeaderVisible(true);
}
private void populateTable(String file, String status){
TableItem item = new TableItem(table, SWT.LEFT);
item.setText(new String[] { file, status});
}
Composite top = new Composite(parent, SWT.WRAP);
GridLayout layout = new GridLayout();
layout.marginHeight = -5;
layout.marginWidth = 0;
top.setLayout(layout);
Composite banner = new Composite(top, SWT.WRAP);
banner.setLayoutData(new GridData(GridData.FILL, GridData.VERTICAL_ALIGN_BEGINNING, false, false));
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 10;
layout.numColumns = 5;
banner.setLayout(layout);
createTable(top);
You haven't specified any layout data for the Table, try something like:
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
table.setLayoutData(data);
If you don't have anything else that is setting the dialog/window size you may need to specify a table height hint:
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.heightHint = 200; // Vertical size for table
table.setLayoutData(data);

Setting number of rows to be displayed for Multi line text in swt

I am using following for TextArea
ToolBar bar = new ToolBar(box,SWT.NONE);
ToolItem item = new ToolItem(bar, SWT.SEPARATOR);
Text text = new Text(bar, SWT.BORDER | SWT.MULTI);
item.setWidth(width);
item.setControl(text);
GridData data = new GridData();
data.verticalAlignment = SWT.CENTER;
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
text.setLayoutData(data);
I want to display a multi line text box, currently its accepting multi line text but showing only a single line at a time.
Any idea how to set the number of rows to be displayed ?
Thanks.
You can also use Text.getLineHeight() to determine the height of a single line of text, you don't need a GC for that:
final Text text = new Text(container, SWT.BORDER | SWT.WRAP);
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.heightHint = 5 * text.getLineHeight();
text.setLayoutData(gridData);
You can set the height in pixels:
/* Set the height to 75 pixels */
data.heightHint = 75;
However, you can also set the height in terms of the number of character rows, but you have to do some trickery to measure the character height. You'll need to build a graphics context (GC) to measure the text extent.
For example:
GC gc = new GC(text);
try
{
gc.setFont(text.getFont());
FontMetrics fm = gc.getFontMetrics();
/* Set the height to 5 rows of characters */
data.heightHint = 5 * fm.getHeight();
}
finally
{
gc.dispose();
}

Categories

Resources