Код: Выделить всё
public class ZoomableJPanel extends JPanel implements MouseWheelListener, MouseListener, MouseMotionListener, KeyListener, PropertyChangeListener {
private Panel innerPanel;
private double zoomFactor = 1;
private double prevZoomFactor = 1;
private boolean zoomer;
private boolean dragger;
private boolean released;
private double xOffset = 0;
private double yOffset = 0;
private int xDiff;
private int yDiff;
private int xZoom;
private int yZoom;
private Point startPoint;
private final CustomCallback callBack;
public ZoomableJPanel(Panel innerPanel, CustomCallback callback) {
this.innerPanel = innerPanel;
this.callBack = callback;
initComponent();
setLayout(null);
add(innerPanel);
setBackground(Color.GREEN);
setFocusable(true);
requestFocusInWindow();
addKeyListener(this);
setComponentZOrder(innerPanel, getComponentCount() - 1);
innerPanel.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
revalidate();
repaint();
revalidate();
}
});
}
private void initComponent() {
addMouseWheelListener(this);
addMouseMotionListener(this);
addMouseListener(this);
setFocusable(true);
addKeyListener(this);
}
public void setInnerPanel(Panel innerPanel) {
this.innerPanel = innerPanel;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
AffineTransform at = new AffineTransform();
if (zoomer) {
double xRel = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX();
double yRel = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY();
double zoomDiv = zoomFactor / prevZoomFactor;
xOffset = zoomDiv * (xOffset - xRel) + xRel;
yOffset = zoomDiv * (yOffset - yRel) + yRel;
// at.translate(xOffset, yOffset);
// at.scale(zoomFactor, zoomFactor);
prevZoomFactor = zoomFactor;
} else if (dragger) {
at.translate(xOffset + xDiff, yOffset + yDiff);
at.scale(zoomFactor, zoomFactor);
if (released) {
xOffset += xDiff;
yOffset += yDiff;
dragger = false;
}
} else {
at.translate(xOffset, yOffset);
at.scale(zoomFactor, zoomFactor);
}
if (zoomer) {
callBack.execute();
zoomer = false;
}
// g2.setTransform(at);
// innerPanel.paint(g2);
updateInnerPanelLocation();
}
@Override
public void update(Graphics g) {
revalidate();
repaint();
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
zoomer = true;
if (e.getWheelRotation() < 0) {
// Zoom in
zoomFactor *= 1.1;
} else if (e.getWheelRotation() > 0) {
// Zoom out
zoomFactor /= 1.1;
}
// Limit zoomFactor to maximum 5x and minimum 1x
if (zoomFactor > 5.0) {
zoomFactor = 5.0;
} else if (zoomFactor < 1.0) {
zoomFactor = 1.0;
}
xZoom = (int) (MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX());
yZoom = (int) (MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY());
// Ensure the parent container is updated
repaint();
this.callBack.execute();
}
@Override
public void mouseDragged(MouseEvent e) {
Point curPoint = e.getLocationOnScreen();
xDiff = curPoint.x - startPoint.x;
yDiff = curPoint.y - startPoint.y;
dragger = true;
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
released = false;
startPoint = MouseInfo.getPointerInfo().getLocation();
}
@Override
public void mouseReleased(MouseEvent e) {
released = true;
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
reset();
}
}
@Override
public void addNotify() {
super.addNotify();
requestFocusInWindow();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
private void updateInnerPanelLocation() {
// Calculate the size of the innerPanel based on the zoom factor
int innerPanelWidth = (int) (getWidth() * zoomFactor);
int innerPanelHeight = (int) (getHeight() * zoomFactor);
int xNewPoint = (int) (xZoom * zoomFactor);
int yNewPoint = (int) (yZoom * zoomFactor);
// Calculate the offset of the inner panel based on the zoom factor and mouse position
int newX = (int) (xNewPoint - xZoom) * -1;
int newY = (int) (yNewPoint - yZoom) * -1;
int xCurrentMouse = (int) (MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX());
int yCurrentMouse = (int) (MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY());
System.out.println("CurrentMouse" + xCurrentMouse + " : " + yCurrentMouse);
System.out.println("NewMouse" + xNewPoint + " : " + yNewPoint);
System.out.println("NewPos: " + newX + " : " + newY);
// Set the new size and location of the inner panel
innerPanel.setSize(innerPanelWidth, innerPanelHeight);
innerPanel.setLocation((int) newX, (int) newY);
}
private void reset() {
zoomFactor = 1;
prevZoomFactor = 1;
xOffset = 0;
yOffset = 0;
repaint();
}
private Container getTopLevelParent() {
Container parent = getParent();
while (parent != null && !(parent instanceof JFrame)) {
parent = parent.getParent();
}
return parent;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
Color background = (Color) evt.getNewValue();
setBackground(background);
repaint();
}
}
Код: Выделить всё
public void panViewOneDevice() {
JRootPane rootPane = getRootPane();
rootPane.setBackground(Color.yellow);
rootPane.updateUI();
rootPane.revalidate();
rootPane.invalidate();
rootPane.repaint();
}
...
ZoomableJPanel mainPanel = new ZoomableJPanel(panViewOneDevice, this::panViewOneDevice);
add(mainPanel);
Сообщите мне, если вам нужны дальнейшие настройки или дополнительная помощь! Спасибо
Подробнее здесь: https://stackoverflow.com/questions/786 ... zoom-panel
Мобильная версия