【问题标题】:Object issues in JavaJava 中的对象问题
【发布时间】:2012-10-08 04:20:31
【问题描述】:

我正在尝试在画布上实现形状的拖动功能。我的Shape 类继承自JPanel

当我单击一个形状、拖动它并松开鼠标按钮时,绝对没有任何反应。它只是保持在原来的位置。有什么想法吗?

【问题讨论】:

  • 查看@camickr 的ComponentMover
  • getSelectedShape() 中的代码能否在鼠标点击时为您提供正确的形状对象?
  • 是的,我已经测试过了,它可以工作。 @sampson-chen
  • 感谢您的链接,但是我已经根据这些示例编写了上述代码,但不确定我哪里出错了。
  • 在哪里更新 shape.xPosition 和 shape.yPosition?似乎调用 getLocation() 会更好。另外,你设置了布局管理器吗?我想这也可能导致问题。

标签: java swing events graphics awt


【解决方案1】:

你需要一些基本的东西:

  1. 形状本身的字段(您已经拥有)
  2. 用于跟踪形状内点击偏移的字段(已有)
  3. 跟踪您是否正在拖动的字段
  4. 覆盖paintComponent 方法以绘制形状
  5. MouseListenerMouseMotionListener 添加到面板(MouseAdapter 执行这两项操作)

这是一个基本的工作示例。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawTest extends JPanel{

    //Shape doesn't have a location field - you'd have to keep track of  
    //this yourself if you're set on using the shape interface
    private Rectangle shape = new Rectangle(100, 100);
    // The location within the shape you clicked
    private int xOffset = 0; 
    private int yOffset = 0;
    // To indicate dragging is happening
    boolean isDragging = false;

    public DrawTest(){
        MouseAdapter listener = new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                // Starts dragging and calculates offset
                if(shape.contains(e.getPoint())){
                    isDragging = true;
                    xOffset = e.getPoint().x - shape.x;
                    yOffset = e.getPoint().y - shape.y;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // Ends dragging
                isDragging = false;
            }


            @Override
            public void mouseDragged(MouseEvent e) {
                // Moves the shape - doesn't actually need to be a method
                // but is because you had it as one
                if(isDragging){
                    moveShape(e);
                }
            }

            private void moveShape(MouseEvent e) {
                Point newLocation = e.getPoint();
                newLocation.x -= xOffset;
                newLocation.y -= yOffset;
                shape.setLocation(newLocation);
                repaint();
            }
        };

        //Add a mouse mostion listener (for dragging) and regular listener (for clicking)
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }

    // So we have a play area to work with
    public Dimension getPreferredSize(){
        return new Dimension(400,300);
    }

    //Paints the shape
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.clearRect(0,0,getWidth(), getHeight());
        g.fillRect(shape.x, shape.y, shape.width, shape.height);
    }


    public static void main(String[] args)
    {

        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new DrawTest());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

【讨论】:

  • +1 个很好的例子(当我的硬盘死机时,我失去了自己的例子:0)
  • @DavidKroukamp 这是失去任何东西的最糟糕的方式 - 你有我的哀悼......(为死者默哀片刻)
  • @DotNET 如果您可以将您的示例更新为一个小的可运行示例,我们也许可以指出您的错误。根据您发布的代码,第 3、4 或 5 点最有可能出现问题的地方
  • 我很惊讶,我希望 setLayout( null ) 做绝对定位。
【解决方案2】:

尝试了一个简单的小例子

拖动矩形将使其随光标移动,它还会检查边界,因此不能将矩形拖出屏幕:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ShapeMover {

    public ShapeMover() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Shape Mover");
        initComponents(frame);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String s[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ShapeMover();
            }
        });

    }

    private void initComponents(JFrame frame) {
        frame.getContentPane().add(new DragPanel());
    }
}

class DragPanel extends JPanel {

    Rectangle rect = new Rectangle(0, 0, 100, 50);
    int preX, preY;
    boolean isFirstTime = true;
    Rectangle area;
    boolean pressOut = false;
    private Dimension dim = new Dimension(400, 300);

    public DragPanel() {
        setBackground(Color.white);
        addMouseMotionListener(new MyMouseAdapter());
        addMouseListener(new MyMouseAdapter());
    }

    @Override
    public Dimension getPreferredSize() {
        return dim;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        if (isFirstTime) {
            area = new Rectangle(dim);
            rect.setLocation(50, 50);
            isFirstTime = false;
        }

        g2d.setColor(Color.black);
        g2d.fill(rect);
    }

    boolean checkRect() {
        if (area == null) {
            return false;
        }

        if (area.contains(rect.x, rect.y, 100, 50)) {
            return true;
        }
        int new_x = rect.x;
        int new_y = rect.y;

        if ((rect.x + 100) > area.getWidth()) {
            new_x = (int) area.getWidth() - 99;
        }
        if (rect.x < 0) {
            new_x = -1;
        }
        if ((rect.y + 50) > area.getHeight()) {
            new_y = (int) area.getHeight() - 49;
        }
        if (rect.y < 0) {
            new_y = -1;
        }
        rect.setLocation(new_x, new_y);
        return false;
    }

    private class MyMouseAdapter extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            preX = rect.x - e.getX();
            preY = rect.y - e.getY();

            if (rect.contains(e.getX(), e.getY())) {
                updateLocation(e);
            } else {
                pressOut = true;
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (!pressOut) {
                updateLocation(e);
            } else {
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (rect.contains(e.getX(), e.getY())) {
                updateLocation(e);
            } else {
                pressOut = false;
            }
        }

        public void updateLocation(MouseEvent e) {
            rect.setLocation(preX + e.getX(), preY + e.getY());
            checkRect();

            repaint();
        }
    }
}

参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多