J2SE的 JPanel实现点击缩放 ,然后可以拉动,类似于百度地图那种,有没有哪位有思路的呢?
求指导下,或者说下思路就行
谢谢了比如这一个界面
我点击中间的部分
那么他就放大到2倍
但是又不能覆盖到周围的那3个Panel
值能通过鼠标拉动来查看放大后的整个Panel
求哪位同僚指点下 或者提供一个思路也可以,谢谢了!

解决方案 »

  1.   

    package map;import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseWheelEvent;
    import java.awt.event.MouseWheelListener;import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;public class Layer extends JPanel{
    private static final long serialVersionUID = 1L;
    ImageIcon img = new ImageIcon(Toolkit.getDefaultToolkit().createImage("/root/桌面/2000.jpg"));

    //以下两个参数描述图层的位置
    private int x = 0;//
    private int y = 0;
    //以下两个参数描述图层的大小
    private int width = 300;
    private int height = 300;

    //以下两个参数描述图层的每次放大或缩小的尺寸
    private int dx = 50;
    private int dy = 50;

    public Layer(){
    this.addMouseWheelListener(new MouseWheelListener() {

    public void mouseWheelMoved(MouseWheelEvent e) {
    if(e.getWheelRotation() < 0){
    zoom();
    }else{
    reduce();
    }

    }
    });

    MouseAdapter ma = new MouseAdapter(){ @Override
    public void mouseClicked(MouseEvent e) {
    zoom();
    }
    boolean moveEnable = false;
    Point point1 = null;
    Point point2 = null;

    @Override
    public void mousePressed(MouseEvent e) {
    moveEnable = true;
    point1 = e.getPoint();
    } @Override
    public void mouseReleased(MouseEvent e) {
    moveEnable = false; 
    point1 = null;
    point2 = null;
    } @Override
    public void mouseMoved(MouseEvent e) {
    //System.out.println("move");
    }
    @Override
    public void mouseDragged(MouseEvent e) {
    System.out.println("dragged");
    point2 = e.getPoint();
    if(moveEnable){
    if(point1 != null && point2 != null){
    int dx = point2.x - point1.x;
    int dy = point2.y - point1.y;
    x = x + dx;
    y = y + dy;
    //Layer.this.setLocation(_x, _y);
    point1 = point2;
    repaint();
    }
    }
    }
    };

    this.addMouseMotionListener(ma);
    this.addMouseListener(ma);
    }
    @Override
    public void paint(Graphics g) {
    //所有的图层变更都在此方法内响应
    super.paint(g);

    Graphics2D g2 = (Graphics2D) g;
    g2.clearRect(0, 0, getBounds().width, getBounds().height);
    g2.drawImage(img.getImage(), x, y, width, height, null);

    }

    /**
     * 缩小
     */
    public void reduce(){
    if(width > 2*dx && height > 2*dy){
    x +=  dx;
    y +=  dy;
    width -= 2 * dx;
    height -= 2 * dy;
    super.repaint();
    }

    }

    /**
     * 放大
     */
    public void zoom(){
    x -=  dx;
    y -=  dy;
    width += 2 * dx;
    height += 2 * dy;
    super.repaint();
    }

    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    JFrame f = new JFrame();
    f.setLayout(new BorderLayout());
    f.setSize(500, 500);

    final Layer layer = new Layer();
    layer.setBorder(new EmptyBorder(2,2,2,2));
    layer.setOpaque(true);
    layer.setBackground(Color.BLUE);
    layer.setSize(400, 400);
    f.getContentPane().add(layer);
    JButton btn1 = new JButton("放大");
    btn1.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
    layer.zoom();
    }
    });

    JButton btn2 = new JButton("缩小");
    btn2.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
    layer.reduce();
    }
    });
    f.add(btn1,BorderLayout.NORTH);
    f.add(btn2,BorderLayout.SOUTH);

    f.setVisible(true);
    }}
      

  2.   

    JPanel 的 鼠标滚轮事件
      

  3.   

    但是我想了下 这个是JPanel背景图片的缩放而不是JPanel的缩放吧?
      

  4.   


    按照你的程序 可以实现拖放,缩放。但是每次repaint的时候的位置都是拖放后的位置,这就导致JPanel出现空白。我的想法是限制图片的坐标不能出界,但是我找不到方法来获得图片的坐标。不知道楼主知不知道怎么样来实现?有空指点一下小弟,谢谢了!
      

  5.   

    你这是图片的放大吧!亲,一下应该会对你有用的:
    把图片名称改成picture.jpghttp://my.csdn.net/luoweifu/album/detail/1293263#1288401
    import java.awt.*;
    import java.awt.event.*;
    import java.io.File;
    import java.net.URL;import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    /**
     * 设置头像
     * @author 罗伟富
     *
     */
    public class HeadPicture extends JDialog implements ChangeListener, ActionListener{
    /**
     * 头像界面的宽度
     */
    public static final int WIDTH = 380;
    /**
     * 头像界面的高度
     */
    public static final int HEIGHT = 580;
    /**
     * 显示图片版面的宽度
     */
    public static final int PWIDTH = 350;
    /**
     * 显示图片版面的高度
     */
    public static final int PHEIGHT = 300;
    /**
     * 滑块的最大值
     */
    public static final int JS_MAXIMUM = 100;
    Image img;
    JSlider jsliderH, jsliderV; //水平和垂直滑块
    JPanel uP, dP, picP, uplodP, setP;
    JButton systemB, nativeB, confirmB1, confirmB2, turnH, turnV, slantL, slantR, restoreB; 
    JTextField tf;
    MyCanvas canvas;
    int imgW = PWIDTH, imgH = PHEIGHT;
    int xcentre = PWIDTH/2, ycentre = PHEIGHT/2;
    private int dx1 = xcentre-imgW/2, dy1 = ycentre-imgH/2, dx2 = xcentre + imgW/2, dy2 = ycentre + imgH/2;
    private int sx1 = 0, sy1 = 0, sx2, sy2;
    private float shx = 0, shy = 0;
    /**
     * 构造函数
     */
    public HeadPicture() {
    launchDialog();
    }

    /**
     * 构造函数
     * @param editor Editor 对象
     * @param frame 对话框所属的容器
     * @param title 对话框的标题
     * @param model 为 true 时是有模式对话框,false 时允许其他窗口同时处于激活状态 
     */
    public HeadPicture(JFrame frame, String title, boolean model) {
    super(frame, title, model);
    launchDialog();
    }
    /**
     * 返回canvas
     * @return
     */
    public Canvas getCanvas() {
    return canvas;
    }
    /**
     * 界面设计
     */
    private void launchDialog() {
    //初始化图片对象
    //URL imgrul = HeadPicture.class.getResource("/systemPictures/landscape9.jpg");
    //初始化组件
    URL imgrul = HeadPicture.class.getResource("/landscape9.jpg");
    img = Toolkit.getDefaultToolkit().getImage(imgrul);
    canvas = new MyCanvas();
    jsliderH = new JSlider();
    jsliderH.setMaximum(JS_MAXIMUM);
    jsliderH.setValue(JS_MAXIMUM/2);
    jsliderH.setMinimum(1);
    jsliderH.setOrientation(JSlider.HORIZONTAL);
    jsliderH.addChangeListener(this);
    jsliderV = new JSlider();
    jsliderV.setMaximum(JS_MAXIMUM);
    jsliderV.setValue(JS_MAXIMUM/2);
    jsliderV.setMinimum(1);
    jsliderV.setOrientation(JSlider.VERTICAL);
    jsliderV.addChangeListener(this);
    picP = new JPanel();
    picP.setPreferredSize(new Dimension(PWIDTH, PHEIGHT));
    uP = new JPanel();
    dP = new JPanel();
    uplodP = new JPanel();
    setP = new JPanel();
    systemB = new JButton("浏览系统图片");
    nativeB = new JButton("浏览本地图片");
    confirmB1 = new JButton("确定");
    confirmB2 = new JButton("确定");
    turnH = new JButton("水平翻转");
    turnV = new JButton("垂直翻转");
    slantL = new JButton("向左倾斜");
    slantR = new JButton("向右倾斜");
    restoreB = new JButton("还原默认设置");
    tf  = new JTextField();
    //添加组件
    picP.setLayout(new BorderLayout());
    picP.add(canvas, BorderLayout.CENTER);
    uP.setLayout(new BorderLayout());
    uP.add(picP, BorderLayout.CENTER);
    uP.add(jsliderH, BorderLayout.SOUTH);
    uP.add(jsliderV, BorderLayout.EAST);

    uplodP.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.insets = new Insets(2,2,2,2);
    gbc.gridx = 0;
    gbc.gridy = 0;
    uplodP.add(systemB, gbc);
    gbc.gridx = 1;
    gbc.gridy = 0;
    uplodP.add(new JLabel("                           "), gbc);
    gbc.gridx = 2;
    gbc.gridy = 0;
    uplodP.add(nativeB, gbc);
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.gridwidth = 2;
    uplodP.add(tf, gbc);
    gbc.gridx = 2;
    gbc.gridy = 1;
    gbc.gridwidth = 1;
    uplodP.add(confirmB1, gbc);
    uplodP.setBorder(new TitledBorder(new SoftBevelBorder(SoftBevelBorder.RAISED, new Color(50, 160, 130), new Color(120, 180, 60)),"更改图片"));

    setP.setLayout(new GridLayout(3, 2, 20, 5));
    setP.add(turnH);
    setP.add(turnV);
    setP.add(slantL);
    setP.add(slantR);
    setP.add(confirmB2);
    setP.add(restoreB);
    setP.setBorder(new TitledBorder(new SoftBevelBorder(SoftBevelBorder.RAISED, new Color(50, 160, 130), new Color(120, 180, 60)),"图片设置"));

    dP.setLayout(new BoxLayout(dP, BoxLayout.Y_AXIS) );
    dP.add(uplodP);
    dP.add(setP);
    //添加响应 //systemB, nativeB, confirmB1, confirmB2, turnH, turnV, slantL, slantR, restoreB;
    systemB.addActionListener(this);
    nativeB.addActionListener(this);
    confirmB1.addActionListener(this);
    confirmB2.addActionListener(this);
    turnH.addActionListener(this);
    turnV.addActionListener(this);
    slantL.addActionListener(this);
    slantR.addActionListener(this);
    restoreB.addActionListener(this);

    Container c = getContentPane();
    c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS));
    c.add(uP);
    c.add(dP);
    setSize(WIDTH, HEIGHT);
    setResizable(false);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    setVisible(true);

    }
    /**
     * 事件监听响应
     */
    public void actionPerformed(ActionEvent e) {
    if(e.getSource() == systemB) {
    URL picUrl = HeadPicture.class.getResource("/systemPictures");
    String dir = picUrl.toString();
    String dirs[] = dir.split("/");
    StringBuffer picDir = new StringBuffer();
    for(int i=1; i<dirs.length-1; i++) {
    picDir.append(dirs[i] + "\\");
    }
    picDir.append(dirs[dirs.length-1]);
    //以上这一段代码的作用是将file:/E:/Eclipse/workspace/Editor1.3/bin/systemPictures
    //变成E:\Eclipse\workspace\Editor1.3\bin\systemPictures
    JFrame optionPicFrame = new JFrame("打开系统图片");
    FileDialog openFileDialog = new FileDialog(optionPicFrame, "打开系统图片");
    openFileDialog.setMode(FileDialog.LOAD); //设置此对话框为从文件加载内容
    openFileDialog.setFile("*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.tif;"); //设置可打开文件的类型为:.txt,.java
    openFileDialog.setDirectory(picDir.toString());
    if(!openFileDialog.getDirectory().endsWith("systemPictures")) {
    openFileDialog.setDirectory(picDir.toString()); //设置默认路径
    }
    openFileDialog.setVisible(true);
    String fileName = openFileDialog.getFile();
    String directory = openFileDialog.getDirectory();
    if(null != fileName) {
    String fn = directory + fileName;
    tf.setText(fn);
    tf.setCaretPosition(fn.length());
    } else {
    tf.setText("您已经取消选择了,请重新选择!");
    }
    } else if(e.getSource() == nativeB) {
    JFrame optionPicFrame = new JFrame("打开本地图片");
    FileDialog openFileDialog = new FileDialog(optionPicFrame, "打开本地图片");
    openFileDialog.setMode(FileDialog.LOAD); //设置此对话框为从文件加载内容
    openFileDialog.setFile("*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.tif;");
    //设置可打开文件的类型为:.jpg,.jpeg等
    openFileDialog.setDirectory("C:\\Users\\Administrator\\Desktop"); //设置默认路径
    openFileDialog.setVisible(true);
    String fileName = openFileDialog.getFile();
    String directory = openFileDialog.getDirectory();
    if(null != fileName) {
    String fn = directory + fileName;
    tf.setText(fn);
    tf.setCaretPosition(fn.length());
    } else {
    tf.setText("您已经取消选择了,请重新选择!");
    }
    } else if(e.getSource() == confirmB1) {
    if(!tf.getText().equals("您已经取消选择了,请重新选择!")) {
    img = Toolkit.getDefaultToolkit().getImage(tf.getText().trim());
    canvas.repaint();
    } else {
    JOptionPane.showMessageDialog(this, "你还没有选择图片,请先选择图片!");
    }
    } else if(e.getSource() == turnH) {
    int temp = dx1;
    dx1 = dx2;
    dx2 = temp;
    canvas.repaint();
    } else if(e.getSource() == turnV) {
    int temp = dy1;
    dy1 = dy2;
    dy2 = temp;
    canvas.repaint();
    } else if(e.getSource() == slantL) {
    shx -= 0.1;
    canvas.repaint();
    } else if(e.getSource() == slantR) {
    shx += 0.1;
    canvas.repaint();
    } else if(e.getSource() == restoreB) {
    URL imgrul = HeadPicture.class.getResource("/systemPictures/landscape9.jpg");
    img = Toolkit.getDefaultToolkit().getImage(imgrul);
    dx1 = xcentre-imgW/2;
    dy1 = ycentre-imgH/2;
    dx2 = xcentre + imgW/2;
    dy2 = ycentre + imgH/2;
    sx1 = 0;
    sy1 = 0;
    sx2 = img.getWidth(this);
    sy2 = img.getWidth(this);
    canvas.repaint();

    }
    /**
     * 滑动条滑动响应事件
     */
    public void stateChanged(ChangeEvent e) {
    if(e.getSource() == jsliderH) {
    float valueH = jsliderH.getValue();
    imgW = (int)(2*PWIDTH*(valueH/JS_MAXIMUM));
    if(imgW < PWIDTH/4) {
    imgW = PWIDTH/4;
    }
    dx1 = xcentre-imgW/2;
    dy1 = ycentre-imgH/2;
    dx2 = xcentre + imgW/2;
    dy2 = ycentre + imgH/2;
    canvas.repaint();
    } else if(e.getSource() == jsliderV) {
    float valueV = jsliderV.getValue();
    imgH = (int)(2*PHEIGHT*(valueV/JS_MAXIMUM));
    if(imgH < PHEIGHT/4) {
    imgH = PHEIGHT/4;
    }
    dx1 = xcentre-imgW/2;
    dy1 = ycentre-imgH/2;
    dx2 = xcentre + imgW/2;
    dy2 = ycentre + imgH/2;
    canvas.repaint();
    }
    }

    public static void main(String[] args) {
    new HeadPicture();
    }

    /**
     * 用于画图像的Canvas
     */
    class MyCanvas extends Canvas {

    public MyCanvas() {

    }
    public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    //g.drawImage(img, xcentre-imgW/2, ycentre-imgH/2, imgW, imgH, this);
    sx2  = img.getWidth(this);
    sy2  = img.getHeight(this);
    g2.shear(shx, shy);
    g2.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, this);//Color.green, 
    }
    }

    }