JPanel缩小 [英] JPanel zoom out
问题描述
下面的代码非常适合放大和缩小,但缩小有限制.如何改进此代码以允许不受限制地缩小.在这个例子中 您可以根据需要进行放大,但是可以通过缩小来将放大的面板恢复到原始状态.
The code below is perfect for zoom in and zoom out, but zoom out with restrictions. How to improve this code to allow zoom out without restrictions. In this example you can do zoom in ever you want, but zooming out is possible to return zoomed in panel to its original state.
public class FPanel extends javax.swing.JPanel {
private Dimension preferredSize = new Dimension(400, 400);
private Rectangle2D[] rects = new Rectangle2D[50];
public static void main(String[] args) {
JFrame jf = new JFrame("test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 400);
jf.add(new JScrollPane(new FPanel()));
jf.setVisible(true);
}
public FPanel() {
// generate rectangles with pseudo-random coords
for (int i=0; i<rects.length; i++) {
rects[i] = new Rectangle2D.Double(
Math.random()*.8, Math.random()*.8,
Math.random()*.2, Math.random()*.2);
}
// mouse listener to detect scrollwheel events
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
updatePreferredSize(e.getWheelRotation(), e.getPoint());
}
});
}
private void updatePreferredSize(int n, Point p) {
double d = (double) n * 1.08;
d = (n > 0) ? 1/d : -d;
int w = (int) (getWidth() * d);
int h = (int) (getHeight() * d);
preferredSize.setSize(w, h);
int offX = (int)(p.x * d) - p.x;
int offY = (int)(p.y * d) - p.y;
setLocation(getLocation().x-offX,getLocation().y-offY);
getParent().doLayout();
}
public Dimension getPreferredSize() {
return preferredSize;
}
private Rectangle2D r = new Rectangle2D.Float();
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.red);
int w = getWidth();
int h = getHeight();
for (Rectangle2D rect : rects) {
r.setRect(rect.getX() * w, rect.getY() * h,
rect.getWidth() * w, rect.getHeight() * h);
((Graphics2D)g).draw(r);
}
}
}
推荐答案
如果我是对的,您希望缩小面板的比例小于100%(原始大小或JFrame的大小). 检查此代码.
If I am correct, you want to zoom out the panel less than 100% (original size OR size of the JFrame). Check this code.
public class FPanel extends javax.swing.JPanel {
private static int prevN = 0;
private Dimension preferredSize = new Dimension(400,400);
private Rectangle2D[] rects = new Rectangle2D[50];
public static void main(String[] args) {
JFrame jf = new JFrame("test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 400);
JPanel containerPanel = new JPanel(); // extra JPanel
containerPanel.setLayout(new GridBagLayout());
FPanel zoomPanel = new FPanel();
containerPanel.add(zoomPanel);
jf.add(new JScrollPane(containerPanel));
jf.setVisible(true);
}
public FPanel() {
// generate rectangles with pseudo-random coords
for (int i=0; i<rects.length; i++) {
rects[i] = new Rectangle2D.Double(
Math.random()*.8, Math.random()*.8,
Math.random()*.2, Math.random()*.2);
}
// mouse listener to detect scrollwheel events
addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
updatePreferredSize(e.getWheelRotation(), e.getPoint());
}
});
}
private void updatePreferredSize(int n, Point p) {
if(n == 0) // ideally getWheelRotation() should never return 0.
n = -1 * prevN; // but sometimes it returns 0 during changing of zoom
// direction. so if we get 0 just reverse the direction.
double d = (double) n * 1.08;
d = (n > 0) ? 1 / d : -d;
int w = (int) (getWidth() * d);
int h = (int) (getHeight() * d);
preferredSize.setSize(w, h);
int offX = (int)(p.x * d) - p.x;
int offY = (int)(p.y * d) - p.y;
getParent().setLocation(getParent().getLocation().x-offX,getParent().getLocation().y-offY);
//in the original code, zoomPanel is being shifted. here we are shifting containerPanel
getParent().doLayout(); // do the layout for containerPanel
getParent().getParent().doLayout(); // do the layout for jf (JFrame)
prevN = n;
}
@Override
public Dimension getPreferredSize() {
return preferredSize;
}
private Rectangle2D r = new Rectangle2D.Float();
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.red);
int w = getWidth();
int h = getHeight();
for (Rectangle2D rect : rects) {
r.setRect(rect.getX() * w, rect.getY() * h,
rect.getWidth() * w, rect.getHeight() * h);
((Graphics2D)g).draw(r);
}
}
}
说明:我添加了一个额外的JPanel(containerPanel
),其中包含zoomPanel
.当zoomPanel
的大小小于JFrame的大小时,containerPanel
将容纳创建的空白空间.
同样,位置敏感缩放仅在zoomPanel
的大小大于框的大小之前进行.一旦zoomPanel
小于JFrame,它将始终居中(通过GridBagLayout
).
Explaination : I have added an extra JPanel (containerPanel
) which contains the zoomPanel
. The containerPanel
will accommodate for the empty space created when zoomPanel
size is less than that of JFrame.
Also, the position sensitive zooming is only till the size of zoomPanel
is greater than that of frame. Once the zoomPanel
is smaller than JFrame, it will always be centered (by GridBagLayout
).
这篇关于JPanel缩小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!