Skip to main content



      Home
Home » Eclipse Projects » NatTable » FreezeColumn Nattable 2.0.2 not working( not working the way it was in 1.5.0)
FreezeColumn Nattable 2.0.2 not working [message #1852917] Fri, 10 June 2022 09:59 Go to next message
Eclipse UserFriend
Hi Nattable supporters,

i have updated Nattable from 1.5.0 to 2.0.2 and since then there is a freezecolumn call that is not working anymore. In the new version in FreezeCommandHandler.java there is a new "if" came into.
 @Override
    public boolean doCommand(IFreezeCommand command) {
        // need to convert for correct handling in scrolled state
        // using ViewportLayer#getScrollableLayer() because the positions in the
        // further processing are taking from the scrollable layer, which does
        // not need to be the SelectionLayer in every case
        if (command.convertToTargetLayer(this.viewportLayer.getScrollableLayer())) {
            if (command instanceof FreezeColumnCommand) {


I mean the above if with this call command.convertToTargetLayer(this.viewportLayer.getScrollableLayer()) is always false. When I debug inside, I see that the this.viewportLayer.getScrollableLayer() gives back a selectionLayer whereas the command.convertToTarget(..) needs it to be the instance of my "custom wrapper" PLRCompositeFreezeLayer.

My code to freeze:
int column = 4;
 CompositeFreezeLayer freezeLayer = getBodyLayerStack().getCompositeFreezeLayer(); //which is instance of my PLRCompositeFreezeLayer
        final FreezeColumnCommand freezeColumnCommand = new FreezeColumnCommand(freezeLayer, column);
        freezeLayer.doCommand(freezeColumnCommand);

Then there is this way of creating the layers which i think seems okay for me.

//from above getBodyLayerStack().getCompositeFreezeLayer()
 this.viewportLayer = new ViewportLayer(this.selectionLayer);
        this.freezeLayer = new FreezeLayer(this.selectionLayer);
        this.compositeFreezeLayer = new PLRCompositeFreezeLayer(this.freezeLayer, this.viewportLayer, this.selectionLayer);
        setUnderlyingLayer(this.compositeFreezeLayer);


I looked at and ran this example: https://git.eclipse.org/c/nattable/org.eclipse.nebula.widgets.nattable.git/tree/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_513_FreezeExample.java
but there there is no command.doCommand() but rather it is done through a user action ctr+sh+f

Is there something I am missing to get my code working?
I actually could have done that via the below change but I can't explain how and why it is correct
//in PLRCompositeFreezeLayer
    @Override
    public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) {
        Collection<ILayer> underlyingLayers = new HashSet<ILayer>();
        System.err.println(columnPosition);
        if (columnPosition==4 /*or > 0 because only 0 makes problems*/) {            
            underlyingLayers.add(this.selectionLayer);
        }
        return underlyingLayers;
    }


I appreciate any expertise!
Mokhtar

[Updated on: Fri, 10 June 2022 13:59] by Moderator

Re: FreezeColumn Nattable 2.0.2 not working [message #1852919 is a reply to message #1852917] Fri, 10 June 2022 10:27 Go to previous messageGo to next message
Eclipse UserFriend
First of all, there is no and was never a NatTable 1.9.0!

Second, I think the issue is somewhere in your PLRCompositeFreezeLayer. If I add the command similar to your snippet in the FreezeExample everything works as intended. Not sure what you have customized in your version and why you thought you need to override the default implementation, but maybe you missed some changes done inside the default implementation.
Re: FreezeColumn Nattable 2.0.2 not working [message #1852923 is a reply to message #1852919] Fri, 10 June 2022 14:09 Go to previous messageGo to next message
Eclipse UserFriend
yes my typo. It was the version 1.5.0 (e.g. org.eclipse.nebula.widgets.nattable.core-1.5.0.201703192131.jar).
Thank you!

The legacy PLRCompositeFreezeLayer I have got (anonymized a bit) is as follows. Actually it is just a wrapper of org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer that will fraw a thicker freeze line..
The commentted out lines are what I added to get the freeze working and no column lost. I don't know how that ( my getUnderlyingLayersByColumnPosition() below ) solved the problem but i am sure it is not the correct one.
/*
 * Copyright: (C) Deutsche ...
 * _____________________________________________________________________________
 */
package com.foo.bar.common.ui.table.layers;

import java.util.Collection;
import java.util.HashSet;

import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer;
import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer;
import org.eclipse.nebula.widgets.nattable.freeze.FreezeConfigAttributes;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;

/**
 * PLR-specific extension of CompositeFreezeLayer to implement PLR-specific
 * issues
 * 
 * @version $Revision$
 * @author 
 * @since 07.02.2014
 */
public class PLRCompositeFreezeLayer extends org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer {

    /**
     * 
     * Special layer painter to draw thicker freeze line
     * 
     * @version $Revision$
     * @author $Author$
     * @since 07.02.2014
     */
    class FreezableLayerPainter extends CompositeLayerPainter {

        @Override
        public void paintLayer(final ILayer natLayer, final GC gc, final int xOffset, final int yOffset,
                final Rectangle rectangle,
                final IConfigRegistry configRegistry) {
            super.paintLayer(natLayer, gc, xOffset, yOffset, rectangle, configRegistry);

            Color separatorColor = configRegistry.getConfigAttribute(FreezeConfigAttributes.SEPARATOR_COLOR,
                    DisplayMode.NORMAL);
            if (separatorColor == null) {
                separatorColor = GUIHelper.COLOR_BLUE;
            }

            gc.setClipping(rectangle);
            Color oldFg = gc.getForeground();
            gc.setForeground(separatorColor);
            gc.setLineWidth(2);
            final int freezeWidth = PLRCompositeFreezeLayer.this.freezeLayer.getWidth() - 1;
            if (freezeWidth > 0) {
                gc.drawLine(xOffset + freezeWidth, yOffset, xOffset + freezeWidth, yOffset + getHeight() - 1);
            }
            final int freezeHeight = PLRCompositeFreezeLayer.this.freezeLayer.getHeight() - 1;
            if (freezeHeight > 0) {
                gc.drawLine(xOffset, yOffset + freezeHeight, xOffset + getWidth() - 1, yOffset + freezeHeight);
            }
            gc.setForeground(oldFg);
        }
    }

    private FreezeLayer freezeLayer;
    private FreezableLayerPainter freezableLayerPainter = new FreezableLayerPainter();
    //private SelectionLayer selectionLayer;

    /**
     * 
     * Konstruktor
     * 
     * @param freezeLayer
     * @param viewportLayer
     * @param selectionLayer
     */
    public PLRCompositeFreezeLayer(final FreezeLayer freezeLayer, final ViewportLayer viewportLayer,
            final SelectionLayer selectionLayer) {
        this(freezeLayer, viewportLayer, selectionLayer, true);
    }

    /**
     * 
     * Konstruktor
     * 
     * @param freezeLayer
     * @param viewportLayer
     * @param selectionLayer
     * @param useDefaultConfiguration
     */
    public PLRCompositeFreezeLayer(final FreezeLayer freezeLayer, final ViewportLayer viewportLayer,
            final SelectionLayer selectionLayer,
            final boolean useDefaultConfiguration) {
        super(freezeLayer, viewportLayer, selectionLayer, useDefaultConfiguration);
        this.freezeLayer = freezeLayer;
        //this.selectionLayer=selectionLayer;
    }

    @Override
    public ILayerPainter getLayerPainter() {
        return this.freezableLayerPainter;
    }
    
//    @Override
//    public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) {
//        Collection<ILayer> underlyingLayers = new HashSet<ILayer>();
//        if (columnPosition > 0) {
//            underlyingLayers.add(this.selectionLayer);
//        }
//        return underlyingLayers;
//    }
    
    
    
    
}

Re: FreezeColumn Nattable 2.0.2 not working [message #1852925 is a reply to message #1852923] Fri, 10 June 2022 14:33 Go to previous messageGo to next message
Eclipse UserFriend
just to not make the answer above too long. here is a gain an addition. The logic that does the freeze:
 handleFreezeCommand(coordinatesProvider,
                        freezeColumnCommand.isToggle(), command.isOverrideFreeze());


in org.eclipse.nebula.widgets.nattable.freeze.command.FreezeCommandHandler

Relies on the method from CompositeLayer:
 @Override
    public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) {
        Collection<ILayer> underlyingLayers = new HashSet<>();

        for (int layoutX = 0; layoutX < this.childLayerLayout.length; layoutX++) {
            int columnPositionOffset = getColumnPositionOffset(layoutX);
            if (columnPosition >= columnPositionOffset
                    && columnPosition < columnPositionOffset + this.childLayerLayout[layoutX][0].getColumnCount()) {
                for (int layoutY = 0; layoutY < this.childLayerLayout[layoutX].length; layoutY++) {
                    underlyingLayers.add(this.childLayerLayout[layoutX][layoutY]);
                }
                break;
            }
        }

        return underlyingLayers;
    }


And this returns an empty set always.. This makes the actual freeze logic to be never reached..
I really could catch the chain deeper but never be able to come up with a solution or even why here the layers are empty at some point..

Any help?

Thanks!
Mokhtar
Re: FreezeColumn Nattable 2.0.2 not working [message #1852926 is a reply to message #1852925] Fri, 10 June 2022 14:40 Go to previous messageGo to next message
Eclipse UserFriend
and by the way, due to your answer on an old post in this regard https://www.eclipse.org/forums/index.php/t/424332/
if the nattable is the layer that calls the freeze command, look what that method does look like
@Override
    public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) {
        Collection<ILayer> underlyingLayers = new HashSet<>();
        underlyingLayers.add(this.underlyingLayer);
        return underlyingLayers;
    }

The columnPosition plays no role! That was why I cheated and overrode the method that way but it was making the column left to the freeze line disappeared. When I filter columnpos=0 out, it works fine!

sry again for posting too much and thank you if you will have the time to look at all of this.

[Updated on: Fri, 10 June 2022 14:41] by Moderator

Re: FreezeColumn Nattable 2.0.2 not working [message #1852927 is a reply to message #1852926] Fri, 10 June 2022 15:09 Go to previous messageGo to next message
Eclipse UserFriend
Sorry but I really can't tell anything here.

A) quite a lot happened between 1.5 and 2.0.2, in 1.6 several enhancements and bugfixes regarding the freeze were introduced. I can't remember every detail of the last years.
B) since 1.6 it is possible to configure the freeze separator width. So you should be able to drop your subclass if that is the only reason for the class
C) are you sure the freeze is not applied? Is the column you want to freeze visible?
D) since I don't know your complete layer composition, can you create a reproducable example or take one of our examples and modify it to reproduce the issue? I am not able to reproduce this.
Re: FreezeColumn Nattable 2.0.2 not working [message #1852934 is a reply to message #1852927] Sat, 11 June 2022 09:17 Go to previous messageGo to next message
Eclipse UserFriend
Oh, and one add question. At which time do you execute the command? If you call it at initialization BEFORE the rendering happened, the client area is not yet set, therefore the width of the viewport is 0 and the command is not processed. For the initialization use case you need to use a paint listener or try to operate on the layer api directly.

To be more precise with some code. If you want to programmatically freeze a column at initialization time, either use a PaintListener:

natTable.addPaintListener(new PaintListener() {

    @Override
    public void paintControl(PaintEvent e) {
        int columnPosition = 2;
        compositeFreezeLayer.doCommand(new FreezeColumnCommand(compositeFreezeLayer, columnPosition, false, true));
        natTable.removePaintListener(this);
    }
});


or via the FreezeHelper API:

int columnPosition = 2;
IFreezeCoordinatesProvider coordinatesProvider =
        new FreezeColumnStrategy(freezeLayer, viewportLayer, columnPosition);
FreezeHelper.freeze(
        freezeLayer,
        viewportLayer,
        coordinatesProvider.getTopLeftPosition(),
        coordinatesProvider.getBottomRightPosition());


IIRC the reason for the change in the FreezeCommandHandler were issues in some more complicated layer compositions.

[Updated on: Mon, 13 June 2022 01:21] by Moderator

Re: FreezeColumn Nattable 2.0.2 not working [message #1852961 is a reply to message #1852934] Mon, 13 June 2022 04:55 Go to previous messageGo to next message
Eclipse UserFriend
I was just about to write.. that this call "natTable.doCommand(new FreezeColumnCommand(natTable, 2));" in the referenced example didn't work, too. I guess for the same issue explained. And yes I am calling this inside the "public Control createExampleControl(Composite parent) { ..." just before the last return. So, I will check your input above regarding the paint listener / FreezeHelper but already my "Bauchgefühl" tells me this is the way it is going to work!
Re: FreezeColumn Nattable 2.0.2 not working [message #1852969 is a reply to message #1852961] Mon, 13 June 2022 07:53 Go to previous message
Eclipse UserFriend
SOLUTION
The variant that worked for me now is the one with the PaintListener
public void freezeColumn(final int columnPosition) {
        CompositeFreezeLayer compositeFreezeLayer = getBodyLayerStack().getCompositeFreezeLayer();
        this.natTable.addPaintListener(new PaintListener() {
            
            @Override
            public void paintControl(PaintEvent e) {
                compositeFreezeLayer.doCommand(new FreezeColumnCommand(compositeFreezeLayer, columnPosition, false, true));
                natTable.removePaintListener(this);
                
            }
        });
    }


The one using the Helper API worked but the freezing column gets disappeared!
I will suffice with that for now.

Thank you very much!
Mokhtar
Previous Topic:Custom GridLineCellLayerPainter issue with RowReorderLayer
Next Topic:Freeze columns programmatically
Goto Forum:
  


Current Time: Wed May 21 12:02:02 EDT 2025

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

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

Back to the top