问题描述
关于问题是我的问题在表单中创建可重新定义的自定义Graphics2d
In connection with question Resizing a component without repainting is my question how to create resiziable custom Graphics2d in form
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ZoomWithSelectionInViewport implements MouseWheelListener {
private JComponent b;
private int hexSize = 3;
private int zoom = 80;
private JScrollPane view;
public ZoomWithSelectionInViewport() throws Exception {
b = new JComponent() {
private static final long serialVersionUID = 1L;
@Override
public Dimension getPreferredSize() {
return new Dimension(700, 700);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = ((Graphics2D) g);
int vertOffsetX, vertOffsetY, horizOffsetX, horizOffsetY;
vertOffsetX = (int) ((double) hexSize * Math.sqrt(3.0f));
vertOffsetY = (int) ((double) -hexSize - 1 * Math.sqrt(3.0f) / 2.0f);
horizOffsetX = (int) ((double) hexSize * Math.sqrt(3.0f));
horizOffsetY = (int) ((double) hexSize + 1 * Math.sqrt(3.0f) / 2.0f);
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
int[] xcoords = new int[6];
int[] ycoords = new int[6];
for (int i = 0; i < 6; i++) {
xcoords[i] = (int) ((hexSize + x * horizOffsetX + y * vertOffsetX)
+ (double) hexSize * Math.cos(i * 2 * Math.PI / 6));
ycoords[i] = (int) (((getSize().height / 2) + x * horizOffsetY
+ y * vertOffsetY) + (double) hexSize * Math.sin(i * 2 * Math.PI / 6));
}
g2d.setStroke(new BasicStroke(hexSize / 2.5f));
g2d.setColor(Color.GRAY);
g2d.drawPolygon(xcoords, ycoords, 6);
}
}
}
};
view = new JScrollPane(b);
b.addMouseWheelListener(this);
JFrame f = new JFrame();
f.setLocation(10, 10);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(view);
f.setPreferredSize(b.getPreferredSize());
f.pack();
f.setVisible(true);
}
public void mouseWheelMoved(MouseWheelEvent e) {
zoom = 100 * -Integer.signum(e.getWheelRotation());
if (hexSize - Integer.signum(e.getWheelRotation()) > 0) {
hexSize -= Integer.signum(e.getWheelRotation());
}
Dimension targetSize = new Dimension(b.getWidth() + zoom, b.getHeight() + zoom);
b.setPreferredSize(targetSize);
b.setSize(targetSize);
b.revalidate();
b.repaint();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
ZoomWithSelectionInViewport example = new ZoomWithSelectionInViewport();
} catch (Exception ex) {
//
}
}
});
}
}
推荐答案
如果我理解正确,您希望滚动窗格的滚动条反映当前的缩放状态。我看到两种选择:
If I understand correctly, you want the scroll pane's scroll bars to reflect the current zoom state. I see two alternatives:
-
不要覆盖
getPreferredSize()
在组件中,并调整鼠标侦听器中的首选大小以包含缩放图像;它似乎在右侧略微截断。
Don't override
getPreferredSize()
in the component, and adjust the preferred size in the mouse listener to include the zoomed image; it appears slightly truncated on the right.
执行覆盖 getPreferredSize()
在组件中,并调整返回的维度
(现在是一个常量),以包含隐含在 paintComponent()
。
Do override getPreferredSize()
in the component, and adjust the returned Dimension
(now a constant) to include the zoomed boundary implicit in paintComponent()
.
我更喜欢后者。我还发现编写显式转换函数来转换缩放和非缩放坐标很有帮助,如图所示。还可以使用显示的逆 AffineTransform
。
I'd prefer the latter. I've also found it helpful to write explicit transformation functions to convert zoomed and un-zoomed coordinates, as shown here. An inverse AffineTransform
, shown here, is also possible.
这篇关于将Graphics2d调整为JScrollPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!