通过JLayer和LayerUI缩放JLayeredPane [英] Zooming JLayeredPane via JLayer and the LayerUI

查看:101
本文介绍了通过JLayer和LayerUI缩放JLayeredPane的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人建议在这个Stack Overflow问题上,在Swing应用程序中实现缩放的最佳方法是通过Java 7提供的 JLayer 装饰器。

It's been suggested on this Stack Overflow question that the best way to implement zooming in Swing applications is via the JLayer decorators provided with Java 7.

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

I've been following the Oracle tutorial and think the best way to do this is by creating my own ZoomUI that extends the LayerUI. My thoughts so far are that this class will have a zoom member variable that is applied before painting the actual component.

然后我可以使用同一个类来捕捉鼠标事件并将它们发送到未缩放的坐标。

Then later on I can then use this same class to catch mouse events and dispatch them to their un-zoomed coordinates.

我在第一步遇到一点麻烦,无法理解为什么 g2.scale(缩放,缩放)调用对我的SSCCE无效。

I'm having a little trouble with the first step and cannot understand why the g2.scale(zoom, zoom) call is having no effect in my SSCCE below.

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

在这个例子中我是期望放大/缩小按钮在单击时以及在缩放以正确响应鼠标事件时增大。这不必单击它们曾经驻留的位置以触发事件。

In this example I'm expecting the zoom in/out buttons to grow in size when clicked and when zoomed to respond to mouse events correctly. That is not having to click where they used to reside in order to trigger an event.

可悲的是,我甚至无法让他们在点击之前通过更改评论行进行缩放,所以我真的很感激一些帮助!

Sadly I can't even get them to zoom before clicked by changing the commented line so I'd really appreciate some help!

推荐答案

你当前的问题是你正在混合重量很重的AWT组件和轻量级/ Swing组件...

You immediate problem is you are mixing heavy weight/AWT components with light weight/Swing components...

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

Button is a native component, meaning that it's painting is out side the control of Swing and therefore is not affected by it.

相反,请改用 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);
        }
    }
}

你的下一个问题是正在研究如何翻译鼠标事件;)

You're next problem will be working out how to translate the mouse events ;)

这篇关于通过JLayer和LayerUI缩放JLayeredPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆