|
|
||
Alexander Potochkin's BlogJune 2008 ArchivesJXLayer 3.0 - MouseScrollableUIPosted by alexfromsun on June 24, 2008 at 10:39 AM | Permalink | Comments (3)The mouse auto-scrolling is very popular these days for modern applications. I usually use this feature in the Firefox browser - you click the mouse wheel somewhere on the page and can immediately start scrolling. A few months ago Kirill wrote an great review of the "auto-scrolling feature" implementation in Swing. I'd like to add one more item to the list. Suppose you create a JTable, wrap it with JScrollPane and add it to a frame:
To enable auto-scrolling you just need to wrap a JScrollPane with JXLayer and set the MouseScrollableUI to it:
After that you can you can activate auto-scrolling by clicking the mouse wheel:JScrollPane sp = JScrollPane(createMyTable()); JXLayer<JScrollPane> l = new JXLayer<JScrollPane>(sp, new MouseScrollableUI()); add(l);
ImplementationThings like MouseScrollableUI are very easily implemented with JXLayer, because it provides a way to catch all mouseEvents for all components inside a JXLayer.Once you have a way to catch all mouseEvents for all subcomponents, everything else is straightforward. The only specific details is the scrolling indicator, initially I thought to paint it, as usual, in the paintLayer() method. However I realized that I want to change the mouse cursor when I move the mouse over scrolling indicator and the best solution is to implement it as a custom component, set a resize mouse cursor and place it at the layer's glassPane. The source code of the MouseScrollableUI is quite compact, the MouseScrollableDemo for the webstart demo is even shorter.class MyLayerUI extends AbstractLayerUI<JComponent> { // This method catches all focus, mouse and keyboard events // for the layer and all its subcomponents @Override public void eventDispatched(AWTEvent e, JXLayer<JComponent> l) { super.eventDispatched(e, l); System.out.println("AWTEvent is dispatched: " + e); } // Utility methods which are called from eventDispatched() // to provide a hook for catching particular type of events @Override protected void processMouseEvent(MouseEvent e, JXLayer<JComponent> l) { System.out.println("MouseEvent on component: " + e.getComponent()); } @Override protected void processMouseMotionEvent(MouseEvent e, JXLayer<JComponent> l) { System.out.println("MouseMotionEvent on component: " + e.getComponent()); } } (the runnable link is above the screenshot) See you on the JXLayer forum Thanks alexp JXLayer 3.0 - Getting startedPosted by alexfromsun on June 05, 2008 at 09:49 AM | Permalink | Comments (13)It is my pleasure to announce a major update of JXLayer component. The new version is hosted on its own java.net project jxlayer.dev.java.net, where I will also provide links to all my blogs about this component. So, why I encourage everybody to try out the new JXLayer? Actually to answer this question I am going to write several more blogs, here is a short answer:
// wrap your component JXLayer<JComponent> layer = new JXLayer<JComponent>(myComponent); // create custom LayerUI AbstractLayerUI<JComponent> layerUI = new AbstractLayerUI<JComponent>() { @Override protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { // this paints layer as is super.paintLayer(g2, l); // custom painting: // here we paint translucent foreground // over the whole layer g2.setColor(new Color(0, 128, 0, 128)); g2.fillRect(0, 0, l.getWidth(), l.getHeight()); } }; // set our LayerUI layer.setUI(layerUI); // add the layer as a usual component frame.add(layer);BufferedLayerUI provides more functionality, since it paints the layer to the double buffer image, it allows filtering the image with the BufferedImageOp subclasses. With it you can invert colors of a layer, blur it apply any other fancy effects. For the Rainbow project I used BufferedLayerUI to implement the image editor dialog. (Here are some more Rainbow screenshots) Let's see how to apply the grayScale effect to a layer: // wrap you component JXLayer<JComponent> layer = new JXLayer<JComponent>(myComponent); // here we use BufferedLayerUI which can work with BufferedImageOps BufferedLayerUI<JComponent> bufferedLayerUI = new BufferedLayerUI<JComponent>(); // create a ColorConvertOp to apply grayScale effect BufferedImageOp grayScaleOp = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); // create a BufferedImageOpEffect with the provided BufferedImageOp BufferedImageOpEffect imageOpEffect = new BufferedImageOpEffect(grayScaleOp); // set BufferedImageOpEffect to the bufferedLayerUI bufferedLayerUI.setLayerEffects(imageOpEffect); // set the bufferedLayerUI to the layer layer.setUI(bufferedLayerUI); // add the layer as a usual component frame.add(layer);And now is the very important news: with JXLayer 3.0 you can catch layer's input events as easy as implement a custom painting. AbstractLayerUI introduces several methods: processFocusEvent, processMouseEvent, processMouseMotionEvent, etc... The names of the methods speak for themselves. If you'd like to catch all mouseEvents for all components inside your layer - just override processMouseEvent in your custom AbstractLayerUI subclass. MouseDrawingDemo combines painting and mouse events processing together.
In this demo you can paint over the layer with your mouse, just like you do in any other image editor. Note that components are alive when you paint over them. See you one the JXLayer forum With best wishes alexp | ||
|
|