JPanel缩小 [英] JPanel zoom out

查看:117
本文介绍了JPanel缩小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码非常适合放大和缩小,但缩小有限制.如何改进此代码以允许不受限制地缩小.在这个例子中 您可以根据需要进行放大,但是可以通过缩小来将放大的面板恢复到原始状态.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆