【问题标题】:how to move and scale image by dragging it's edges?如何通过拖动边缘来移动和缩放图像?
【发布时间】:2013-08-23 11:34:21
【问题描述】:

我之前也发布过这个问题,但这次我只添加了必需和必要的代码,尽管代码有些冗长。 我想在 Jlabel 中加载图像,然后在用户单击下一步按钮时更改图像。当用户想要移动或缩放图像时,他可以通过选择图像边缘轻松地做到这一点,但它不起作用。 除了缩放和运动图像,所有问题都解决了。

我的代码:

public class CopyOfPictureEditor extends JFrame 
{ 
    private static final long serialVersionUID = 6676383931562999417L; 
    String[] validpicturetypes = {"png", "jpg", "jpeg", "gif"}; 
    Stack<File> pictures ;
    JLabel label = new JLabel(); 
    BufferedImage a = null; 
    JPanel panel = new JPanel();

    public CopyOfPictureEditor() 
    { 
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());            
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }            
        JMenuBar menubar = new JMenuBar(); 
        JMenu toolsmenu = new JMenu(" File ");          
        final File dir = new File("");
        final JFileChooser file;
        file = new JFileChooser();
        file.setCurrentDirectory(dir);
        file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        file.showOpenDialog(panel);
        String path = file.getSelectedFile().getAbsolutePath();
        System.out.println(path);
        pictures= getFilesInFolder(path.toString());        
         JButton NEXT = new JButton("");         
        NEXT.setToolTipText("Next Image");           
        Image imgn = null;           
        try 
        { 
           imgn = ImageIO.read(getClass().getResource("/images/next12.png"));
        }catch (IOException e) {    
             e.printStackTrace();
        }                          
        NEXT.setIcon(new ImageIcon(imgn));            
        JPanel buttonPane = new JPanel();           
        buttonPane.add(Box.createRigidArea(new Dimension(250,0)));              
        buttonPane.add(Box.createRigidArea(new Dimension(250,0)));          
        NEXT.addActionListener(new ActionListener()  {          
            @Override
            public void actionPerformed(ActionEvent arg0) {         
                nextImage();
            }
        });         
        buttonPane.add(NEXT);
        getContentPane().add(buttonPane, BorderLayout.SOUTH);           
        setJMenuBar(menubar); 
        menubar.add(toolsmenu);     
        panel.add(label,BorderLayout.CENTER);       
        add(panel);         
        setTitle("Aero Picture Editor"); 
        setVisible(true);       
        setPreferredSize(getPreferredSize());
        setLocation(0,0);
            label.addMouseListenet(new MouseHandler());     
            label.addMouseMotionListenet(new MouseHandler());
    } 
     public Stack<File> getFilesInFolder(String startPath){ 
        File startFolder = new File(startPath); 
        Stack<File> picturestack = new Stack<File>();       
        String extension; 
        int dotindex; 
        for (File file : startFolder.listFiles()) { 
            extension = ""; 
            dotindex = file.getName().lastIndexOf('.');

            if (dotindex > 0) { 
                extension = file.getName().substring(dotindex + 1);                     
                for (String filetype : validpicturetypes){ 
                    if (extension.equals(filetype)) { 
                        picturestack.add(file); 
                    } 
                } 
            } 
        } 
    return picturestack; 
    } 
      public void nextImage()   {   
        String p;
        File f;
        try{
            f= pictures.pop().getAbsoluteFile();
            a=ImageIO.read(f);
            p = f.getPath();
            System.out.println(p);                  
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        ImageIcon image = new ImageIcon(a);         
         label.setIcon(image);          
        repaint();
    }    
     protected void paintComponent(Graphics g) 
     {
        super.paintComponents(g);
        Graphics2D g2d = (Graphics2D) g.create();        
        int x = (getWidth() - a.getWidth()) / 2;
        int y = (getHeight() - a.getHeight()) / 2;        
        AffineTransform at = new AffineTransform();
        at.translate(x, y);           
        g2d.setTransform(at);            
        g2d.drawImage(a, 0, 0, this);
        g2d.dispose();
    }
    public enum MouseAction  {
         Move(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)),
         ResizeSouth(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)),
         ResizeNorth(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)),
         ResizeEast(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)),
         ResizeWest(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)),
         ResizeNorthEast(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)),
         ResizeNorthWest(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)),
         ResizeSouthEast(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)),
         ResizeSouthWest(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
         private Cursor cursor;
         private MouseAction(Cursor cursor)  {
             this.cursor = cursor;
         }
         public Cursor getCursor() {
             return cursor;
        }
     }  
    public class MouseHandler extends MouseAdapter 
    {
        private MouseAction action;
        private Point clickPoint;
        private boolean ignoreMoves;
        protected void updateAction(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            int width = getWidth();
            int height = getHeight();
            if (x < 10 && y < 10)      {
                action = MouseAction.ResizeNorthWest;
            }         else if (x > width - 10 && y < 10)         {
                action = MouseAction.ResizeNorthWest;
            }             else if (y < 10)             {
                action = MouseAction.ResizeNorth;
            }             else if (x < 10 && y > height - 10)            {
                action = MouseAction.ResizeSouthWest;
            }             else if (x > width - 10 && y > height - 10)            {
                action = MouseAction.ResizeSouthEast;
            }             else if (y > height - 10)             {
                action = MouseAction.ResizeSouth;
            }             else if (x < 10)            {
                action = MouseAction.ResizeWest;
            }            else if (x > width - 10)             {
                action = MouseAction.ResizeEast;
            }             else             {
                action = MouseAction.Move;
            }            setCursor(action.getCursor());
        }
        @Override
        public void mouseMoved(MouseEvent e)  {
            if (!ignoreMoves) 
            {
                updateAction(e);
            }
        }
        @Override
        public void mousePressed(MouseEvent e) {
            updateAction(e);
            ignoreMoves = true;
            clickPoint = e.getPoint();
            repaint();        
            System.out.println(e.getX());
            System.out.println(e.getY());*/
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            clickPoint = null;
            ignoreMoves = false;           
        }
        @Override
        public void mouseDragged(MouseEvent e)  {           
            switch (action)  {
                case Move:  {
                    Point p = e.getPoint();
                    p.x -= clickPoint.x;                  
                    p=SwingUtilities.convertPoint(label, p, null);                    
                    setLocation(p);
                }
                break;
                case ResizeWest:  {
                    Point p = e.getPoint();
                    int xDelta = p.x - clickPoint.x;
                    int width = getWidth() - xDelta;
                    int x = getX() + xDelta;
                    setSize(width, getHeight());
                    setLocation(x, getY());
                    revalidate();
                }
                break;
                case ResizeEast:  {
                    Point p = e.getPoint();
                    int xDelta = p.x - clickPoint.x;
                    int width = getWidth() + xDelta;                   
                    setSize(width, getHeight());
                    revalidate();
                    clickPoint = p;
                }
                break;
                case ResizeNorth:  {
                    Point p = e.getPoint();
                    int yDelta = p.y - clickPoint.y;
                    int height = getHeight() - yDelta;
                    int y = getY() + yDelta;                    
                    setSize(getWidth(), height);
                    setLocation(getX(), y);
                    revalidate();
                }
                break;
                case ResizeSouth:  {
                    Point p = e.getPoint();
                    int yDelta = p.y - clickPoint.y;
                    int height = getHeight() + yDelta;                   
                    setSize(getWidth(), height);
                    revalidate();
                    clickPoint = p;
                }
                break;
            }
        }
        @Override
        public void mouseExited(MouseEvent e) 
        {           
        }
    }
}

【问题讨论】:

  • 您有可以编译的代码示例吗?您看到了什么错误?
  • @Robert - 不,先生,没有错误,当我执行此代码时,整个窗口被拖动,我无法通过选择边缘来拖动或缩放图像。
  • @user2659972 停止发布关于同一主题的问题,做其他人已经多次问过的问题,提供SSCCE
  • 然后提供SSCCE
  • “必需的代码” SSCCE 不仅仅是“短”。 SSCCE 需要导入、类声明和main() 来运行它。它应该热链接到图像,或在 SSCCE 本身中创建合成图像。

标签: java image swing mouselistener


【解决方案1】:

找到这个:

label.addMouseListener(new MouseHandler());     
label.addMouseMotionListener(new MouseHandler());

由于您将 clickPoint 设置为 mousePressed 并希望将其设置为 mouseDragged,因此它应该是同一个对象。您实际上应该在 mouseDragged 中获得一些空指针吗?

【讨论】:

  • MouseHandler mouseHandler = new mouseHandler(); label.addMouseListenet(mouseHandler); label.addMouseMotionListenet(MouseHandler);那么你得到一些 NullpointerExceptions 了吗?
  • 不,先生,它工作不正常。是的,拖动有效,但整个窗口都在拖动。不,我没有得到空指针异常
  • 先生,我只添加了罗伯特发布给我的一件事。 label.setlocation 等
  • 刚刚测试了它,我替换了 label.setLocation,用 validate 重新验证,listerner 的东西,它对我有用。拖动不是 100% 正确,但这只是坐标问题
  • 先生,我要不要放 label.setLocation ?有一件事很清楚,我必须用 validate 替换 revalidate。
【解决方案2】:

如果没有完整的代码,很难看到,但一方面,您在 MouseDragged 方法中对 Window 本身调用 setSizesetLocation。如果你想获取用户点击的对象,你需要从e.getSource()获取,比如:

public void mouseDragged(MouseEvent e){
    JLabel l = (JLabel)e.getSource();
    switch(action){
        case ResizeWest:
                Point p = e.getPoint();
                int xDelta = p.x - clickPoint.x;
                int width = getWidth() - xDelta;
                int x = getX() + xDelta;
                l.setSize(width, getHeight()); // call setSize on JLabel l
                l.setLocation(x, getY());
                l.revalidate();
                break;
    }

顺便说一句,您为什么要为此使用 JLabel?我会使用一个 Java 对象,该对象使用 JFrame 的图形上下文将自身绘制到 JFrame 上。

【讨论】:

  • 先生,我必须创建新的 JLabel 实例,否则我的全局实例 label 将在 l.setSize(width, getHeight()); l.setLocation(x, getY());l.revalidate(); 工作
  • 您将拥有多少个标签?一?然后你可以调用它上面的方法,但是如果你希望能够扩展到多个,最好从MouseEvent获取源对象。
  • 我在整个应用程序中只使用了一个标签,即在全局部分声明。在每个地方我都在重新粉刷和替换那个标签。
  • 是的,试试看会发生什么。
  • 不,它不起作用我试过label.setSize(getWidth(), height); label.setLocation(getX(), y); label.revalidate();,但它不起作用。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
相关资源
最近更新 更多