【问题标题】:Zooming JLayeredPane via JLayer and the LayerUI通过 JLayer 和 LayerUI 缩放 JLayeredPane
【发布时间】:2014-02-21 17:50:47
【问题描述】:

建议 on this Stack Overflow question 在 Swing 应用程序中实现缩放的最佳方式是通过 Java 7 提供的 JLayer 装饰器。

我一直关注Oracle tutorial,并认为最好的方法是创建我自己的ZoomUI,扩展LayerUI。到目前为止,我的想法是这个类将有一个 zoom 成员变量,该变量在绘制实际组件之前应用。

稍后我可以使用同一个类来捕获鼠标事件并将它们分派到它们未缩放的坐标。

第一步我遇到了一点麻烦,不明白为什么g2.scale(zoom, zoom) 调用在我下面的 SSCCE 中没有效果。

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);
        }
    }
}

在此示例中,我希望放大/缩小按钮在单击和缩放以正确响应鼠标事件时增大。无需单击他们曾经居住的位置即可触发事件。

遗憾的是,我什至无法通过更改注释行来让它们在点击之前进行缩放,所以我非常感谢一些帮助!

【问题讨论】:

    标签: java swing zooming jlayer


    【解决方案1】:

    您的直接问题是您将重量级/AWT 组件与重量轻/Swing 组件混合...

    Button 是一个原生组件,这意味着它的绘制不在 Swing 的控制范围内,因此不受它的影响。

    改为使用JButton

    public class TestJLayerZoom {
    
        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 JPanel panel = new JPanel();
                    final ZoomUI layerUI = new ZoomUI();
                    final JLayer<JComponent> jLayer = new JLayer<JComponent>(panel, layerUI);
    
                    JButton zoomIn = new JButton("Zoom In");
                    zoomIn.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            layerUI.zoom += 0.1;
                            jLayer.repaint();
                        }
                    });
                    panel.add(zoomIn);
    
                    JButton zoomOut = new JButton("Zoom Out");
                    zoomOut.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            layerUI.zoom -= 0.1;
                            jLayer.repaint();
                        }
                    });
                    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 double zoom = 2; // 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);
            }
        }
    }
    

    你的下一个问题将是如何翻译鼠标事件;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 2018-05-18
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多