Java 使用鼠标和图形缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19643637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
zoom using mouse and graphics
提问by Choubidou
I draw in my JComponent some curves, etc .. with Graphics G ( not 2D ).
我在我的 JComponent 中绘制了一些曲线等......使用 Graphics G(不是 2D)。
Now I want to use the scroll wheel of my mouse to zoom in and out.
现在我想使用鼠标的滚轮来放大和缩小。
Any tracks ?
任何曲目?
I heard talk about a BuferredImage ?
我听说过一个 BuferredImage ?
回答by trashgod
Try JFreeChart
; the setMouseWheelEnabled()
method, used to control zooming in ChartPanel
, is illustrated in examples cited here.
尝试JFreeChart
; setMouseWheelEnabled()
用于控制放大的方法ChartPanel
在此处引用的示例中进行了说明。
回答by MadProgrammer
There are a few considerations you need to take into account...
您需要考虑一些注意事项......
The end result will depend on what you want to achieve. If you are drawing curves using the Graphics2D API, it might be simpler to simply scale the coordinates each time the component is rendered. You will need to make sure that any changes in the scale are reflected in the preferred size of the component itself.
最终结果将取决于您想要实现的目标。如果您使用 Graphics2D API 绘制曲线,每次渲染组件时简单地缩放坐标可能会更简单。您需要确保比例的任何更改都反映在组件本身的首选大小中。
You could also render the "default" output to a BufferedImage
and simply use an AffineTransform
to change the scaling the is used to render the result, for example.
例如,您还可以将“默认”输出渲染为 aBufferedImage
并简单地使用 anAffineTransform
更改用于渲染结果的缩放比例。
This simple uses a BufferedImage
and loads a picture from disk, but the basic concept is the same.
这个简单的使用 aBufferedImage
并从磁盘加载图片,但基本概念是相同的。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomPane {
public static void main(String[] args) {
new ZoomPane();
}
public ZoomPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
private float scale = 1;
public TestPane() {
try {
img = ImageIO.read(new File("/path/to/image"));
} catch (IOException ex) {
ex.printStackTrace();
}
addMouseWheelListener(new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double delta = 0.05f * e.getPreciseWheelRotation();
scale += delta;
revalidate();
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
Dimension size = new Dimension(200, 200);
if (img != null) {
size.width = Math.round(img.getWidth() * scale);
size.height = Math.round(img.getHeight() * scale);
}
return size;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
g2d.drawImage(img, at, this);
g2d.dispose();
}
}
}
}
You could also scale the Graphics
context passed to your paintComponent
method directly.
您还可以直接缩放Graphics
传递给您的paintComponent
方法的上下文。
The important thing here is to remember to reset the AffineTransform
after you have completed, otherwise it will be passed to other components when they are rendered, which won't generate the expected output...
这里重要的是记住AffineTransform
在你完成后重置它,否则它会在渲染时传递给其他组件,而不会产生预期的输出......
This example basically creates a copy of the Graphics
context which we can manipulate and dispose of without effecting the original, making it simpler to mess with
这个例子基本上创建了一个Graphics
上下文的副本,我们可以在不影响原始的情况下操作和处理它,使其更容易混淆
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomPane {
public static void main(String[] args) {
new ZoomPane();
}
public ZoomPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private float scale = 1;
public TestPane() {
addMouseWheelListener(new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double delta = 0.05f * e.getPreciseWheelRotation();
scale += delta;
revalidate();
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
Dimension size = new Dimension(200, 200);
size.width = Math.round(size.width * scale);
size.height = Math.round(size.height * scale);
return size;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
g2d.setTransform(at);
g2d.setColor(Color.RED);
// This is for demonstration purposes only
// I prefer to use getWidth and getHeight
int width = 200;
int height = 200;
Path2D.Float path = new Path2D.Float();
int seg = width / 3;
path.moveTo(0, height / 2);
path.curveTo(0, 0, seg, 0, seg, height / 2);
path.curveTo(
seg, height,
seg * 2, height,
seg * 2, height / 2);
path.curveTo(
seg * 2, 0,
seg * 3, 0,
seg * 3, height / 2);
g2d.draw(path);
g2d.dispose();
}
}
}
Take a look at Transforming Shapes, Text and Imagesfor more details
查看变换形状、文本和图像以了解更多详细信息
回答by Younes Meridji
I put this simple code to show you how to use mouse wheel mouving by adding a MouseWheelListener to a JPanel:
我把这个简单的代码告诉你如何通过向 JPanel 添加一个 MouseWheelListener 来使用鼠标滚轮移动:
myJpanel.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent mwe) {
jPanelMouseWheelMoved(mwe);
}
});
To implement the mouse wheel listener:
要实现鼠标滚轮侦听器:
private void jPaneMouseWheelMoved(MouseWheelEvent mwe) {
if(Event.ALT_MASK != 0) {
if(mwe.getWheelRotation() > 0) {
//here you put your code to scrool douwn or to minimize.
System.out.println(" minimize by "+(-1*mwe.getWheelRotation()));
}
else if(mwe.getWheelRotation() < 0) {
//here you put your code to scrool up or to maximize.
System.out.println(" maximaze by "+(-1*mwe.getWheelRotation()));
}
}
}
You can adapt this exemple to zoom or to scrool what you want.
您可以调整此示例以缩放或滚动您想要的内容。