首页 新闻 会员 周边

图片的拖动受范围限制,如何解决?

0
悬赏园豆:50 [已解决问题] 解决于 2012-09-21 08:49

图片在固定大小的矩形框里显示,对图片放大后,可以进行拖动、或缩小,但是不能让矩形框的底板露出来

(用矩阵进行变换,缩放是等倍的

请问,有什么简单的方法吗?

比如下面这段代码,怎样加上拖放的范围控制呢?(图片放大到一定程度后把Panel全部覆盖,但是在移动的过程中不能把图片的边界一处JPanel的边界)
[code=Java][/code]

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);
  }

}

Crazy_Yang的主页 Crazy_Yang | 初学一级 | 园豆:167
提问于:2012-09-17 22:04
< >
分享
最佳答案
0

哈哈,刚好我正在做这个。给你一个思路。

一、

最直接的方法就是在图片移动事件中判断图片的“区域”是否在画板中,在就可以移动,不在就不能移动。

主要是这个“区域”怎么取。因为你应用了变幻,所以这个要考虑进去。

这个记算就是坐标转换的问题了,有好多种方法,你可以参考Transform类,很简单的,两三行代码就行。

二、

拖动图片时,图片先不要动,用一个虚框代替,这样在移动事件中不会做太多处理,影响性能。

在放开时(UP事件)记算当前位置是否可以放置图片,如果可以就坐标替换,不可以就不变。

记算方式跟上面的一样,不同的是一个只记算一次,一个每移动一下都要记算。

收获园豆:40
中文代码 | 小虾三级 |园豆:951 | 2012-09-18 12:23

你好,请问你实现了嘛?有代码可以发出来参考下吗?急啊!现在开始按照你说的思路来尝试下

Crazy_Yang | 园豆:167 (初学一级) | 2012-09-18 12:31

楼主你实现了嘛?我按照你的思路试了下,但是还是不行啊,急啊!!1能否分享下你的?

Crazy_Yang | 园豆:167 (初学一级) | 2012-09-18 15:43

@Crazy_Yang:


求教了 ,哪位帮忙看下呢?

Crazy_Yang | 园豆:167 (初学一级) | 2012-09-20 12:13
其他回答(2)
0

帮顶 and 学习

收获园豆:10
jason2013 | 园豆:1998 (小虾三级) | 2012-09-18 08:58

求高手指点

支持(0) 反对(0) Crazy_Yang | 园豆:167 (初学一级) | 2012-09-18 09:01
0

public void mouseDragged(MouseEvent e) {
  point2 = e.getPoint();
  if(moveEnable){
  if(point1 != null && point2 != null){
  int dx = point2.x - point1.x;
  int dy = point2.y - point1.y;

  if(x + dx < 0 || y + dy < 0 || x + dx + width > getWidth() || y + dy + height > getHeight()) {
return;
  }
  
  x = x + dx;
  y = y + dy;
  //Layer.this.setLocation(_x, _y);
  point1 = point2;
  repaint();
  }
  }
  }
  };

Crazy_Yang | 园豆:167 (初学一级) | 2012-09-21 08:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册