gpt4 book ai didi

java - 当 JCheckBox 未选中时,使光标周围的 ZoomBox 消失

转载 作者:行者123 更新时间:2023-11-30 02:28:53 24 4
gpt4 key购买 nike

我使用了Zoom box for area around mouse location on screen的第一个答案在鼠标位置周围创建一个缩放框窗口,该窗口将随着鼠标移动而放大图像。

现在,我想知道如何在选中 JCheckBox 时激活此 Zoom Box View,并在未选中时停用它。

我修改了@MadProgrammer编写的类ZoomBoxWindowZoomPane,添加了用于激活和停用ZoomBoxView的代码行,但是这个似乎不起作用。你能告诉我我做错了什么吗?

这是代码:

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.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JCheckBox;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;

public class ZoomPane extends JPanel {

protected static final int ZOOM_AREA = 40;

private JComponent parent;
private JWindow popup;
private Boolean zoomBoxActivated = false;

private BufferedImage buffer;

private float zoomLevel = 2f;

public ZoomPane(JComponent parent, Boolean zba) {
this.parent = parent;
this.zoomBoxActivated=zba;
popup = new JWindow();
popup.setLayout(new BorderLayout());
popup.add(this);
popup.pack();
popup.setAlwaysOnTop(true);
MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
Point pos = e.getLocationOnScreen();
updateBuffer(p);
popup.setLocation(pos.x - 20, pos.y + 20);
repaint();
}

@Override
public void mouseEntered(MouseEvent e) {

if(zoomBoxActivated){
popup.setVisible(true);
}
else {
popup.setVisible(false);
}
}

@Override
public void mouseExited(MouseEvent e) {
popup.setVisible(false);
}

};

parent.addMouseListener(ma);
parent.addMouseMotionListener(ma);
}

protected void updateBuffer(Point p) {
int width = Math.round(ZOOM_AREA);
int height = Math.round(ZOOM_AREA);
buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = buffer.createGraphics();
AffineTransform at = new AffineTransform();

int xPos = (ZOOM_AREA / 2) - p.x;
int yPos = (ZOOM_AREA / 2) - p.y;

if (xPos > 0) {
xPos = 0;
}
if (yPos > 0) {
yPos = 0;
}

if ((xPos * -1) + ZOOM_AREA > parent.getWidth()) {
xPos = (parent.getWidth() - ZOOM_AREA) * -1;
}
if ((yPos * -1) + ZOOM_AREA > parent.getHeight()) {
yPos = (parent.getHeight()- ZOOM_AREA) * -1;
}

at.translate(xPos, yPos);
g2d.setTransform(at);
parent.paint(g2d);
g2d.dispose();
}

@Override
public Dimension getPreferredSize() {
return new Dimension(Math.round(ZOOM_AREA * zoomLevel), Math.round(ZOOM_AREA * zoomLevel));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (buffer != null) {
AffineTransform at = g2d.getTransform();
g2d.setTransform(AffineTransform.getScaleInstance(zoomLevel, zoomLevel));
g2d.drawImage(buffer, 0, 0, this);
g2d.setTransform(at);
}
g2d.setColor(Color.RED);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.dispose();
}

}

public class TestPane extends JPanel {

private BufferedImage img;

public TestPane() {
try {
img = ImageIO.read(new File("satellite-image-of-spain.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}

public class ZoomBoxWindow {

ZoomPane zoomPane;

public static void main(String[] args) {
new ZoomBoxWindow();
}

public ZoomBoxWindow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

TestPane pane = new TestPane();
zoomPane = new ZoomPane(pane, false);

JPanel buttonPanel = new JPanel(new BorderLayout());

JCheckBox zoomBoxChkBox = new JCheckBox("Zoom Box");
zoomBoxChkBox.setMnemonic(KeyEvent.VK_Z);
zoomBoxChkBox.setSelected(false);
zoomBoxChkBox.addItemListener(new ItemListener() {

@Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
if ( e.getStateChange() == ItemEvent.SELECTED) {
zoomPane = new ZoomPane(pane,true);
}
else {

zoomPane = new ZoomPane(pane,false);
}
}

});
buttonPanel.add(zoomBoxChkBox);

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane,BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.PAGE_START);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

感谢您的回答。

最佳答案

所以,

zoomBoxChkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
if (e.getStateChange() == ItemEvent.SELECTED) {
zoomPane = new ZoomPane(pane, true);
} else {

zoomPane = new ZoomPane(pane, false);
}
}
});

实际上并没有做任何事情,您只是创建了 ZoomPane 的新实例。除了向 parent 组件添加一堆 MouseListener 之外,这可能会导致无穷无尽的问题。

相反,我会向 ZoomPane 添加一个新方法

public class ZoomPane extends JPanel {

private boolean isAutoDisplayEnabled = false;
//...


public void setShowZoomPopup(boolean show) {
popup.setVisible(show);
isAutoDisplayEnabled = show;
}

现在,您可以在外部控制弹出窗口的可见性状态。

现在,isAutoDisplayEnabled 标志仅用于确定当触发 mouseEntered 事件时是否应显示弹出窗口,例如...

MouseAdapter ma = new MouseAdapter() {
//...
@Override
public void mouseEntered(MouseEvent e) {
if (isAutoDisplayEnabled) {
popup.setVisible(true);
}
}

现在您的 ItemListener 可以控制弹出窗口的状态

zoomBoxChkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
if (e.getStateChange() == ItemEvent.SELECTED) {
zoomPane.setShowZoomPopup(true);
} else {
zoomPane.setShowZoomPopup(false);
}
}
});

您还可以添加一个检查来查看鼠标当前是否在图像 Pane 的范围内,这样您就不会不必要地显示它,但我将把它留给您尝试找出;)

the popup is flickering as it is being moved

这是因为每次弹出窗口显示时,都会触发 mouseExit 事件,该事件会触发弹出窗口隐藏,然后触发 mouseEnter 事件,如此等等...

这与同一想法略有不同,但是,这不是一个单独的窗口,而是将缩放绘制为图像 Pane 本身的一部分。

这确实意味着,如果缩放超出面板的边界,它将被截断,但我花了一些时间,以便您可以将面板大小调整为大于图像,并且缩放效果仍然有效

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ZoomBoxWindow {

public static void main(String[] args) {
new ZoomBoxWindow();
}

public ZoomBoxWindow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

TestPane pane = new TestPane();

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private BufferedImage img;
private Point zoomPoint;
private boolean zoomEnabled = true;
private int zoomArea = 80;
private float zoom = 2.0f;

public TestPane() {
try {
img = ImageIO.read(new File("/Volumes/Big Fat Extension/Dropbox/MegaTokyo/_cg_1009___Afraid___by_Serena_Clearwater.png"));
} catch (IOException ex) {
ex.printStackTrace();
}

addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
zoomPoint = e.getPoint();
repaint();
}
});

addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
repaint();
}

@Override
public void mouseExited(MouseEvent e) {
zoomPoint = null;
repaint();
}

});
}

public float getZoom() {
return zoom;
}

public void setZoom(float zoom) {
this.zoom = zoom;
repaint();
}

public int getZoomArea() {
return zoomArea;
}

public void setZoomArea(int zoomArea) {
this.zoomArea = zoomArea;
repaint();
}

public boolean isZoomEnabled() {
return zoomEnabled;
}

public void setZoomEnabled(boolean zoomEnabled) {
this.zoomEnabled = zoomEnabled;
repaint();
}

@Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}

protected Point getOffset() {
if (img == null) {
return new Point(0, 0);
}
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
return new Point(x, y);
}

protected Rectangle getImageBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (img != null) {
bounds.setLocation(getOffset());
bounds.setSize(img.getWidth(), img.getHeight());
}
return bounds;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
Point offset = getOffset();
g2d.drawImage(img, offset.x, offset.y, this);
if (zoomPoint != null) {
BufferedImage zoomBuffer = updateBuffer(zoomPoint);
if (zoomBuffer != null) {
Rectangle bounds = getZoomBounds();
g2d.drawImage(zoomBuffer, bounds.x, bounds.y, this);
g2d.setColor(Color.RED);
g2d.draw(bounds);
}
}
g2d.dispose();
}
}

protected Rectangle getZoomBounds() {
Rectangle bounds = null;
if (zoomPoint != null && img != null) {
int zoomArea = getZoomArea();
int xPos = zoomPoint.x - (zoomArea / 2);
int yPos = zoomPoint.y - (zoomArea / 2);

Rectangle zoomBounds = new Rectangle(xPos, yPos, zoomArea, zoomArea);
Rectangle imageBounds = getImageBounds();

bounds = imageBounds.intersection(zoomBounds);
System.out.println(bounds);
}
return bounds;
}

protected BufferedImage updateBuffer(Point p) {
if (zoomPoint == null) {
return null;
}
Rectangle bounds = getZoomBounds();
Point offset = getOffset();
bounds.translate(-offset.x, -offset.y);
if (bounds.x < 0 || bounds.y < 0 || bounds.width <= 0 || bounds.height <= 0) {
return null;
}
BufferedImage zoomBuffer = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = zoomBuffer.createGraphics();

BufferedImage sample = img.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
double zoom = getZoom();
Image scaled = sample.getScaledInstance((int) (bounds.width * zoom), (int) (bounds.height * zoom), Image.SCALE_SMOOTH);

g2d.drawImage(scaled, 0, 0, this);
g2d.dispose();
return zoomBuffer;
}

}

}

关于java - 当 JCheckBox 未选中时,使光标周围的 ZoomBox 消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44756360/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com