Hacer zoom en JLayeredPane a través de JLayer y LayerUI

Ha sido sugeridoen esta pregunta de desbordamiento de pila que la mejor manera de implementar el zoom en las aplicaciones Swing es a través deJLayer Decoradores provistos de Java 7.

He estado siguiendo elTutorial de Oracle y creo que la mejor manera de hacerlo es creando mi propiaZoomUI que extiende elLayerUI. Mis pensamientos hasta ahora son que esta clase tendrá unazoom Variable miembro que se aplica antes de pintar el componente real.

Luego, más adelante, puedo usar esta misma clase para detectar eventos del mouse y enviarlos a sus coordenadas sin zoom.

Tengo un pequeño problema con el primer paso y no puedo entender por qué elg2.scale(zoom, zoom) La llamada no tiene efecto en mi SSCCE a continuación.

import javax.swing.*;
import javax.swing.plaf.LayerUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;

public class Demo {


    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

                final JLayeredPane panel = new JLayeredPane();
                final ZoomUI layerUI = new ZoomUI();
                final JLayer<JComponent> jLayer = new JLayer<JComponent>(panel, layerUI);

                Button zoomIn = new Button("Zoom In");
                zoomIn.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                       layerUI.zoom += 0.1;
                       jLayer.repaint();
                    }
                });
                zoomIn.setBounds(0,0,100,50);
                panel.add(zoomIn);

                Button zoomOut = new Button("Zoom Out");
                zoomOut.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        layerUI.zoom -= 0.1;
                        jLayer.repaint();
                    }
                });
                zoomOut.setBounds(100,0,100,50);
                panel.add(zoomOut);

                frame.setPreferredSize(new Dimension(400,200));
                frame.add(jLayer);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    private static class ZoomUI extends LayerUI<JComponent> {
        public int zoom = 1.5; // Changing this value seems to have no effect
        @Override
        public void paint(Graphics g, JComponent c) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.scale(zoom, zoom);
            super.paint(g2, c);
            g2.dispose();
        }

        @Override
        public void installUI(JComponent c) {
            super.installUI(c);
            JLayer jlayer = (JLayer)c;
            jlayer.setLayerEventMask(
                    AWTEvent.MOUSE_EVENT_MASK | AWTEvent.ACTION_EVENT_MASK |
                            AWTEvent.MOUSE_MOTION_EVENT_MASK
            );
        }

        @Override
        public void uninstallUI(JComponent c) {
            JLayer jlayer = (JLayer)c;
            jlayer.setLayerEventMask(0);
            super.uninstallUI(c);
        }
    }
}

En este ejemplo, espero que los botones de acercar / alejar aumenten de tamaño cuando se hace clic y cuando se amplía para responder a los eventos del mouse correctamente. Eso no es tener que hacer clic donde solían residir para desencadenar un evento.

Lamentablemente, ni siquiera puedo hacer que se acerquen antes de hacer clic cambiando la línea comentada, ¡así que realmente agradecería algo de ayuda!

Respuestas a la pregunta(1)

Su respuesta a la pregunta