问题描述:
要求:
1、选中图片后,通过鼠标拖拽改变图片的位置;
2、拖拽图片边框可以改变大小。实现方法不限,Swing和SWT 都行。
开发工具不限,eclipse 和 netbeans 都行。注意:是桌面程序,不是网页。源码会在一楼回复中给出,
先说一个问题:在拖拽图片的时候,由于需要不断地刷新屏幕,会出现闪屏的问题,有什么办法可以解决???

解决方案 »

  1.   

    源码是从下面链接拷贝过来的
    http://topic.csdn.net/u/20120201/15/2c9ea68e-c0ee-45e5-b9c6-c3e515a3e27f.html?seed=1629562633&r=77436630#r_77436630
    是用户 ssyliusha 提供的
    2个类
    不知道怎么上传图片,也不知道怎么上传项目压缩包。。自己去网上随便找一张256*256大小的bmp类型的图片吧 改名为img.bmp就可以了
    图片位置 项目根目录创建一个images的文件夹 图片放里面!!import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    /**
     * 读取图片
     * @author Administrator
     *
     */
    public class MyBufferedImage {
        
        private BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_3BYTE_BGR);
        
        public MyBufferedImage(){
            File file = new File("images/img.bmp");
            if(!file.exists())
                return;
            try {
                BufferedImage imageRead = ImageIO.read(file);
                Graphics g = image.getGraphics();
                g.drawImage(imageRead, 0, 0, imageRead.getWidth(),imageRead.getHeight(), null);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        public BufferedImage getImage(){
            return this.image;
        }
    }import java.awt.Color;
    import java.awt.Cursor;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionListener;
    import java.awt.image.BufferedImage;import javax.swing.JFrame;public class MainFrame extends JFrame implements MouseListener,MouseMotionListener{
        
        public static void main(String[] args) {
            new MainFrame();
        }
        
        private static final long serialVersionUID = 1L;
        
        private BufferedImage img;        //绘制图片
        
        private boolean isPressImage;        //是否操作图片
        
        private int moveSide;        //拉升的边(0:移动 1:上 2:下 3:左 4:右)
        
        private Point imagePoint;        //图片位置
        
        private int[] imageSize;        //图片大小
        
        private Point pressPoint;        //press图片时的鼠标位置    public MainFrame(){
            setSize(new Dimension(600,400));
            setResizable(false);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            initData();
            
            setVisible(true);
            
            this.getContentPane().addMouseListener(this);
            this.getContentPane().addMouseMotionListener(this);
        }
        
        private void initData(){
            img = new MyBufferedImage().getImage();
            imagePoint = new Point(0, 0);            //记录图片位置
            imageSize = new int[]{img.getWidth(),img.getHeight()};        //记录图片大小
        }    
        /**当前是否操作图片**/
        private boolean isContains(Point point){
            Rectangle rectangle = new Rectangle();
            rectangle.x = imagePoint.x;
            rectangle.y = imagePoint.y;
            rectangle.width = imageSize[0];
            rectangle.height = imageSize[1];
            return rectangle.contains(point);
        }
        
        /**得到是否是点击的4个边中的1个(0,1,2,3,4)**/
        private int getPressSide(Point point){
            int side = 0;
            Rectangle rectTop = new Rectangle(imagePoint.x+8,imagePoint.y,imageSize[0]-16,8);
            Rectangle rectBottom = new Rectangle(imagePoint.x+8,imagePoint.y+imageSize[1]-8,imageSize[0]-16,8);
            Rectangle rectLeft = new Rectangle(imagePoint.x,imagePoint.y+8,8,imageSize[1]-16);
            Rectangle rectRight = new Rectangle(imagePoint.x+imageSize[0]-8,imagePoint.y+8,8,imageSize[1]-16);        if(rectTop.contains(point)){
                setCursor(2);
                return 1;        //上
            }else if(rectBottom.contains(point)){
                setCursor(2);
                return 2;        //下
            }else if(rectLeft.contains(point)){
                setCursor(4);
                return 3;         //左
            }else if(rectRight.contains(point)){
                setCursor(4);
                return 4;        //右
            }
            return side;        //中间
        }
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
            
        }    @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub
            
        }    @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub
            
        }
        
        
        @Override
        public void mousePressed(MouseEvent e) {
            /**把图片所占的矩阵用变量表示出来(便于判断是否操作图片)**/
            if(isContains(new Point(e.getPoint().x+4, e.getPoint().y+30))){
                
                moveSide = getPressSide(new Point(e.getPoint().x+4, e.getPoint().y+30));        //记录操作图片的边
                
                isPressImage = true;
                pressPoint = e.getPoint();
            }else{
                isPressImage = false;
            }
        }
        
        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub
            isPressImage = false;
            pressPoint = null;
            setCursor(0);
        }
        
        @Override
        public void mouseDragged(MouseEvent arg0) {
            // TODO Auto-generated method stub
            if(isPressImage){
                Point nowPoint = arg0.getPoint();        //当前鼠标拖拽到的鼠标位置
                int diffX = nowPoint.x - pressPoint.x;
                int diffY = nowPoint.y - pressPoint.y;
                /**移动**/
                if(moveSide == 0){    
                    setCursor(1);
                    this.imagePoint.x += diffX;
                    this.imagePoint.y += diffY;
                    pressPoint = nowPoint;
                }
                /**收缩**/
                else{
                    //收缩 下和右时
                    if(moveSide == 2 || moveSide == 4){
                        if(moveSide == 2)            //拉下(只能拉长拉短)
                            this.imageSize[1] += diffY;
                        else                        //拉右(只能拉宽拉窄)
                            this.imageSize[0] += diffX;
                        
                    }
                    //收缩 上和左时
                    else if(moveSide == 1 || moveSide == 3){
                        if(moveSide == 1){            //拉上边(只能拉长拉短)
                            this.imagePoint.y += diffY;
                            this.imageSize[1] -= diffY;
                        }else{                        //拉左边(只能拉宽拉窄)
                            this.imagePoint.x += diffX;
                            this.imageSize[0] -= diffX;
                        }
                        
                    }
                    pressPoint = nowPoint;
                }
                repaint();
            }
        }    @Override
        public void mouseMoved(MouseEvent arg0) {
            // TODO Auto-generated method stub
            
        }
        
        public void paint(Graphics g){
            super.paint(g);
            g.drawImage(img, imagePoint.x, imagePoint.y, imageSize[0],imageSize[1], null);
        }
        
        public void update(Graphics g){
            paint(g);
        }
        
        public void repaint(Graphics g){
            paint(g);
        }
    }
      

  2.   


    处理闪屏的常规手段是 DoubleBuffer,不过太久没搞已经不熟悉。总的来说就是不要让repaint直接输出到屏幕上,而是先输出到image上,然后切换image。
      

  3.   

    参考下这里:http://huzhenyu.iteye.com/blog/975046http://developer.51cto.com/art/201105/259587.htm
      

  4.   

    楼主,对不起,误导你了。
    认真看了你代码后发现,你这个问题不是常规的双缓冲问题,而是你的paint方法调用了super.paint(g);导致每次都会清屏再回写image,从而产生屏闪。粗暴的解决方案如下:    public void paint(Graphics g) {
            // super.paint(g);
            Image tmp = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
            tmp.getGraphics().drawImage(img, imagePoint.x, imagePoint.y, null);
            g.drawImage(tmp, 0, 0, null);    }
    可做改进,把用来做背景的tmp重用起来,而不要每次都new,那么paint之前做个clear就好了。
      

  5.   

    谢谢,修改的确不闪屏了,可是背景怎么是黑色的,我修改了rgb也没用。BufferedImage temp   = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
         temp.setRGB(255, 255, 255);
         Image tmp=temp;
             tmp.getGraphics().drawImage(img, imagePoint.x, imagePoint.y, imageSize[0],imageSize[1],null);
             g.drawImage(tmp, 0, 0, null);
      

  6.   


    调错函数了,要用Graphics的才行。tmp.getGraphics().setColor(......);
      

  7.   

    这个对Swing和Java2D来说,很容易实现。
      

  8.   


    tmp.getGraphics().setColor(Color.WHITE);这样写,他的背景色还是黑色
      

  9.   

    设置完了,至少还要做个fill啥的吧tmp.getGraphics().setColor(Color.WHITE);
    tmp.getGraphics().fillRect(0, 0, this.getWidth(), this.getHeight());
      

  10.   


    Image tmp          = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
                tmp.getGraphics().setColor(Color.RED);
                tmp.getGraphics().fillRect(0, 0, this.getWidth(), this.getHeight());
    我设置的是红色,怎么填充出来时白色背景。