いくつかの2Dオブジェクトが動き回っているパネルがあります。必要に応じてpaintComponent()をオーバーライドしました。次に、その領域をズームインおよびズームアウトできるようにします。ズームインすると、スクロールバーが表示され、スクロールしてフィールド全体を表示できます。ズームインおよびズームアウトしている間、2Dオブジェクトのサイズはそれに応じて増減する必要があります。どのSwingコンポーネント、またはコンポーネントの組み合わせがこれを達成するのに役立ちますか?
最も簡単な方法は、パネルを変更して、ズームレベルを示すダブルを導入することです。このdoubleは、スケールを示します。1は通常で、それより高い値が拡大されます。このdoubleは、paintComponent
でGraphics2D
と一緒に使用できます。
といった:
Graphics2D g2 = (Graphics2D) g;
int w = // real width of canvas
int h = // real height of canvas
// Translate used to make sure scale is centered
g2.translate(w/2, h/2);
g2.scale(scale, scale);
g2.translate(-w/2, -h/2);
スクロールするには、パネルをJScrollPaneに配置し、ズームスケールも使用するgetPreferredSizeと組み合わせます。 JScrollPaneは、配置したコンポーネントの推奨サイズを使用します。優先サイズがそれ自体のサイズを超えると、スクロールバーが表示されます。
パネルの希望するサイズを変更して、返される幅と高さがスケーリングされるようにすると、問題はありません。基本的に、次のようなものを返すことができます。
return new Dimension(w * scale, h * scale)
この質問は古いことは知っていますが、将来誰かに役立つ可能性がある場合に備えて、解決策を投稿できると思いました。
そこで、ユーザーがマウスを回したことを検出するために、MouseWheelListenerを実装するJPanelを拡張するクラスを作成しました。私のクラスは、ユーザーがクリックしてドラッグしたときにコンテンツを移動するために、ドラッグもリッスンします。
まず、コンストラクターでこれをMouseWheelListenerとして設定する必要があります
_ addMouseWheelListener(this);
_
ズームインとズームアウトには、ブール値zoomer
(ユーザーがマウスでロールするタイミングを示す)と2つのdouble zoomFactor
(オブジェクトのサイズに乗算される現在の係数を維持するため)を使用しました。 )およびprevZoomFactor
(前のズーム率の場合)。
_private double zoomFactor = 1;
private double prevZoomFactor = 1;
private boolean zoomer;
_
また、JPanelのPaint()
メソッドをオーバーライドします。このメソッドでは、(何かを描画する前に)ユーザーがズームしたときに(zoomer
= true)グラフィックをzoomFactor
でスケーリングします。コード:
_@Override
public void Paint(Graphics g) {
super.Paint(g);
Graphics2D g2 = (Graphics2D) g;
if (zoomer) {
AffineTransform at = new AffineTransform();
at.scale(zoomFactor, zoomFactor);
prevZoomFactor = zoomFactor;
g2.transform(at);
zoomer = false;
}
// All drawings go here
}
_
最後に、MouseWheelListenerのmouseWheelMoved
メソッドをオーバーライドします。このメソッドでは、zoomFactor
を増やす(ユーザーがロールアップする場合)か、zoomFactor
を減らす(ユーザーがロールダウンする場合)。 。コード:
_@Override
public void mouseWheelMoved(MouseWheelEvent e) {
zoomer = true;
//Zoom in
if (e.getWheelRotation() < 0) {
zoomFactor *= 1.1;
repaint();
}
//Zoom out
if (e.getWheelRotation() > 0) {
zoomFactor /= 1.1;
repaint();
}
}
_
ドラッグ機能も使用し、マウスの位置に応じてズームする場合は、以下のクラスを使用できます。このクラスは、コンストラクターのパラメーターとしてBufferedImageを取得して、画面に何かを表示します。
また、GitHubに Zoomable-Java-Panel というプロジェクトをアップロードしました。ここには、私が示した機能の例があります。上記では、プロジェクトに実装する方法をテストして確認できます。
_package zoomable.panel;
import Java.awt.Graphics;
import Java.awt.Graphics2D;
import Java.awt.MouseInfo;
import Java.awt.Point;
import Java.awt.event.MouseEvent;
import Java.awt.event.MouseListener;
import Java.awt.event.MouseMotionListener;
import Java.awt.event.MouseWheelEvent;
import Java.awt.event.MouseWheelListener;
import Java.awt.geom.AffineTransform;
import Java.awt.image.BufferedImage;
import javax.swing.JPanel;
/**
*
* @author Thanasis1101
* @version 1.0
*/
public class MainPanel extends JPanel implements MouseWheelListener, MouseListener, MouseMotionListener {
private final BufferedImage image;
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 Point startPoint;
public MainPanel(BufferedImage image) {
this.image = image;
initComponent();
}
private void initComponent() {
addMouseWheelListener(this);
addMouseMotionListener(this);
addMouseListener(this);
}
@Override
public void Paint(Graphics g) {
super.Paint(g);
Graphics2D g2 = (Graphics2D) g;
if (zoomer) {
AffineTransform at = new AffineTransform();
double xRel = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX();
double yRel = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY();
double zoomDiv = zoomFactor / prevZoomFactor;
xOffset = (zoomDiv) * (xOffset) + (1 - zoomDiv) * xRel;
yOffset = (zoomDiv) * (yOffset) + (1 - zoomDiv) * yRel;
at.translate(xOffset, yOffset);
at.scale(zoomFactor, zoomFactor);
prevZoomFactor = zoomFactor;
g2.transform(at);
zoomer = false;
}
if (dragger) {
AffineTransform at = new AffineTransform();
at.translate(xOffset + xDiff, yOffset + yDiff);
at.scale(zoomFactor, zoomFactor);
g2.transform(at);
if (released) {
xOffset += xDiff;
yOffset += yDiff;
dragger = false;
}
}
// All drawings go here
g2.drawImage(image, 0, 0, this);
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
zoomer = true;
//Zoom in
if (e.getWheelRotation() < 0) {
zoomFactor *= 1.1;
repaint();
}
//Zoom out
if (e.getWheelRotation() > 0) {
zoomFactor /= 1.1;
repaint();
}
}
@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 mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
released = false;
startPoint = MouseInfo.getPointerInfo().getLocation();
}
@Override
public void mouseReleased(MouseEvent e) {
released = true;
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
_