2

I need to set a custom height to my tables/tree rows. Listening to SWT.MeasureItem events works when i have items in my table, but when I have an empty table it doesn't work. Any ideas? Thanks in advance.

viewer.getTree().addListener(SWT.MeasureItem, new Listener() {
     public void handleEvent(Event event) {
        event.height = 30;
     }
  });
Joris Kluivers
  • 11,894
  • 2
  • 48
  • 47
Lori
  • 562
  • 5
  • 24

2 Answers2

2

Are you trying to set the height on a table row, or on the table itself?

If you're trying to set the height of table rows, SWT.MeasureItem events don't get fired unless there's an item to measure - so they wouldn't be fired for an empty table. See the (somewhat questionable seeming) Eclipse bug 134454.

Internally, Table has a setItemHeight(int), but you'd need to use reflection to access it, as it's package protected. Reflection is an advanced language feature that can be exceptionally useful - especially when you need to support multiple versions of the Java runtime, or multiple versions of SWT, where new methods are added or old methods are removed. You can dynamically query the availability of classes, methods, fields, etc, and invoke them only if they exist. In addition, you can access methods and fields that are normally protected to the caller. I wouldn't recommend using Reflection often, but it's nice to fall back on when you have no other alternatives.

This other stackoverflow question does a good job of explaining how to generally invoke a private method, but here's a specific example of getting the method signature for the setItemHeight method and invoking it:

final Table table = new Table(parent, SWT.BORDER);

/* Set up table columns, etc. */

table.pack();

try
{
    /*
     * Locate the method setItemHeight(int). Note that if you do not
     * have access to the method, you must use getDeclaredMethod(). If
     * setItemHeight(int) were public, you could simply call
     * getDeclaredMethod.
     */
    Method setItemHeightMethod =
        table.getClass().getDeclaredMethod("setItemHeight", int.class);

    /*
     * Set the method as accessible. Again, this would not be necessary
     * if setItemHeight(int) were public.
     */
    setItemHeightMethod.setAccessible(true);

    /*
     * Invoke the method. Equivalent to table.setItemHeight(50).
     */
    setItemHeightMethod.invoke(table, 50);
}
catch (Exception e)
{
    /*
     * Reflection failed, it's probably best to swallow the exception and
     * degrade gracefully, as if we never called setItemHeight.  Maybe
     * log the error or print the exception to stderr?
     */
    e.printStackTrace();
}

However, if you're really just trying to set the height on the table itself, it's probably better to do that using your layout. For example, setting GridData.heightHint for a GridLayout.

Community
  • 1
  • 1
Edward Thomson
  • 74,857
  • 14
  • 158
  • 187
  • Hi sorry, I wasn't clear enough, I'm trying to set the height of the table row. I was thinking that i could use a Dummy input for the table, and then reset the input to empty as a workaround, but i really hope i can find a more elegant solution. – Lori Feb 27 '12 at 15:37
  • I see. I think that adding (then removing) some input will preserve the height in the rows, but I think that it will require a paint in order to invoke the measure item listener, in which case you might have flicker. I suppose if your label decorator returned empty strings, it would minimize that, but it still seems like a less than optimal solution. Are you open to reflection to call `Table.setItemHeight(int)`? (I'm not sure if that's more or less of a hack.) – Edward Thomson Feb 27 '12 at 15:44
  • Sorry but i've never used reflection before so I don't really know what you mean. – Lori Feb 28 '12 at 10:10
0

I had the same problem with a table which contained images provided via ColumnLabelProvider method getImage. I wanted higher rows. I noticed that the maximum height of the images you use set the height of the table's rows, so a quite dumb but effective workaround was to use higher images, adding some transparent areas to them.

Giuseppe
  • 597
  • 7
  • 26