Pergunta

I've subclassed Swingx's ComponentProvider to provide JButtons but on some lines of my JXTreeTable, I don't want to show any button. The final "result" I want is to have an empty cell, like what I get when showing an empty text in a column for which I haven't set a provider.

  1. Is it possible to hide the rendered component on certain rows (depending on the value for example)? Setting setVisible(false) on the rendered component in format() or configureState() doesn't work.

  2. Is it possible to subclass ComponentProvider to provide different several types of Components? If yes, how would that work?

  3. Where can I find some examples of the possibilities that the ComponentProvider offers and a clear explanation of which method does what (for example, I hardly understand the difference between configureState() and format())?

EDIT

  1. Is it possible to prevent a JButton displayed in a JX(Tree)?Table to be as wide as the cell?

  2. If I create another highlighter, can I use another predicate (ROLLOVER or something) to change the cursor? The cursor change to a hand (over a link) even if the button is hidden.

Many thanks!

Foi útil?

Solução

Interesting :-)

  1. generally doesn't work because the CellRendererPane doesn't respect the component's visible property - it stamps it always. BUT: can work in SwingX if the actual provider it wrapped into a WrappingProvider and then that wrapper's component is set invisible.

a snippet, just as proof-of-concept

table.getColumn(1).setCellRenderer(new DefaultTableRenderer(
        new WrappingProvider(IconValues.NONE, new ButtonProvider(), false) {

            @Override
            protected void configureState(CellContext context) {
                super.configureState(context);
                rendererComponent.getComponent().setVisible(context.getRow() != 5);
            }

        }
));

On the other hand, the provider is not the place for plugging in custom context-dependent configuration. That should be done in a Highlighter, as f.i. in

AbstractHighlighter highlighter = new AbstractHighlighter(HighlightPredicate.EVEN) {

    @Override
    protected Component doHighlight(Component component,
            ComponentAdapter adapter) {
        ((WrappingIconPanel) component).getComponent().setVisible(false);
        return component;
    }

    @Override
    protected boolean canHighlight(Component component,
            ComponentAdapter adapter) {
        return component instanceof WrappingIconPanel;
    }


};
table.addHighlighter(highlighter);

Which doesn't work as expected (the button is always hidden) because is not one of the properties which are guaranteed to be reset in the provider. Nothing prevents custom providers to extend those guarantees, like

table.getColumn(1).setCellRenderer(new DefaultTableRenderer(
        // custom wrappingProvider which guarantees the reset of visible
        // property of the wrapped component
        new WrappingProvider(IconValues.NONE, new ButtonProvider(), false) {
            @Override
            protected void configureState(CellContext context) {
                super.configureState(context);
                rendererComponent.getComponent().setVisible(true);
            }

        }
));

Now the highlighter can fearlessly change the visible based on context. A slight visual glitch: the WrappingIconPanel always leaves some space for the icon, even if there is none - not quite sure why that happens or whether it would be safe (in SwingX) to remove that spacing (the wrappingProvider originally is meant for use in JXTree, it's not installed by default because there are still issues with ComponentOrientation).

  1. (2 in the question) not supported, the componentProvider is designed to return the same single component configured with the exact same properties on each call

  2. (3 in the question) cough ... no, nothing but the sources and examples (in the demos and the test packages)

Edit (to answer the edited part of the question)

  1. no, with the current WrappingIconpPanel: it does use a Borderlayout which - as we all know :-) doesn't respect max size. Using a BoxLayout would but had issues that I don't fully remember. Nevertheless, that would be the place to tweak, so that the button's max would be respected

  2. hmmm ... not entirely sure how you implemented the cursor change. Assuming that it's in your ButtonProvider: implement the isRolloverEnabled to return true/false depending on whether it is visible or not Edit-in-Edit doesn't work. Don't know why, could be that this is a bug in rollover-dectection and/or handling in WrappingProvider

Off into the weekend now :-)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top