Prior Art

Swiby is influenced by many things

Flash

Macromedia / Adobe's incredibly pervasive fat-experience media-rich browser plugin. Youtube and other illustrate how transparent Flash can be.

JavaFX

JavaFX (formerly F3) is Sun's answer to Flash. It introduced a new language that was more friendly to designers and tools. Under the hood it was Java though and leverages Java technologies Swing and media libraries. Traditionally Java has been inaccessible to UI design specialists using tools, it remains to be seen whether JavaFX can cross the chasm.

Thicky

From 2004, and using an early Groovy (when it still had an interpreter) rather than JRuby. Thicky was a page-by-page interpreted UI markup language that leveraged the SwingBuilder than the Groovy team had made. Like one mode of Swiby, it provided a context/kernel for page navigation and similar 'browser' functions. The intenty was to use instead of HTML & Javascript for some applications.

Here was are some screen shots of its browser-test frame and some pages rendered within it, with source for each:

Page 1
// Fairly standard imports.
import groovy.util.BuilderSupport
import org.thicky.client.SwingPage
import org.thicky.client.Titled
import org.thicky.client.ThickyContext

// used by Page1
import javax.swing.border.TitledBorder

// used by inlined classes Fruit and FruitRenderer
import javax.swing.JLabel
import javax.swing.ImageIcon
import javax.swing.JList
import javax.swing.ListCellRenderer
import java.awt.Component

class Page1 extends SwingPage implements Titled {

  Page1(ThickyContext context, BuilderSupport builder) {
    super(builder)
    context.setBackPoint(true);
    body(border:new TitledBorder("A 2 by 3 table")) {
      tableLayout() {
        tr {
          td {
            label(text:'<html>Unfortunately Images are not<br>downloaded asynchronously.' +
                  '<br>A fix is needed to<br>speed up the initial page load.</html>')
          }
          td() {
            label(text:'AnotherLabel').setBorder(new TitledBorder("Fancy Border"))          
          }
        }
        tr {
          td() {
            button(text:'Go to page 2', actionPerformed:{ context.goTo("Page2.groovy") })
          }
          td() {
            comboBox(items:[new Fruit(context, 'apple','apple.gif'), new Fruit(context,
                  'banana','banana.gif')]).setRenderer(new FruitRenderer())
          }
        }
        tr {
          td() {
            lazyLabel(text:'Another Apple', imageUrl:'apple.gif')
          }
          td {

          }
        }
      }
    }
  }

  String getTitle() {
    return "Page One";
  }

}

// Inlined classes .........

// These two should be general and standard one day.
public class Fruit extends JLabel {
  public Fruit(ThickyContext context, String name, String image) {
    super(name, new ImageIcon(context.makeAbsoluteURL(image)), JLabel.LEFT)
  }
}
public class FruitRenderer implements ListCellRenderer {
    public Component getListCellRendererComponent( JList list, Object value, int index, 
          boolean isSelected, boolean cellHasFocus) {
        return (Fruit) value;
    }
}

Page 1 with drop down pressed

page 1  
Page 2 page 2
import groovy.util.BuilderSupport
import org.thicky.client.SwingPage
import org.thicky.client.Titled
import org.thicky.client.ThickyContext

class Page2 extends SwingPage implements Titled {

  Page2(ThickyContext context, BuilderSupport builder) {
    super(builder)
    body() {
      button(text:'Go to page 3', actionPerformed:{ 
            context.goTo("Page3.groovy") })
      button(text:'Go to BOGUS', actionPerformed:{ 
            context.goTo("NoPage.groovy") })
    }
  }

  String getTitle() {
    return "Page Two";
  }

}
Page 3 page 3
import javax.swing.JComponent
import groovy.util.BuilderSupport
import org.thicky.client.SwingPage
import org.thicky.client.Titled
import org.thicky.client.ThickyContext

class Page3 extends SwingPage implements Titled {

  Page3(ThickyContext context, BuilderSupport builder) {
    super(builder)
    body() {
      label(text:'hello')
      button(text:'Go to page 1', actionPerformed:{ 
            context.goTo("Page1.groovy") })
      def alphabet = ['a','b','c','d','e','f','g','h',
            'i','j','k','l','m','n','opqrstuvwxyz']
      def combo = comboBox()
      for(letter in alphabet) {
        combo.addItem(letter)
      }
      comboBox(items:alphabet) {
      }
    }
  }

  String getTitle() {
    return "Page Three";
  }
}