Writing a Java library to conditionally process an input class without explaining an unconditional dependency on this class

I have what seems like a daunting task of the Java library.

I need to write adapter / helper class to work with JTable, which has some additional features, if JTableis JXTable. But I do not want to add a run-time dependency on swingx-core-1.6.2.jar if my application does not actually use JXTable (in this case it already requires the presence of a jing SwingX file in the classpath)

How can I separate my code from this? I don’t even know how I can test JXTable; if I try to use instanceof JXTableas a test, it means that my code already has an unconditional runtime dependency on JXTable.

I wrote Java libraries before they have “extra” runtime dependencies: if I have this in my library:

package com.foobar.foolib;

// import from whizbang.jar
import com.whizbang.BloatwareThingy;

public class SuperObject
{
    /* ... uses a BloatwareThingy ... */
}

and SuperObject- the only class that uses whizbang.jar, then while my final application is not using SuperObject, then there is no runtime dependency on whizbang.jar; if my final application really wants to use SuperObject, then it needs to include whizbang.jar in the classpath. Optional from an application point of view. It works great.

How to write a method to verify that a given JTable is an instance of JXTable without requiring a dependency on the SwingX jar file if the application uses only JTable?

+5
4

:

Class cls = null;
try {
    cls = Class.forName( "org.jdesktop.swingx.JXTable" );
} catch( Throwable ex ) {}

if( cls != null )
    // have JXTable

Reflection , , .

, API , , JXTable , Reflection :

public interface MyTableHandler
{
    void doSomethingWithTable( JTable table );
}

public class JXTableHandler implements MyTableHandler
{
    void doSomethingWithTable( JTable table )
    {
        JXTable jxt = (JXTable) table;
        // use JXTable API directly ...
    }
}

public class StdTableHandler implements MyTableHandler
{
    void doSomethingWithTable( JTable table )
    {
        // do without JXTable
    }
}

public class MyIndependentClass
{
    static final MyTableHandler handler;

    static {
        try {
            Class.forName( "org.jdesktop.swingx.JXTable" ); // force exception
            handler = (MyTableHandler) Class.forName( "my.pkg.JXTableHelper" )
                                            .newInstance();
        } catch( Throwable ex ) {
            handler = new StdTableHandler();
        }
    }
    public void treatTable( JTable table )
    {
        handler.doSomethingWithTable( table );
    }
}

Java API , , jar. JXTableHandler, org.jdesktop.swingx.JXTable StdTableHandler.

+5

. Class.forName(...) JXTable. , ClassNotFoundException.

, , JTable.

+2

, , , .

if (table.getClass().getName().equals("path.to.JXTable")
{
// Do something using reflection.
}
else // proceed as normal
0

, :

:

static private class JXTableHandler
{
    public JXTableHandler() {}

    boolean testJXTable(JTable table)
    {
        try
        {
            if (table instanceof JXTable)
                return true;
        }
        catch (java.lang.NoClassDefFoundError e) { /*gulp*/ }
        return false;
    }
    boolean handleTable(JTable table)
    {
        if (!testJXTable(table))
            return false;

        JXTable xtable = (JXTable) table;
        // here where we do stuff, this is just something basic
        System.out.println("columnControlVisible: "
             +xtable.isColumnControlVisible());
        return true;
    }
}

:

    JComponent c = ...

    if (c instanceof JTable)
    {
        JTable table = (JTable) c;
        boolean isJXTable = new JXTableHandler().handleTable(table);
        System.out.println("jtable "+
            (isJXTable ? "is" : "is not")+" a jxtable");
    }

, JTables, swingx , , NoClassDefFoundError JXTable. JXTable swingx , . ( "", JXTable swingx , JXTable, .)

0

All Articles