horizontalSpan in SWT GridLayout doesn't span - swt

I'm trying to configure a dialog window like so:
#Override
protected Control createDialogArea(Composite parent) {
GridLayout dialogAreaLayout = new GridLayout();
dialogAreaLayout.numColumns = 2;
parent.setLayout(dialogAreaLayout);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
gridData.minimumWidth = 300;
// the label in the first row should span across both columns
gridData.horizontalSpan = 2;
Label headlineLabel = new Label(parent, SWT.NONE);
headlineLabel.setText("example test");
headlineLabel.setLayoutData(gridData);
// the rest should be ordered in two columns
gridData.horizontalSpan = 1;
companyLabel = new Label(parent, SWT.NONE);
companyLabel("company");
companyTextfield = new Text(parent, SWT.BORDER);
companyTextfield(gridData);
...
What I'm trying to accomplish is a label in the first line, that spans across both columns and have the following fields be ordered in pairs per line. What I get with this is, that the lable (that should be left in second line) is right in first line, just as the label wouldn't span across two columns. Can anybody see, what I'm doing wrong?
Thanx again!

After setting the layoutData to headlineLabel, you are setting the horizontalSpan to 1. You need to create a new LayoutData object for every SWT widget. It is not possible to reuse them after setting them.

Related

Eclipse SWT Maintaining Same layout in 2 separate composites

Hello Everyone,
I have 2 Groups and each group has 3 Label and Text combinations, as you can see from the above Image.
I would like the text field to grab as much as space possible.hence, I have used grab 'true' only for the text field.
These label and text fields are well aligned inside their own group/composite.
But, when these 2 Groups are considered as a whole, the label and text fields are out of alignment.
Is there a way to align these label and text fields across multiple Groups?
is there a way to align these labels and text fields, without declaring each groups having equal column width, and specifying the number of columns label and text fields occupy?
Below is the code I have used for creating the below groups.
private void createFirstGroup(Composite parent) {
Group firstGroup = new Group(parent, SWT.NONE);
firstGroup.setText("first group");
GridDataFactory.fillDefaults().grab(true, false).applyTo(firstGroup);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(firstGroup);
String[] labels = new String[]{"Kwd","Variable","Value"};
for(int index=0;index<labels.length; index++){
Label label = new Label(firstGroup, SWT.NONE);
label.setText(labels[index]);
GridDataFactory.fillDefaults().applyTo(label);
Text textField = new Text(firstGroup, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
}
}
private void createSecondGroup(Composite parent) {
Group secondGroup = new Group(parent, SWT.NONE);
secondGroup.setText("second group");
GridDataFactory.fillDefaults().grab(true, false).applyTo(secondGroup);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(secondGroup);
String[] labels = new String[]{"Count","Upper Comment","Lower Comment"};
for(int index=0;index<labels.length; index++){
Label label = new Label(secondGroup, SWT.NONE);
label.setText(labels[index]);
GridDataFactory.fillDefaults().applyTo(label);
Text textField = new Text(secondGroup, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
}
}

How to put label item on rowLayout in SWT?

I want to put some items on row layout. But I take an error. My error image is here:
my example code is below:
GridLayout parentLayout = new GridLayout(1, true);
parent.setLayout(parentLayout);
// design filter composite layout
Composite filterComposite = new Composite(parent, SWT.NONE);
RowLayout filterCompositeLayout = new RowLayout();
filterCompositeLayout.wrap = true;
filterCompositeLayout.pack = false;
filterCompositeLayout.justify = true;
filterCompositeLayout.type = SWT.HORIZONTAL;
filterComposite.setLayout(filterCompositeLayout);
// design filter composite
Label lbl_type = new Label(filterComposite, SWT.BORDER);
lbl_type.setText("Type :");
Combo cmb_type = new Combo(filterComposite, SWT.BORDER);
cmb_type.setText("-- choose --");
Label lbl_severity = new Label(filterComposite, SWT.BORDER);
lbl_severity.setText("Severity :");
Combo cmb_severity = new Combo(filterComposite, SWT.BORDER);
cmb_severity.setText("-- choose --");
Label lbl_startDate = new Label(filterComposite, SWT.BORDER);
lbl_startDate.setText("Start Date : ");
DateTime dateTimeStart = new DateTime(filterComposite, SWT.DROP_DOWN | SWT.LONG);
dateTimeStart.setLayoutData(new GridData(SWT.NONE, SWT.NONE, true, true));
Error is on DataTime row. Can anybody give some advice? Thank you.
You cant set GridData to component placed in RowLayout. You should use RowData instead:
DateTime dateTimeStart = new DateTime(filterComposite, SWT.DROP_DOWN | SWT.LONG);
RowData rd = new RowData();
rd.width = 123;
rd.height = 23;
dateTimeStart.setLayoutData(rd);
You are attempting to set GridData layout data for dateTimeStart. However Composite filterComposite has RowLayout and this Layout expects RowData layout data.
example:
DateTime dateTimeStart = new DateTime(filterComposite, SWT.DROP_DOWN | SWT.LONG);
dateTimeStart.setLayoutData(new RowData (width, height)); //set proper height and width according to your UI expectations

copy chart control to new form

Is there a way to copy a chart control to a new form?
I have a Windows Form with a chart control on it, but the form is not allowed to be resizable. For that reason I have a button "Zoom" that opens the chart in a new form that is resizable. I have set a lot of chart properties in the "original" chart (axis color, axis intervalls etc.) and would like to just reuse this properties. I tried to call the constructor of the new form with the chart as parameter, but that didn't work.
public ZoomChartSeriesForm(Chart myChart)
My main problem is, that I allow zooming inside of the chart and that crashes, when I just copy the chart.
Here is the code of my "original chart" (example):
System.Drawing.Color color = System.Drawing.Color.Red;
//plot new doublelist
var series = new Series
{
Name = "Series2",
Color = color,
ChartType = SeriesChartType.Line,
ChartArea = "ChartArea1",
IsXValueIndexed = true,
};
this.chart1.Series.Add(series);
List<double> doubleList = new List<double>();
doubleList.Add(1.0);
doubleList.Add(5.0);
doubleList.Add(3.0);
doubleList.Add(1.0);
doubleList.Add(4.0);
series.Points.DataBindY(doubleList);
var chartArea = chart1.ChartAreas["ChartArea1"];
LabelStyle ls = new LabelStyle();
ls.ForeColor = color;
Axis a = chartArea.AxisY;
a.TitleForeColor = color; //color of axis title
a.MajorTickMark.LineColor = color; //color of ticks
a.LabelStyle = ls; //color of tick labels
chartArea.Visible = true;
chartArea.AxisY.Title = "TEST";
chartArea.RecalculateAxesScale();
chartArea.AxisX.Minimum = 1;
chartArea.AxisX.Maximum = doubleList.Count;
// Set automatic scrolling
chartArea.CursorX.AutoScroll = true;
chartArea.CursorY.AutoScroll = true;
// Allow user to select area for zooming
chartArea.CursorX.IsUserEnabled = true;
chartArea.CursorX.IsUserSelectionEnabled = true;
chartArea.CursorY.IsUserEnabled = true;
chartArea.CursorY.IsUserSelectionEnabled = true;
// Set automatic zooming
chartArea.AxisX.ScaleView.Zoomable = true;
chartArea.AxisY.ScaleView.Zoomable = true;
chartArea.AxisX.ScrollBar.IsPositionedInside = true;
chartArea.AxisY.ScrollBar.IsPositionedInside = true;
//reset zoom
chartArea.AxisX.ScaleView.ZoomReset();
chartArea.AxisY.ScaleView.ZoomReset();
chart1.Invalidate();
Copy as in deep copying the object?
I ran into this exact problem recently myself. Unfortunately, MS Chart has no method to clone their chart object and their class is not marked as serializable so you can't use the method suggested here.
If you want to do this the right way, you'll have to introduce a third party control such as Copyable or handle the reflection yourself, but this won't be easy.
A really nice workaround I found is to use the built-in serialization inside MS Chart control. The idea is to serialize the chart using memorystream, create a new instance of the chart and deserialize the chart.
private Chart CloneChart(Chart chart)
{
MemoryStream stream = new MemoryStream();
Chart clonedChart = chart;
clonedChart.Serializer.Save(stream);
clonedChart = new Chart();
clonedChart.Serializer.Load(stream);
return clonedChart;
}
Not exactly an efficient solution, but if performance isn't your priority, this works like a charm.

How to load dynamic data on a eclipse shell?

I want to load details of a user's when clicking their names . So I create a Grid Layout with two columns left hand side is standalone and right hand side data will be loaded based on clicking their names .
JAVA CODE
Display display = PlatformUI.createDisplay();
Shell shell = new Shell(display);
shell.setSize(400, 400);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
shell.setLayout(gridLayout);
shell.setBackground(new Color(display, 255, 255, 255));
final Table table = new Table(shell, SWT.VIRTUAL);
table.setLayout(new GridLayout());
table.setSize(400, 400);
final TableColumn column = new TableColumn(table, SWT.LEFT);
column.setWidth(150);
column.setText("Runnable Services");
table.setItemCount(5);
final String[] services = new String[] { "Franklin", "Christian",
"Richard Levi",
"Dale Steyn", "Chris Gayle" };
table.addListener(SWT.SetData, new Listener() {
public void handleEvent(Event event) {
TableItem item = (TableItem) event.item;
int index = table.indexOf(item);
item.setText(services[index]);
System.out.println(item.getText());
}
});
table.addSelectionListener(new OnClickListener());
alignCenter(shell, display);
shell.open();
I added a selection listener on a table . When click the players I add their details on SelectionListener's widget Selected method .
JAVA CODE
Composite parent = new Composite(table.getParent(), SWT.NONE);
parent.setLayout(new GridLayout(2, false));
Label label = new Label(parent, SWT.NULL);
label.setText("Name :");
System.out.println(table.getSelection()[0].getText());
Text text = new Text(parent, SWT.BORDER);
text.setText(table.getSelection()[0].getText());
text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
| GridData.GRAB_HORIZONTAL));
ViewActionDelegate.resize(200, true, 20, table.getShell());
If i did like this on click action each time data will be appended to existing shell . How can I clear the righ hand side details ? . I posted a image below .
How can i do this ? .
Finally I found the answer .
Issue :
I append new elements into already created composite .
Solution:
Clear elements from existing composite before drawing new elements .
Java Code :
if ((composite != null) && (!composite.isDisposed())) {
Control[] children = composite2.getChildren();
for(Control ch : children){
ch.dispose();
}
}

Table shows extra blank columns at the end

I am using jface tableViewer.When table has no data in it ,it shows all columns correctly But when Data gets added to the table it shows extra blank space or column at the end of the table.
I am using TreeViewer + TreeViewerColumn and had this problem too, this workaround might work for your TableViewer too: Programmatically set the size of the last column on parent resize:
treeViewer.getTree().addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
packAndFillLastColumn();
}
});
where the action is in
// Resize last column in tree viewer so that it fills the client area completely if extra space.
protected void packAndFillLastColumn() {
Tree tree = treeViewer.getTree();
int columnsWidth = 0;
for (int i = 0; i < tree.getColumnCount() - 1; i++) {
columnsWidth += tree.getColumn(i).getWidth();
}
TreeColumn lastColumn = tree.getColumn(tree.getColumnCount() - 1);
lastColumn.pack();
Rectangle area = tree.getClientArea();
Point preferredSize = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT);
int width = area.width - 2*tree.getBorderWidth();
if (preferredSize.y > area.height + tree.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = tree.getVerticalBar().getSize();
width -= vBarSize.x;
}
// last column is packed, so that is the minimum. If more space is available, add it.
if(lastColumn.getWidth() < width - columnsWidth) {
lastColumn.setWidth(width - columnsWidth);
}
}
Works well for me - you might want to set column resizable to false ;-). This can also be called when data in the last column changes (introducting / removing vertical scroll bar).
Thanks Thomas. Your idea worked for me as well, though I was using TableViewer and TableColumn.
Quoting my code so that others can take some hints.
`public void controlResized(ControlEvent e) {
if ( listOfTableColumns.size() != colProportions.length )
{
logger.warn( "Number of columns passed and size of column proportions array are different. " +
"Columns resizing shall not be effective on GUI window resizing" );
return;
}
Rectangle area = tableBaseComposite.getClientArea();
Point size = theTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);
ScrollBar vBar = theTable.getVerticalBar();
int width = area.width - theTable.computeTrim(0,0,0,0).width - vBar.getSize().x;
if (size.y > area.height + theTable.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = vBar.getSize();
width -= vBarSize.x;
}
Point oldSize = theTable.getSize();
if (oldSize.x > area.width) {
// table is getting smaller so make the columns
// smaller first and then resize the table to
// match the client area width
int index = 0 ;
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
theTable.setSize(area.width, area.height);
} else {
// table is getting bigger so make the table
// bigger first and then make the columns wider
// to match the client area width
int index = 0;
theTable.setSize(area.width, area.height);
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
}
}`
No need for complicated hacks to remove the extra unwanted column space at the end...
Just create a columnLayout:
TableColumnLayout columnLayout = new TableColumnLayout();
and then set it to each of your columns:
columnLayout.setColumnData(YOUR_VIEWER_COLUMN1.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(YOUR_VIEWER_COLUMN2.getColumn(), new ColumnWeightData(200, 100));
Finally, set the layout on your parent composite:
parent.setLayout(columnLayout);
Full sample:
public void createPartControl(Composite parent) {
TableViewer viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
TableViewerColumn keyColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableViewerColumn valueColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableColumnLayout columnLayout = new TableColumnLayout();
columnLayout.setColumnData(keyColumn.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(valueColumn.getColumn(), new ColumnWeightData(200, 100));
parent.setLayout(columnLayout);
}
Just guessing: maybe your columns do not get resized to fill all the table?
How do you set the widths of columns?
Consider using TableColumnLayout for the table container.
On windows, you will always get an extra column/row if the net width of all the columns that has been set up is less than the dimension of the table. So its always good to make your columns fit your table, also there is some space left for scroll bars, though I am not very sure about this, but its always better to specify whether you want vertical or horizontal scroll bars.
I used the packAndFillLastColumn() method and it worked for me. But I found one issue with it. My table was created with a border. After using the packAndFillLastColumn() method the border for the row no longer exists. I used the setLinesVisible(true) method within the packAndFillLastColumn() method but still that does not work.
So simple! Just remove this line in your table commands inside the createContents function:
table.getColumn(i).pack();
Good-luck
As a workaround use :
-For Column
use TableColumnLayout for the treeViewer's composite and set appropriate column data for each column using:
"tableColumnLayout.setColumnData(column,new ColumnWeightData(...as per your requirement));"
-For Row
Set GridData to the treeViewer's composite and provide height hint using
"gridData.heightHint = table.getItemHeight()*numberOfVisibleRows"
I found eclipse has marked it as WONTFIX.. so can not do much to remove this space..We have tp live with it...:)
To the end column we need to set the setWidth to window size or shell-size, parent-shell size like 1500,5000
final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setResizable(true);
column.setMoveable(true);
//set the setWidth size upto shell size or set upto to some size like 1000,1500,2000,5000
col.setWidth(comp.getShell().getSize().x); // or col.setWidth(1500) ;
return viewerColumn;