通过JLayer和LayerUI缩放JLayeredPane
在Stack Overflow问题上已经提出,在Swing应用程序中实现缩放的最佳方法是通过Java 7提供的JLayer
装饰器。
我一直在关注Oracle教程并认为最好的方法是创建我自己的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 jLayer = new JLayer(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 { 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); } } }
在这个例子中,我希望放大/缩小按钮在单击时以及在缩放以正确响应鼠标事件时增大。 这不必单击它们曾经驻留的位置以触发事件。
可悲的是,我甚至无法让他们在点击之前通过改变评论线进行缩放,所以我真的很感激一些帮助!
你当前的问题是你正在混合重量/ 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 jLayer = new JLayer (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 { 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); } } }
你接下来的问题将是如何翻译鼠标事件;)
- SimpleOpenNI记录和重播用户跟踪数据
- MacOSX Snow Leopard和Eclipse:启动Eclipse时出错(没有Java虚拟机……)
- 对于具有字段double d = 2.2250738585072012e-308的类,编译挂起
- 编译器错误 – ‘错误:无法找到或加载主类com.sun.tools.javac.Main’
- 解密后几个字符丢失
- Java EE 6 @Inject懒惰?
- 在java代码库中自动为所有if / else / for / while等添加花括号
- 尝试在google app engine for java中实现异步http时遇到奇怪的exception
- 在Java 8中对比较器的误解