Author: tchemit Date: 2009-03-18 18:17:16 +0000 (Wed, 18 Mar 2009) New Revision: 1271 Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx jaxx/trunk/jaxx-runtime-swing/changelog.txt jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java Log: introduce BlockingLayerUI2 Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx =================================================================== --- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx 2009-03-18 08:46:51 UTC (rev 1270) +++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx 2009-03-18 18:17:16 UTC (rev 1271) @@ -11,22 +11,38 @@ accept(e, "from icon of layer"); } }}' /> + <jaxx.runtime.swing.BlockingLayerUI2 id='layerUI2' + blockIcon='{SwingUtil.createImageIcon("action-block.png")}' + acceptIcon='{SwingUtil.createImageIcon("action-accept.png")}' + acceptAction='{new AbstractAction() { private static final long serialVersionUID = 1L; + @Override + public void actionPerformed(ActionEvent e) { + accept(e, "from icon of layer"); + } + }}' /> <script><![CDATA[ import jaxx.runtime.SwingUtil; void $afterCompleteSetup() { for (JComponent boxed : SwingUtil.getLayeredComponents(this)) { + if (boxed == d) { + SwingUtil.getLayer(boxed).setUI(layerUI2); + continue; + } + jaxx.runtime.swing.BlockingLayerUI ui = layerUI.clone(); if ( boxed == c) { ui.setBlock(true); } SwingUtil.getLayer(boxed).setUI(ui); - //ui.setDirty(true); } } public void setLayer(boolean active) { for (JComponent boxed : SwingUtil.getLayeredComponents(this)) { + if (boxed == d) { + continue; + } jaxx.runtime.swing.BlockingLayerUI ui = (jaxx.runtime.swing.BlockingLayerUI)SwingUtil.getLayer(boxed).getUI(); if ( boxed == c) { ui.setBlock(active); @@ -59,6 +75,8 @@ onActionPerformed='accept(event, "from button (no layer)")'/> <JButton id='c' text='button C (full block)' decorator='boxed' _clickedText='"button C was clicked"' onActionPerformed='accept(event, "from button (no layer)");'/> + <JButton id='d' text='button D (full block 2)' decorator='boxed' _clickedText='"button D was clicked"' + onActionPerformed='accept(event, "from button (no layer)");'/> </JPanel> </cell> </row> Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt =================================================================== --- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 08:46:51 UTC (rev 1270) +++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 18:17:16 UTC (rev 1271) @@ -1,4 +1,5 @@ 1.3 ?? 200903?? + * 20090318 [chemit] - introduce the BlockingLayerUI2 class (should be merge with BlockingLayerUI) * 20090318 [chemit] - introduce the CardLayout2Ext class * 20090312 [chemit] - add some usefull code from ObServe (load Nimbus L&F, load ui configuration) * 20090309 [chemit] - in BlockingLayerUI, add a new state 'block' to enable/disable blocking mode with a blockingColor Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java 2009-03-18 08:46:51 UTC (rev 1270) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java 2009-03-18 18:17:16 UTC (rev 1271) @@ -4,9 +4,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Graphics2D; -import java.awt.Insets; import java.awt.Point; -import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java (rev 0) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java 2009-03-18 18:17:16 UTC (rev 1271) @@ -0,0 +1,206 @@ +package jaxx.runtime.swing; + +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import org.jdesktop.jxlayer.JXLayer; + +/** + * + * A JXLayer ui implementation that permits to block a component but still + * allow an action when clicking everywhere on the layer. + * + * Moreover, an icon can be added on the right-top icon painted and changed + * when the mouse is over the layer. + * + * You can change the blocking and accepting icon. + * + * To hook an click on the layer's icon, you can : + * + * <ul><li>pass an Action via method {@link #setAcceptAction(Action)}</li> + * <li>override the method {@link #acceptEvent(java.awt.event.MouseEvent, org.jdesktop.jxlayer.JXLayer)}</li> + * </ul> + * + * @author tony + * @since 1.3 + */ +public class BlockingLayerUI2 extends org.jdesktop.jxlayer.plaf.AbstractLayerUI<JComponent> { + + public static final String CAN_CLICK_PROPERTY = "canClick"; + public static final String ACCEPT_ICON_PROPERTY = "acceptIcon"; + public static final String BLOCK_ICON_PROPERTY = "blockIcon"; + private static final long serialVersionUID = 1L; + /** + * Action to be treated when click on icon + */ + protected Action acceptAction; + /** + * Icon when you can not click + */ + protected BufferedImage blockIcon; + /** + * Icon when you can click + */ + protected BufferedImage acceptIcon; + /** + * Internal state to known when we can accept click + */ + protected boolean canClick; + + public void setAcceptAction(Action acceptAction) { + this.acceptAction = acceptAction; + } + + public void setAcceptIcon(ImageIcon acceptIcon) { + this.acceptIcon = prepareIcon(acceptIcon); + firePropertyChange(ACCEPT_ICON_PROPERTY, null, acceptIcon); + setDirty(true); + } + + public void setBlockIcon(ImageIcon blockIcon) { + this.blockIcon = prepareIcon(blockIcon); + firePropertyChange(BLOCK_ICON_PROPERTY, null, blockIcon); + setDirty(true); + } + + public void setCanClick(boolean canClick) { + boolean oldvalue = this.canClick; + this.canClick = canClick; + firePropertyChange(CAN_CLICK_PROPERTY, oldvalue, canClick); + if (oldvalue != canClick) { + setDirty(true); + } + } + + @Override + public void setDirty(boolean isDirty) { + super.setDirty(isDirty); + } + + public void setBlockIcon(BufferedImage blockIcon) { + this.blockIcon = blockIcon; + } + + public BufferedImage getBlockIcon() { + return blockIcon; + } + + protected BufferedImage getAcceptIcon() { + return acceptIcon; + } + + public boolean isCanClick() { + return canClick; + } + + @Override + public BlockingLayerUI2 clone() { + BlockingLayerUI2 clone = new BlockingLayerUI2(); + clone.acceptAction = acceptAction; + clone.acceptIcon = acceptIcon; + clone.blockIcon = blockIcon; + clone.setCanClick(false); + return clone; + } + + @Override + protected void processKeyEvent(KeyEvent e, JXLayer<JComponent> l) { + + e.consume(); + + } + + @Override + protected void processMouseMotionEvent(MouseEvent e, JXLayer<JComponent> l) { + + e.consume(); + + } + + @Override + protected void processMouseEvent(MouseEvent e, JXLayer<JComponent> l) { + switch (e.getID()) { + case MouseEvent.MOUSE_ENTERED: + setCanClick(true); + break; + case MouseEvent.MOUSE_EXITED: + setCanClick(false); + break; + case MouseEvent.MOUSE_CLICKED: + if (canClick) { + acceptEvent(e, l); + } + break; + } + e.consume(); + } + + @Override + protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { + super.paintLayer(g2, l); + + // to be in sync with the view if the layer has a border + /*Insets layerInsets = l.getInsets(); + g2.translate(layerInsets.left, layerInsets.top); + + JComponent view = l.getView(); + // To prevent painting on view's border + Insets insets = view.getInsets(); + g2.clip(new Rectangle(insets.left, insets.top, + view.getWidth() - insets.left - insets.right, + view.getHeight() - insets.top - insets.bottom)); + */ + + if (getCurrentIcon() != null) { + g2.drawImage(getCurrentIcon(), l.getWidth() - getCurrentIcon().getWidth() - 1, 0, null); + } + } + + protected void acceptEvent(MouseEvent e, JXLayer<JComponent> l) { + if (acceptAction != null) { + acceptAction.putValue("layer", l); + Component source = l.getView(); + acceptAction.actionPerformed(new ActionEvent(source, 0, "accept")); + } + } + + protected BufferedImage getCurrentIcon() { + return canClick ? acceptIcon : blockIcon; + } + + protected BufferedImage prepareIcon(ImageIcon image) { + BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = (Graphics2D) icon.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + g2.drawImage(image.getImage(), 0, 0, null); + g2.dispose(); + return icon; + } + + protected void updateCanClickState(JXLayer<JComponent> l, MouseEvent e) { + // udpate toolTipText + Point layerLocation = l.getView().getLocation(); + Point mousePoint = e.getPoint(); + BufferedImage currentIcon = getCurrentIcon(); + if (currentIcon == null) { + setCanClick(false); + return; + } + int minX = (int) layerLocation.getX() + l.getWidth() - currentIcon.getWidth(); + int maxX = (int) layerLocation.getX() + l.getWidth(); + int minY = 0; + int maxY = currentIcon.getHeight(); + boolean accept = minX <= mousePoint.getX() && mousePoint.getX() <= maxX; + accept &= minY <= mousePoint.getLocation().getY() && mousePoint.getLocation().getY() <= maxY; + setCanClick(accept); + } +}