The “Support for SwingX components” series (parts i, ii, iii, iv, v, vi, vii and viii) showed the the support for SwingX components in Substance look and feel, while the “Advanced animations on core Swing components” series (parts i, ii, iii and iv) showed the extensive enhancements to the animations done on the core Swing components. This entry shows the extended animations available on the JXMonthView component in the latest drop of the Substance SwingX plugin.

With the great help of Jan Haderka of SwingX project (see the progress on this issue), the JXMonthView now features complete rollover and selection animations which are fully consistent with animations on core JLists, JTrees and JTables. The first video shows different rollover and selection animations on a month view component under the Office Silver 2007 skin. Note how the animations respect different state-specific color schemes and alpha values.


The second video shows the same month view component under the dark Raven Graphite skin:

The last video shows the same month view component under the dark Magma skin. Note the rollover and selection animations are done on both the background and the foreground colors. Also note that the animations are done on the individual days as well as on the month view header (which now uses drop-shadow painting of the month / year strings):

This is the fourth part in the ongoing series about advanced animations on core Swing component built-in to the latest binary drops of Substance look-and-feel.

  • The first part showed rollover and selection background animations on menus, sliders, tables and table headers
  • The second part showed rollover foreground animations on menus under a skin that uses dark background fill on menubars
  • The third part showed rollover and selection background and foreground animations under a mixed dark-light theme

This part demonstrates the animations under the new Magma skin. Unlike other mixed dark-light skins (Nebula, Nebula Brick Wall and Business Black Steel), pretty much all animations under Magma feature dark-light transitions for both background and foreground colors. Here is a sample video that shows animation effects on buttons, toggle buttons, checkboxes and radio buttons (note that for the later two, the foreground is not animated):


The next video shows rollover animation effects on Magma sliders:

The last video shows a complex rollover animation effect on Magma tabs. Substance provides support for tab close buttons. When installed, Substance shows the close buttons on the currently selected and the currently rolled over tab. On rolled over tabs, the close button is faded as the mouse moves over the tabbed pane. For Magma, this means that the close button animation has two channels – during the fade in, the color fades from white to black, and the alpha fades from 0.0 to 1.0. During the fade out, the color fades from black to white, and the alpha fades from 1.0 to 0.0. The video shows the rollover animation sequence under very slow animation speed so you can follow this effect:
You can run a test WebStart application by clicking the button below. The application is signed and requires read-only access to the local disk (for the filetree). In order to switch to Magma, go to the Skins menu and select “Magma”.

It’s finally time to release one of my favorite new skins for Swing applications. The latest 4.0dev drop of Substance provides full support for a new dark skin named Magma. Like Nebula, Nebula Brick Wall and (partially) Business Black Steel, it uses a mix of dark and light color schemes, but takes this one step further. In Magma, the default and disabled color schemes are dark, and the active (selected, pressed, armed, rollover) color schemes are light (saturated Sunset shifted to red). In addition, like Autumn, it uses the same color scheme for the default and disabled states, and defines a custom alpha value (translucency) for the disabled state. The end result (see screenshots below) is that the disabled controls appear less “visible” as the default controls. This also means that the watermark “shines through” the disabled controls (look closer at the disabled buttons in the first screenshot below).

Here are a few screenshots of different controls under the new Magma skin. Buttons, toggle buttons, checkboxes and radio buttons in different states (default, selected, disabled and disabled selected):

Comboboxes in different states (default, active, disabled, with custom background):

An internal frame with a few controls:

Horizontal and vertical sliders in different states (enabled, disabled, ticks, labels, RTL). Note the translucent layers on the disabled sliders:

Progress bars (horizontal, vertical, determinate, indeterminate, with caption):

Tree with a selected and rollover path:

A control panel with different controls embedded in a SwingX task pane:

SwingX error pane:

SwingX month view:

A frame with menubar, toolbar and status bar from SwingX:

You’re welcome to try this skin and report any issues / RFEs that you find.

This also marks the core feature freeze stage for the 4.0 version of Substance. From this point on, only the user-requested features, minor polishments and bugfixes will be done on the main trunk. Since version 4.0 introduces binary incompatibilities with the previous release, you’re welcome to follow the instructions in the migration guide in order to migrate to version 4.0 (in case your application uses Substance-specific APIs and client properties). The final release is planned for September 4th.

You can run a test WebStart application by clicking the button below. The application is signed and requires read-only access to the local disk (for the filetree). In order to switch to Magma, go to the Skins menu and select “Magma”.

Year of the Desktop Linux

July 12th, 2007
    
<font color="#7f0055"><strong>import </strong></font><font color="#000000">java.awt.*;</font>
<font color="#7f0055"><strong>import </strong></font><font color="#000000">java.util.Calendar;</font>

<font color="#7f0055"><strong>import </strong></font><font color="#000000">javax.swing.*;</font>

<font color="#7f0055"><strong>public class </strong></font><font color="#000000">YearOfLinuxDesktop </font><font color="#000000">{</font>
<font color="#ffffff">  </font><font color="#7f0055"><strong>private static class </strong></font><font color="#000000">YearOfLinuxDesktopPanel </font><font color="#7f0055"><strong>
        extends </strong></font><font color="#000000">JPanel </font><font color="#000000">{</font>
<font color="#ffffff">    </font><font color="#646464">@Override</font>
<font color="#ffffff">    </font><font color="#7f0055"><strong>protected </strong></font><font color="#7f0055"><strong>void </strong></font><font color="#000000">paintComponent</font><font color="#000000">(</font><font color="#000000">Graphics g</font><font color="#000000">) {</font>
<font color="#ffffff">      </font><font color="#000000">Graphics2D g2d = </font><font color="#000000">(</font><font color="#000000">Graphics2D</font><font color="#000000">)</font><font color="#000000">g.create</font><font color="#000000">()</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">g2d.setColor</font><font color="#000000">(</font><font color="#000000">Color.white</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">g2d.fillRect</font><font color="#000000">(</font><font color="#990000">0</font><font color="#000000">, </font><font color="#990000">0</font><font color="#000000">, getWidth</font><font color="#000000">()</font><font color="#000000">,
           getHeight</font><font color="#000000">())</font><font color="#000000">;</font>

<font color="#ffffff">      </font><font color="#000000">g2d.setColor</font><font color="#000000">(</font><font color="#000000">Color.black</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">Calendar calendar = Calendar.getInstance</font><font color="#000000">()</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">String str = </font><font color="#000000">(</font><font color="#000000">calendar.get</font><font color="#000000">(</font><font color="#000000">Calendar.YEAR</font><font color="#000000">)</font><font color="#000000">
        + </font><font color="#990000">1</font><font color="#000000">)</font><font color="#000000">+ </font><font color="#2a00ff">
        " will be the year of Linux desktop"</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">g2d.setFont</font><font color="#000000">(</font><font color="#000000">g2d.getFont</font><font color="#000000">()</font><font color="#000000">.deriveFont</font><font color="#000000">(</font><font color="#990000">20.0f</font><font color="#000000">))</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">FontMetrics fm = g2d.getFontMetrics</font><font color="#000000">()</font><font color="#000000">;</font>

<font color="#ffffff">      </font><font color="#000000">g2d.setRenderingHint</font><font color="#000000">(
          </font><font color="#000000">RenderingHints.KEY_TEXT_ANTIALIASING,</font>
<font color="#ffffff">          </font><font color="#000000">RenderingHints.VALUE_TEXT_ANTIALIAS_ON</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#3f7f5f">// The following is safe to call on Linux
      // as well</font><font color="#3f7f5f"> since the rendering is done in
      // Java and not with</font><font color="#3f7f5f"> native APIs.
</font><font color="#ffffff">      </font><font color="#000000">g2d.drawString</font><font color="#000000">(</font><font color="#000000">str, </font><font color="#000000">
          (</font><font color="#000000">getWidth</font><font color="#000000">() </font><font color="#000000">- fm.stringWidth</font><font color="#000000">(</font><font color="#000000">str</font><font color="#000000">)) </font><font color="#000000">/ </font><font color="#990000">2</font><font color="#000000">,</font>
<font color="#ffffff">          </font><font color="#000000">(</font><font color="#000000">getHeight</font><font color="#000000">() </font><font color="#000000">- fm.getHeight</font><font color="#000000">()) </font><font color="#000000">/ </font><font color="#990000">2</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">g2d.dispose</font><font color="#000000">()</font><font color="#000000">;</font>
<font color="#ffffff">    </font><font color="#000000">}</font>
<font color="#ffffff">  </font><font color="#000000">}</font>

<font color="#ffffff">  </font><font color="#7f0055"><strong>public static </strong></font><font color="#7f0055"><strong>void </strong></font><font color="#000000">main</font><font color="#000000">(</font><font color="#000000">String</font><font color="#000000">[] </font><font color="#000000">args</font><font color="#000000">) {</font>
<font color="#ffffff">    </font><font color="#000000">SwingUtilities.invokeLater</font><font color="#000000">(</font><font color="#7f0055"><strong>new </strong></font><font color="#000000">Runnable</font><font color="#000000">() {</font>
<font color="#ffffff">      </font><font color="#7f0055"><strong>public </strong></font><font color="#7f0055"><strong>void </strong></font><font color="#000000">run</font><font color="#000000">() {</font>
<font color="#ffffff">        </font><font color="#000000">JFrame frame = </font><font color="#7f0055"><strong>new </strong></font><font color="#000000">JFrame</font><font color="#000000">(</font><font color="#2a00ff">
          "Linux on Desktop is here!!!"</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">        </font><font color="#000000">frame.add</font><font color="#000000">(</font><font color="#7f0055"><strong>new </strong></font><font color="#000000">YearOfLinuxDesktopPanel</font><font color="#000000">())</font><font color="#000000">;</font>
<font color="#ffffff">        </font><font color="#000000">frame.setSize</font><font color="#000000">(</font><font color="#990000">400</font><font color="#000000">, </font><font color="#990000">300</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">        </font><font color="#000000">frame.setLocationRelativeTo</font><font color="#000000">(</font><font color="#7f0055"><strong>null</strong></font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">        </font><font color="#000000">frame.setDefaultCloseOperation</font><font color="#000000">(
             </font><font color="#000000">JFrame.EXIT_ON_CLOSE</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">        </font><font color="#000000">frame.setVisible</font><font color="#000000">(</font><font color="#7f0055"><strong>true</strong></font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#ffffff">      </font><font color="#000000">}</font>
<font color="#ffffff">    </font><font color="#000000">})</font><font color="#000000">;</font>
<font color="#ffffff">  </font><font color="#000000">}</font>
<font color="#000000">}</font>