Ruben Laguna's blog

Jan 13, 2010 - 6 minute read - beans beansbinding binding database db java jtable lazy loading pagination swing

JTable bound to a database with lazy loading

I’ve been doing experiments with JTables bound to database tables in the past. But I was not satisfied with the result to be honest. The pagination helps but there is still noticeable pauses each time a database query has to be issued. So I started looking into other possibilities.

I come up with the idea of doing lazy loading and presenting some fake data until the data is really retrieved from the database, I did a small proof of concept and seems to work ok.

Jan 3, 2010 - 2 minute read - blinklist bookmarks comma separated values csv del.icio.us delicious html migrating migration ruby script tab

Migrating from Blinklist to Delicious.com: CSV to HTML

Apparently blinklist doesn’t export bookmarks to JSON format any longer and delicious has changed authentication scheme for its delicious API for new accounts (now it forces new users to use the OAuth / Yahoo ID). So the solutions described in this old post of mine doesn’t work.

So given the current state of affairs the only way to get your bookmarks out of Blinklist is CSV (actually tab-separated) and the only easy way to import them to delicious is to use the HTML import. So we need a way to transforms Blinklist’s CSV to HTML bookmark file format. So I created this ruby scripts that takes bookmark.csv and generates bookmarks.html that you can import to delicious.

Nov 15, 2009 - 4 minute read - block flying flyingsaucer java replacedelementfactory sauce xhtmlrenderer

How to handle custom tags using Flying Saucer

If you have a customized xhtml variant, like evernote ENML format and you want to render it with Flying Saucer R8 you must first make sure that the extra element (in ENML case, en-media) is defined as a block-level element. To do that you create your own NamespaceHandler and you make sure that you return "display: block;" for en-media in the implementation of NamespaceHandler.getNonCssStyling. (See ENMLNamespaceHandler.java below)

        ....
        XHTMLPanel panel = new XHTMLPanel();
        panel.setDocument(doc,"",new ENMLNamespaceHandler(new XhtmlNamespaceHandler()));
        ....
        class ENMLNamespaceHandler implements NamespaceHandler {
        ....
           public String getNonCssStyling(Element e) {
               String toReturn = delegate.getNonCssStyling(e);
               if ("en-media".equalsIgnoreCase(e.getNodeName())) {
                  toReturn = "display: block;";
               }
               return toReturn;
           }
        ....
        }

With that you ensure that xhtmlrenderer will call ReplacedElementFactory.createReplacedElement for en-media. Now you must supply a ReplacedElementFactory that it’s able to process en-media. Usually the implementation of the createReplacedElement() involves creating a Swing JComponent, wrapping it in a SwingReplacedElement and adding it to the LayoutContext.getCanvas().

Nov 1, 2009 - 1 minute read - encode incorrect itunes lame length mp3 reencode wrong

Incorrect track length in iTunes

iTunes was reporting a incorrect track time length for an audiobook that I created concatenating several mp3 together.

I had to reencode the whole thing again to make iTunes recognize propertly the track lenght. I could’t reencode the concatenated file itself as that ended up with a Segmentation fault in lame

cat *.mp3 |lame --mp3input - - >resultfile.mp3

cat *Night.mp3 |lame --mp3input -  down.mp3
ID3v2 found. Be aware that the ID3 tag is currently lost when transcoding.
LAME 3.98.2 64bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding <stdin> to down.mp3
Encoding as 44.1 kHz single-ch MPEG-1 Layer III (11x)  64 kbps qval=3
bitstream problem: resyncing...
bitstream problem: resyncing...
bitstream problem: resyncing...
bitstream problem: resyncing...

This uses the lame streaming mode, decodes the input stream (all mp3 concatenated) as mp3 and then reencodes it as mp3. Although it complains about “bitstream problem: resyncing...”, the resulting mp3 sounds fine.

Oct 25, 2009 - 1 minute read - disable dom dtd java load parser validation xerces xml

Disable DOM DTD validation

setValidating(false) will not prevent DTD validation, but you can set http://apache.org/xml/features/nonvalidating/load-external-dtd feature to false. I think is a Xerces-only feature, though, it may not be recognized by other parsers.

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);
        //factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // it doesn't work
        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        DocumentBuilder parser = factory.newDocumentBuilder();
        Document doc = parser.parse(getClass().getResourceAsStream("ennote.xml"));

Typical DTD not found exception stacktrace

java.io.FileNotFoundException: /Users/ecerulm/NetBeansProjects/en4j/NBPlatformApp/DTD/xhtml1-strict.dtd (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1282)
    at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:283)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1193)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1003)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:225)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283)
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
    at com.rubenlaguna.en4j.NoteContentViewModule.NoteContentViewTopComponent.resultChanged(NoteContentViewTopComponent.java:141)
...
...

Oct 1, 2009 - 1 minute read - build build.xml classes classpath compile jaxb netbeans project schema target taskdef xjc xml

Netbeans: Compile schemas into JAXB classes with XJC task

To add a XJC task to a Netbeans build.xml you need to add a -pre-compile target to your build.xml. If it’s a netbeans module build.xml then you need to make compile depend on -pre-compile and projectized-common.compile (see example below). For regular Java Applications just define the -pre-compile target as the standard build.xml will call -pre-compile before compile. Then it’s just a matter of defining the <taskdef> with the proper classpath to the jaxb’s jars.

Sep 28, 2009 - 1 minute read - cce classcastexception java jaxb jaxbcontext netbeans parser woodstox

Netbeans & woodstox: ClassCastException: JAXBContextImpl cannot be cast to JAXBContext

Are you getting a ClassCastException in a Netbeans Platform Application, when you are you sure that the class can be casted? Then check http://wiki.netbeans.org/PlainView.jsp?page=DevFaqModuleCCE. This is most likely the result of the the classes being loaded by different classloaders. So JAXBContextImpl cannot be cast to JAXBContext because that JAXBContext is from Classloader “A” and JAXBContextImpl can only be cast to JAXBContext from Classloader “B”.

SEVERE [global]
java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to javax.xml.bind.JAXBContext
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:145)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244)
        at com.rubenlaguna.en4j.mainmodule.ImportEvernoteFile.actionPerformed(ImportEvernoteFile.java:65)
        at org.openide.awt.AlwaysEnabledAction.actionPerformed(AlwaysEnabledAction.java:115)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:389)
        at com.apple.laf.ScreenMenuItem.actionPerformed(ScreenMenuItem.java:95)
        at java.awt.MenuItem.processActionEvent(MenuItem.java:627)
        at java.awt.MenuItem.processEvent(MenuItem.java:586)
        at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:317)
        at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:305)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:638)
        at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
[catch] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
BUILD SUCCESSFUL (total time: 28 minutes 5 seconds)

So this could happen for example if you have both woodstox in a Netbeans Library Wrapper module and you make you application dependent on ide11JAXB 2.1 Library jaxb21.