package textbender.a.b.rhinohideDemo._; // Copyright 2007, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Textbender Software"), to deal in the Textbender Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Textbender Software, and to permit persons to whom the Textbender Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Textbender Software. THE TEXTBENDER SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE TEXTBENDER SOFTWARE OR THE USE OR OTHER DEALINGS IN THE TEXTBENDER SOFTWARE. import java.awt.*; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.*; import javax.swing.border.EmptyBorder; import org.w3c.dom.*; import textbender.g.lang.*; import textbender.g.util.logging.LoggerX; import textbender.o.Browser; import textbender.o.rhinohide.*; import textbender.o.rhinohide._.*; import static textbender.o.xhtml.XHTML.XHTML_NAMESPACE; /** Demo of Rhinohide, Core Level 2. * * @see http://reluk.ca/var/cache/rhinohide-demo/textbender/a/b/rhinohideDemo/Core_2_Demo.html * @see http://reluk.ca/var/cache/rhinohide-demo/textbender/a/b/rhinohideDemo/Core_2_Demo.xht */ public @ThreadRestricted("AWT event dispatch") final class Core_2_Demo extends JApplet implements Runnable { // - A p p l e t ---------------------------------------------------------------------- private final AtomicBoolean isStartedA = new AtomicBoolean(); public @ThreadSafe void start() { if( isStartedA.getAndSet( true )) return; // start once only LoggerX.i(getClass()).info( "starting" ); EventQueue.invokeLater( Core_2_Demo.this ); // in AWT event dispatch thread } private final AtomicBoolean isDestroyedA = new AtomicBoolean(); public @ThreadSafe void destroy() { if( isDestroyedA.getAndSet( true )) { assert false; return; } LoggerX.i(getClass()).info( "destroying" ); if( window != null ) window.release(); } // - R u n n a b l e ------------------------------------------------------------------ /** Runs this test applet. */ public void run() { reportList.addElement( "starting..." ); // ThreadSafe.U.disableChecking(); // I lack permission, I'm an unsigned applet { // Construct GUI. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JList reportListV = new JList( reportList ); reportListV.setBorder( new EmptyBorder( /*top*/2, /*left*/2, /*bottom*/2, /*right*/0 )); JScrollPane scrollPane = new JScrollPane( reportListV ); scrollPane.setBorder( null ); getContentPane().add( scrollPane, BorderLayout.CENTER ); } try { window = RhiWindow.createWindow( Core_2_Demo.this ); // Query DOM implementation. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - final Document document = window.getDocument(); reportList.addElement ( "browser supports Core Level 2... " + document.getImplementation().hasFeature( "Core", "2.0" ) ); // Start a DOM manipulator. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - final Thread thread = new Thread( new Manipulator(), "manipulator" ); thread.setDaemon( true ); thread.setPriority( Thread.NORM_PRIORITY - 1 ); thread.start(); // - - - reportList.addElement( "successfully started" ); } catch( StunnedRhinoException xSR ) { LoggerX.i(getClass()).info( Browser.pageExitSupressionMessage( xSR )); } // in case the page exits, from beneath us catch( Exception x ) // all, checked or not { LoggerX.i(getClass()).log( LoggerX.WARNING, /*message*/"", x ); } } //// P r i v a t e /////////////////////////////////////////////////////////////////////// @ThreadRestricted( "AWT event dispatch" ) private final DefaultListModel reportList = new DefaultListModel(); private volatile RhiWindow window; // final after init // ==================================================================================== private final class Manipulator implements Runnable { Manipulator() { final Document document = window.getDocument(); final String namespace; if( document.isSupported( "XML", ""/*any version*/ )) namespace = XHTML_NAMESPACE; else namespace = null; // parsed as plain old HTML // Actually, that fails to detect HTML, at least in firefox 1.5 (per textbender.o.Browser.isXML). No harm, maybe. Is there no easy way to detect, in DOM 2? // Create element // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Element parent = document.getElementById( "parent-of-created" ); Element createdElement = document.createElementNS( namespace, "span" ); createdElement.setAttributeNS( null, "class", "altered" ); // neither HTML nor XHTML attributes have namespaces Text text = document.createTextNode( "Hello world, from Java" ); createdElement.appendChild( text ); parent.appendChild( createdElement ); // - - - Element alteredElement = document.getElementById( "altered" ); alteredText = (Text)alteredElement.getFirstChild(); } private final Text alteredText; public void run() { // Alter text // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - for( int n = 1;; ++n ) { ThreadX.trySleep( 1000/*ms*/ ); if( isDestroyedA.get() ) break; alteredText.setData( Integer.toString( n )); } } } }