Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » column width
column width [message #902647] Thu, 16 August 2012 16:41 Go to next message
Martin Jacob is currently offline Martin JacobFriend
Messages: 191
Registered: July 2009
Senior Member
Hi,

I wonder how can I set the column width to autosize for all columns. Same what happen when double
clicking the header.
On the other hand how can I set the width column specific? I know I can set the default width in the
constructor of DataLayer but this applies to all columns. But I want the first 2 columns larger than
the rest of the table.

looking forward to any hints, Martin
Re: column width [message #902648 is a reply to message #902647] Fri, 17 August 2012 05:36 Go to previous messageGo to next message
Martin Jacob is currently offline Martin JacobFriend
Messages: 191
Registered: July 2009
Senior Member
Hi,

in the meantime I found the solution to set a specific column width:

DataLayer bodyDataLayer = new DataLayer(dataProvider, 45, 20);
bodyDataLayer.setDefaultColumnWidthByPosition(0, 200);
bodyDataLayer.setDefaultColumnWidthByPosition(1, 120);


But how to do the autoresize by the software instead by user action is still unclear.

Martin


Martin Jacob wrote, On 16.08.2012 18:41:
> Hi,
>
> I wonder how can I set the column width to autosize for all columns. Same what happen when double
> clicking the header.
> On the other hand how can I set the width column specific? I know I can set the default width in the
> constructor of DataLayer but this applies to all columns. But I want the first 2 columns larger than
> the rest of the table.
>
> looking forward to any hints, Martin
Re: column width [message #902730 is a reply to message #902648] Mon, 20 August 2012 07:38 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
I think this can be solved by executing the InitialAutoResizeCommand. Not sure if this is the correct name of the command. But hopefully it will point into the right direction.
Re: column width [message #941791 is a reply to message #902730] Fri, 12 October 2012 21:40 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Hi,

quite late, but I have to correct myself. The InitialAutoResizeCommand doesn't work, because on calling the command the NatTable normally the rendering of the NatTable isn't finished. Therefore the size calculation is wrong. Instead you can use the TextPainter and configure it for automatic calculation to achieve autoresizing dependent on the content.

I added a "How to" to the FAQ section of the documentation on this. http://eclipse.org/nattable/documentation.php?page=faq

NatTable also supports percentage sizing since newer versions. This can also be configured within the DataLayer. Documentation on this will follow.

Greez,
Dirk
Re: column width [message #944971 is a reply to message #941791] Mon, 15 October 2012 07:24 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Hi,

I remembered that there was a discussion on SourceForge regarding the same topic, back in the days. The solution found there was to register a listener that will do the autoresize after rendering is finished. To keep this information aswell I modified the FAQ section to also tell the downsites of the TextPainter solution and posted the listener solution aswell.

Greez,
Dirk
Re: column width [message #946318 is a reply to message #902647] Tue, 16 October 2012 05:31 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
I noticed that the virtual nature of the table kind of gets in the way, so I had to leave this paint listener enabled. This works for me,but I wonder whether the calls will scale well. You add it as you add the other OverlayPainters in the examples. I'll take a look at the faq now...

import java.util.HashSet;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.painter.IOverlayPainter;
import org.eclipse.nebula.widgets.nattable.resize.command.InitializeAutoResizeColumnsCommand;
import org.eclipse.nebula.widgets.nattable.resize.command.InitializeAutoResizeRowsCommand;
import org.eclipse.nebula.widgets.nattable.util.GCFactory;
import org.eclipse.swt.graphics.GC;

public class ResizeOverlayPainter implements IOverlayPainter {
private NatTable table;
private HashSet<Integer> rowset;
private HashSet<Integer> colset;

ResizeOverlayPainter(NatTable tb){
table = tb;
rowset = new HashSet<Integer>(100);
colset = new HashSet<Integer>(100);
}
@Override
public synchronized void paintOverlay(GC gc, ILayer layer) {
int count = table.getColumnCount();
for (int i=0; i<count; i++) {
if (table.isColumnPositionResizable(i)==false){
continue;
}
int pos = table.getColumnIndexByPosition(i);
if (colset.contains(pos)) continue;
colset.add(pos);
InitializeAutoResizeColumnsCommand columnCommand = new InitializeAutoResizeColumnsCommand(
table, i, table.getConfigRegistry(), new GCFactory(table));
table.doCommand(columnCommand);
}
count = table.getRowCount();
for (int i=0; i<count; i++) {
if (table.isRowPositionResizable(i)==false){
continue;
}
int pos = table.getRowIndexByPosition(i);
if (rowset.contains(pos)) continue;
rowset.add(pos);
InitializeAutoResizeRowsCommand rowCommand = new InitializeAutoResizeRowsCommand(
table, i, table.getConfigRegistry(), new GCFactory(table));
table.doCommand(rowCommand);
}
}
}
Re: column width [message #946425 is a reply to message #946318] Tue, 16 October 2012 07:37 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Hi,

thanks for your post. You are right, using an IOverlayPainter is of course also a reasonable approach. This way you hook the autoresize directly to the end of NatTable rendering. But it can't remove itself from the NatTable as it would get a ConcurrentModificationException. We can talk about modifying the code there. Smile

And yes, as the NatTable is a virtual table, this approach only works for visible columns and rows. How else should the autoresizing know about the needed space otherwise. So if you need the automatic autoresize in large tables that need to scroll, you'll have to leave the listener active instead of removing it after the initial autoresize. So it is necessary to remember the information which row/column has already be autoresized like you do. Otherwise if you manually resizing your columns, on resizing the view that contains the NatTable, the autoresize will be fired again.

I'm also not quite sure how this listener would scale for larger tables. But in fact I wouldn't do an automatic autoresize of large tables. Well known grids don't do this aswell and leave the sizing of cells to the user who looks at them. Wink

I added this information to the FAQ as this approach could also be really interesting for other users. Let me know if it is ok with you or if you want me to modify the text in some ways. Feedback is very welcome!

Thanks,
Dirk
Re: column width [message #946893 is a reply to message #946425] Tue, 16 October 2012 15:59 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
ok for using it in the faq. I added your faq example code to the Big_data example and found a couple of problems ...
1. in your example you'd need to change natTable to final.
2. in your example you'd need to remove the override.
Then it builds ok.

The big_data example runs then, but is fairly unresponsive. I believe the time is being spent in getPreferredColumnWidth, which doesn't scale. It appears to look at all rows during execution of InitializeAutoResizeColumnsCommand, rather than just at the the viewed rows. A version of these which only considered the viewed cells might be more responsive. It currently takes on the order of 30 secs per column to resize.

The getPreferedRowHeights is doing the same, but the Big_data example only has 500 rows, and so its problems don't show up in my current test. But if I change the test to 10K rows and 10K columns I see even worse responsiveness due to getPreferedRowHeights calculation relative to getPreferredColumnWidth. So probably should have a more responsive version of both of these for large virtual tables, limiting to just the viewed columns and rows for the resize preferred heights and widths.

private static int getPreferredColumnWidth(ILayer layer, int columnPosition, IConfigRegistry configRegistry, GC gc) {
ICellPainter painter;
int maxWidth = 0;
ILayerCell cell;

for (int rowPosition = 0; rowPosition < layer.getRowCount(); rowPosition++) {

[Updated on: Tue, 16 October 2012 16:55]

Report message to a moderator

Re: column width [message #947018 is a reply to message #946893] Tue, 16 October 2012 18:37 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
1. that's correct, added it to the example
2. well that's true for the Big_data example as the examples are compiled against Java 5. Since Java 6 @Override is also allowed for interfaces. Wink

Of which getPreferredColumnWidth() are you speaking. Could you please be a bit more precise so we can have a look at the specific class?

As I also wrote in the FAQ, we do not suggest to use initial autoresizing on startup because of several issues regarding behaviour on scrolling and the performance issues you noticed. If you have an idea how to solve this, feel free to contribute. We are open for improvements. Smile
In the meantime maybe the TextPainter solution could fit your needs?

Greez,
Dirk
Re: column width [message #947058 is a reply to message #941791] Tue, 16 October 2012 19:25 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
I tried your cellPainter example from the faq and added this code to the Big_data example. This works very much faster than the IOverlayPainter example that I experimented with. However, updates lag increasingly as you scroll to the right, and it seems to be related to the number of table columns. For example, if you change the Big_data example to have 1 Million rows and 1 Million columns, then scroll to the middle of the range on both horizontal and vertical, then scroll down single step takes on the order of 10 secs and scroll to right take on order of 5 secs. If you scroll to end of range on both, then scoll single step left takes about 11 seconds, and scroll single step up takes about 15 sec.
At the top of range on both bars, scroll single step down occurs immediately, scroll singe step right occurs immediately. So there is likely some code buried in there that is processing the whole table dimensions rather than just the viewed port.


final NatTable natTable = new NatTable(parent,layer,false);
ConfigRegistry configRegistry = new ConfigRegistry();
natTable.setConfigRegistry(configRegistry);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration() {
{
cellPainter = new LineBorderDecorator(
new TextPainter(false, true, 5, true));
}
});
natTable.configure();
Re: column width [message #947247 is a reply to message #947018] Wed, 17 October 2012 00:05 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
Dirk Fauth wrote on Tue, 16 October 2012 14:37
Of which getPreferredColumnWidth() are you speaking. Could you please be a bit more precise so we can have a look at the specific class?

As I also wrote in the FAQ, we do not suggest to use initial autoresizing on startup because of several issues regarding behaviour on scrolling and the performance issues you noticed. If you have an idea how to solve this, feel free to contribute. We are open for improvements. Smile
In the meantime maybe the TextPainter solution could fit your needs?

Greez,
Dirk


The getPreferredColumnWidth is in
org.eclipse.nebula.widgets.nattable.resize.MaxCellBoundsHelper

I do have a suggestion that getPreferredColumnWidth shouldn't be going over all the rows ... just the visible ones viewed when you scroll into a new section.


I did try creating the new TextPainter, as you suggested in the faq, and that works better, but also appears to have some lag related to the number of rows and columns. I'll look into it more.
Re: column width [message #947396 is a reply to message #947247] Wed, 17 October 2012 03:44 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
I've done some investigation into the slower performance for the resize processing as the arrays get larger, and I suspect at least a part of the problem is explained by the implementation of the ColumnReorderLayer lookups. The cross-reference is being contained as an ArrayList, and the cross-reference lookups are being done using an indexOf operation, which iterates through the whole ArrayList looking for the first occurrence of the columnIndex. So as you operate on columns and rows that are at the upper ends of large row and column counts, you spend increasing time in this lookup. So columnIndexOrder needs to be converted to something that has constant lookup time.

public int getColumnPositionByIndex(int columnIndex) {
return columnIndexOrder.indexOf(Integer.valueOf(columnIndex));
}


I've confirmed this is the major problem. I added an int[] version of list and a reverse index int[] version of the list, and use those for the look-ups. Then on 100k by 100k grids, all the resize updates for a page are constant time anywhere on the grid and reasonably fast.

[Updated on: Wed, 17 October 2012 06:56]

Report message to a moderator

Re: column width [message #948131 is a reply to message #947018] Wed, 17 October 2012 19:48 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
Another place where InitializeAutoResizeColumnsCommand is causing a problem:


The Big_Data example has a million rows, and has an AutoResizeColumnAction action bound to the header in DefaultColumnResizeBindings. That action calls InitializeAutoResizeColumnsCommand, which makes the example hang while it looks at all the rows if you happen to double click on one of the column header separators.

A reasonable fix might be to limit the range of the rows inspected to the view or to some reasonable sized range that includes the view.

DefaultColumnResizeBindings

uiBindingRegistry.registerDoubleClickBinding(new ColumnResizeEventMatcher(SWT.NONE, GridRegion.COLUMN_HEADER, 1), new AutoResizeColumnAction());

InitializeAutoResizeColumnsCommand command = new InitializeAutoResizeColumnsCommand(natTable, column, natTable.getConfigRegistry(), new GCFactory(natTable));

The problem is because MaxCellBoundsHelper.getPreferedColumnWidths looks at all rows, which appears to hang on this million row example.
Re: column width [message #948149 is a reply to message #948131] Wed, 17 October 2012 20:11 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Hi,

Thank you very much for your investigation. Would you like to contribute your solution?

Greez,
Dirk
Re: column width [message #948325 is a reply to message #948149] Thu, 18 October 2012 00:19 Go to previous messageGo to next message
Jay Norwood is currently offline Jay NorwoodFriend
Messages: 155
Registered: July 2009
Senior Member
I haven't created a fix yet for the InitializeAutoResizeColumnsCommand.

I am adding fixes that improve the big_data example performance. The changes are to remove use of ArrayList.indexOf in the column reorder layer and column hide layer.
Re: column width [message #948583 is a reply to message #948325] Thu, 18 October 2012 06:50 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Quote:
The changes are to remove use of ArrayList.indexOf in the column reorder layer and column hide layer.


Well you've found and solved a potential performance issue. And if your solution doesn't break any other use cases of the NatTable, than it is an improvement worth contributing. Smile
ColumnReorderLayer and ColumnHideLayer are used a lot. So any improvement will be useful for many people.

As it is used a lot, of course we have to double/triple check if it has any impact. One thing that comes into my mind without having a closer look is that arrays have a fixed size. So arrays can't grow afterwards. And then it won't be possible to add new data to the NatTable after initial creation correctly. But this needs to be verified.
Re: column width [message #1712658 is a reply to message #948583] Tue, 27 October 2015 09:32 Go to previous message
Ines El Euch is currently offline Ines El EuchFriend
Messages: 35
Registered: March 2015
Member
Hello everyone,

If anyone is still concerned about this, It propably isn't related fully to this topic but very alike. The solution I propose in here is mostly describing the topic mentioned by Jose in here http://sourceforge.net/p/nattable/discussion/744994/thread/f94a6b96/ . I was inspired but what she proposed as a solution to find mine. Anyway, this is what I did:

In my class BodyLayerStack, I define the width percentage of each of my columns (of course making sure that the sum is 100%) and I have 3 columns in my nattable:

 bodyDataLayer = new DataLayer(this.bodyDataProvider);      
         bodyDataLayer.setColumnPercentageSizing(true);
         bodyDataLayer.setColumnWidthPercentageByPosition(0, 30);
         bodyDataLayer.setColumnWidthPercentageByPosition(1, 30);
         bodyDataLayer.setColumnWidthPercentageByPosition(2, 40);


Of course make sure that your table with is the same as its parent (if you want your nattable to have this size of course)

add this after you have defined you natTable, just after the natTable.configure() (it needs to be the last thing you do when creating your table)
 GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);		    
		return natTable;


I hope this will help others.

Best regards,
Ines
Previous Topic:addColumnsIndexesToGroup
Next Topic:collapse column groups
Goto Forum:
  


Current Time: Tue Mar 19 07:18:51 GMT 2024

Powered by FUDForum. Page generated in 0.03192 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top