我有一个带有代码的JPanel。当我用鼠标滚轮滚动时,我希望面板朝着面板中间的位置放大。当前,每当我用鼠标滚轮放大/缩小时,图像左上角的角都保持在同一位置。我很难找到正确的算法。
为了放大图片,代码使用AffineTransform对象,该对象根据双精度值缩放图像,该值根据鼠标滚轮的移动而增大或减小。
还增加了复杂性的是,还可以在面板周围单击和拖动图像。如果单击并拖动它,则缩放仍必须放大面板中心的内容,而不是实际图像中心的内容。
再次,应该相对于当前可见区域的中心点进行缩放。也就是说,随着缩放发生,视图中心的点应保持固定。
这是代码(并且是可执行文件):
package clientgui;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.border.TitledBorder;
public class MoveImageExample extends JFrame {
ShowCanvas canvas;
public MoveImageExample() throws Exception {
super();
Container container = getContentPane();
canvas = new ShowCanvas(
"http://cdn.smosh.com/sites/default/files/bloguploads/funny-iphone-5-bruce-lee.jpg");
container.setPreferredSize(new Dimension(canvas.getWidth(), canvas
.getHeight()));
System.out.println("width = " + canvas.getWidth() + " height = "
+ canvas.getHeight());
container.add(canvas);
pack();
setVisible(true);
}
public static void main(String arg[]) throws Exception {
new MoveImageExample();
}
}
@SuppressWarnings("serial")
class ShowCanvas extends JPanel {
int imageX = 0, imageY = 0;
int lastMouseX = 0, lastMouseY = 0;
int centerX = 225;
int centerY = 225;
int canvasWidth = 450;
int canvasHeight = 450;
double scaleFactor = 1.0;
boolean firstMouseDrag = true;
BufferedImage image;
public ShowCanvas(String imagePath) throws Exception {
setBackground(Color.white);
MouseMotionHandler mouseHandler = new MouseMotionHandler();
addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
addMouseWheelListener(mouseHandler);
URL url = new URL(imagePath);
Image rawImage = ImageIO.read(url);
image = new BufferedImage(rawImage.getWidth(this),
rawImage.getHeight(this), BufferedImage.TYPE_INT_ARGB);
setSize(image.getWidth(), image.getHeight());
Graphics2D g2 = image.createGraphics();
g2.drawImage(rawImage, imageX, imageY, this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.gray);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
AffineTransform transformer = new AffineTransform();
// translate the image back (using new scale factor)
transformer.scale(scaleFactor, scaleFactor); // scale by 2x on x and y
// axes.
transformer.translate(imageX / scaleFactor, imageY / scaleFactor);
g2D.drawImage(image, transformer, this);
}
class MouseMotionHandler extends MouseMotionAdapter implements
MouseListener, MouseWheelListener {
public void mousePressed(MouseEvent e) {
lastMouseX = e.getX();
lastMouseY = e.getY();
}
public void mouseDragged(MouseEvent e) {
int xDiff = e.getX() - lastMouseX;
int yDiff = e.getY() - lastMouseY;
imageX = imageX + xDiff;
imageY = imageY + yDiff;
lastMouseX = e.getX();
lastMouseY = e.getY();
repaint();
}
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
scaleFactor = scaleFactor + notches / 10.0;
if (scaleFactor < 0.5) {
scaleFactor = 0.5;
} else if (scaleFactor > 3.0) {
scaleFactor = 3.0;
}
repaint();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
}
}
因此,基本思想是,当您更改比例时,而不是允许整个更改被添加/减去宽度/高度,您需要在位置和尺寸之间进行划分…
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
// Get the current/old size...
double oldWidth = image.getWidth() * scaleFactor;
double oldHeight = image.getHeight() * scaleFactor;
scaleFactor = scaleFactor + notches / 10.0;
if (scaleFactor < 0.5) {
scaleFactor = 0.5;
} else if (scaleFactor > 3.0) {
scaleFactor = 3.0;
}
// Get the new size
double newWidth = image.getWidth() * scaleFactor;
double newHeight = image.getHeight() * scaleFactor;
// Calculate the difference (and divide it by 2)
double difWidth = (oldWidth - newWidth) / 2;
double difHeight = (oldHeight - newHeight) / 2;
// Add it to the image position...
imageX += difWidth;
imageY += difHeight;
revalidate();
repaint();
}
更新了工作示例
好的,所以基本的想法是要处理图像所在的虚拟空间。该虚拟空间具有一个大小(组件大小x比例因子)。这使您可以将虚拟空间置于实际空间的中心。
之后,您只需要计算虚拟空间(在真实空间内)的x / y偏移量和图像的虚拟位置。
在此示例中,我删除了AffineTransformation#setLocation
生成图像的缩放实例的支持,这只是使放置图像变得更加容易。
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.net.URL;
public class MoveImageExample extends JFrame {
ShowCanvas canvas;
public MoveImageExample() throws Exception {
super();
Container container = getContentPane();
canvas = new ShowCanvas(
"http://cdn.smosh.com/sites/default/files/bloguploads/funny-iphone-5-bruce-lee.jpg");
container.add(canvas);
pack();
setVisible(true);
}
public static void main(String arg[]) throws Exception {
new MoveImageExample();
}
}
@SuppressWarnings("serial")
final class ShowCanvas extends JPanel {
int imageX = 0, imageY = 0;
int lastMouseX = 0, lastMouseY = 0;
int centerX = 225;
int centerY = 225;
int canvasWidth = 450;
int canvasHeight = 450;
double scaleFactor = 1.0;
boolean firstMouseDrag = true;
BufferedImage image;
private BufferedImage scaled;
public ShowCanvas(String imagePath) throws Exception {
setBackground(Color.white);
MouseMotionHandler mouseHandler = new MouseMotionHandler();
addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
addMouseWheelListener(mouseHandler);
URL url = new URL(imagePath);
Image rawImage = ImageIO.read(url);
image = new BufferedImage(rawImage.getWidth(this),
rawImage.getHeight(this), BufferedImage.TYPE_INT_ARGB);
setSize(image.getWidth(), image.getHeight());
Graphics2D g2 = image.createGraphics();
g2.drawImage(rawImage, imageX, imageY, this);
}
@Override
public Dimension getPreferredSize() {
return new Dimension((int) (image.getWidth()), (int) (image.getHeight()));
}
protected BufferedImage getScaledInstance() {
if (scaled == null) {
int width = (int) (image.getWidth() * scaleFactor);
int height = (int) (image.getHeight() * scaleFactor);
scaled = new BufferedImage(width, height, image.getType());
Graphics2D g2d = scaled.createGraphics();
AffineTransform transformer = new AffineTransform();
transformer.scale(scaleFactor, scaleFactor); // scale by 2x on x and y
g2d.setTransform(transformer);
g2d.drawImage(image, 0, 0, this);
g2d.dispose();
}
return scaled;
}
public Dimension getVirtualSize() {
return new Dimension(
(int)(getWidth() * scaleFactor),
(int)(getHeight() * scaleFactor));
}
public Point getVirtualPoint(int x, int y) {
return new Point(
(int)(x * scaleFactor),
(int)(y * scaleFactor));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension vitualSize = getVirtualSize();
int xOffset = (getWidth() - vitualSize.width) / 2;
int yOffset = (getHeight() - vitualSize.height) / 2;
Graphics2D g2D = (Graphics2D) g.create();
g2D.setColor(Color.gray);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g2D.setColor(Color.GREEN);
g2D.drawRect(xOffset, yOffset, vitualSize.width, vitualSize.height);
g2D.setColor(Color.RED);
g2D.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
g2D.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
Point virtualPoint = getVirtualPoint(imageX, imageY);
System.out.println(virtualPoint);
g2D.drawImage(getScaledInstance(), virtualPoint.x + xOffset, virtualPoint.y + yOffset, this);
g2D.dispose();
}
class MouseMotionHandler extends MouseMotionAdapter implements
MouseListener, MouseWheelListener {
public void mousePressed(MouseEvent e) {
lastMouseX = e.getX();
lastMouseY = e.getY();
}
public void mouseDragged(MouseEvent e) {
int xDiff = e.getX() - lastMouseX;
int yDiff = e.getY() - lastMouseY;
imageX = imageX + xDiff;
imageY = imageY + yDiff;
lastMouseX = e.getX();
lastMouseY = e.getY();
repaint();
}
public void mouseWheelMoved(MouseWheelEvent e) {
scaled = null;
int notches = e.getWheelRotation();
scaleFactor = scaleFactor + notches / 10.0;
if (scaleFactor < 0.5) {
scaleFactor = 0.5;
} else if (scaleFactor > 3.0) {
scaleFactor = 3.0;
}
repaint();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
}
}
我想做一个更大的分辨率/全屏,但我不知道我应该使用什么布局,你们能帮我选择一个更好的布局吗这是第一张图片的第一个代码 这一个,我想把它放在框架的中间,所有的都已经在面板上了,我怎样才能把它移到中间呢?这是第二张图片的代码
问题内容: 我有一个面板,其中正在移动一些2D对象。我已经根据需要重写了paintComponent()。现在,我希望能够放大和缩小该区域。放大时,将出现滚动条,通过滚动条可以滚动查看整个字段。在放大和缩小时,二维对象的大小应相应增加或减小。哪个Swing组件或什至是组件组合将有助于实现这一目标? 问题答案: 最简单的方法是修改面板并引入一个双倍来指示您的缩放级别。这双会指示你的规模,其中1是正常
我有三个JPanel,我用gridlayout将它们添加到contentPane中;gridlayout包含3行。面板之间有令人讨厌的间隙。我怎样才能轻易摆脱这些?我尝试调整JFrame的大小,但空格仍然存在。我还尝试重新调整网格布局选项,如HGap和Vgap,但没有解决问题。我看了之前关于这个的一些问题,但没有一个解决了这个问题。看起来是这样的:
了解如何通过映射实时视图中的元素或 CSS Designer 中应用的选择器及其 HTML 标记,使用 DOM 面板来编辑 HTML 结构。 DOM 面板呈现包含静态和动态内容的交互式 HTML 树。此视图有助于直观地在实时视图中通过 HTML 标记以及 CSS Designer 中所应用的选择器,对元素进行映射。您也可在 DOM 面板中编辑 HTML 结构,并在实时视图中查看即时生效的更改。 要
了解如何使用 CSS Designer 面板创建或附加样式表、媒体查询、选择器以及设置 CSS 属性。 “CSS Designer”面板(“窗口”> “CSS Designer”)属于“CSS 属性检查器”,能让您“可视化”地创建 CSS 样式和规则并设置属性和媒体查询。 在 CSS Designer 界面中可以使用以下内容: 来源:与项目相关的 CSS 文件的集合 @Media:用于控制屏幕大小
默认面板 <section class="ui-panel ui-grid ui-grid-trisect"> <h2 class="ui-arrowlink">猜你喜欢<span class="ui-panel-subtitle">1328条</span></h2> <ul> <li> <div class="ui-img-vert