-1

我想画一个可以在 Jpanel 上移动的画布。那就是当用户点击画布并拖动它时,它必须移动到一个新的位置。我已经实现了 MouseMotionListener,但我不知道要在里面包含什么来使画布按照要求移动。这是 DisplayCanvas 类:

class DisplayCanvas extends Canvas
{
    public DisplayCanvas()
    {
        setBounds(20, 40, 300, 300);
        setBackground(Color.white);
    }
}
class shape extends JFrame  implements MouseMotionListener{

static JPanel panel;
static Container contentpane;
static DisplayCanvas canvas;
shape()
{
    canvas=new DisplayCanvas();
    canvas.addMouseMotionListener(this);
    panel= new JPanel();
    panel.setBounds(20,20,250,140);
    panel.setLayout(null);
    contentpane = getContentPane();
    contentpane.add(canvas);
    contentpane.add(panel);
}
@Override
public void mouseDragged(MouseEvent e) {}
@Override
public void mouseMoved(MouseEvent arg0) {}
}

这就是我测试它的方式。

public class display 
{
    static JFrame frame;
    public static void main(String[] args) 
    {
        frame=new shape();
        frame.setBounds(380, 200, 500, 400);
        frame.setTitle("SHAPE AND COLOR");
        frame.setVisible(true);
    }
}

注意:请不要建议我使用 JPanel 来使用画布。

4

1 回答 1

4

您不想扩展的事实JPanel似乎很奇怪,但这并非不可行。然而,您可能会在某些时候遇到问题,因为您正在混合轻量级和重量级组件。您可能会遇到视觉故障和其他显示问题。

但是,我会提请您注意您在当前代码中犯的几个重要错误:

  1. 如果不需要,不要扩展类(不需要扩展JFrame也不Canvas
  2. static除非绝对必要,否则不要制造变量
  3. 遵循 Java 命名约定:类名总是以大写字母开头
  4. 不要使用null LayoutManager.

这是一个片段,说明了您可以使其工作的非常基本的方法(需要重构代码以正确分离各个方面)

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestHeavyweightLightweight {

    public class MyLayoutManager implements LayoutManager2 {

        private Map<Component, Rectangle> constraints = new LinkedHashMap<Component, Rectangle>();

        @Override
        public void addLayoutComponent(String name, Component comp) {
            constraints.put(comp, comp.getBounds());
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            constraints.remove(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            Rectangle rect = new Rectangle();
            for (Rectangle r : constraints.values()) {
                rect = rect.union(r);
            }
            return rect.getSize();
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return preferredLayoutSize(parent);
        }

        @Override
        public void layoutContainer(Container parent) {
            for (Map.Entry<Component, Rectangle> e : constraints.entrySet()) {
                e.getKey().setBounds(e.getValue());
            }
        }

        @Override
        public void addLayoutComponent(Component comp, Object constraints) {
            if (constraints instanceof Rectangle) {
                this.constraints.put(comp, (Rectangle) constraints);
            } else {
                addLayoutComponent((String) null, comp);
            }
        }

        @Override
        public Dimension maximumLayoutSize(Container target) {
            return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
        }

        @Override
        public float getLayoutAlignmentX(Container target) {
            return 0;
        }

        @Override
        public float getLayoutAlignmentY(Container target) {
            return 0;
        }

        @Override
        public void invalidateLayout(Container target) {

        }

        public void setConstraints(Component component, Rectangle rect) {
            constraints.put(component, rect);
        }

        public class MouseDragger extends MouseAdapter {
            private Point lastLocation;
            private Component draggedComponent;

            @Override
            public void mousePressed(MouseEvent e) {
                draggedComponent = e.getComponent();
                lastLocation = SwingUtilities.convertPoint(draggedComponent, e.getPoint(), draggedComponent.getParent());
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                Point location = SwingUtilities.convertPoint(draggedComponent, e.getPoint(), draggedComponent.getParent());
                if (draggedComponent.getParent().getBounds().contains(location)) {
                    Point newLocation = draggedComponent.getLocation();
                    newLocation.translate(location.x - lastLocation.x, location.y - lastLocation.y);
                    newLocation.x = Math.max(newLocation.x, 0);
                    newLocation.x = Math.min(newLocation.x, draggedComponent.getParent().getWidth() - draggedComponent.getWidth());
                    newLocation.y = Math.max(newLocation.y, 0);
                    newLocation.y = Math.min(newLocation.y, draggedComponent.getParent().getHeight() - draggedComponent.getHeight());
                    setConstraints(draggedComponent, new Rectangle(newLocation, draggedComponent.getSize()));
                    if (draggedComponent.getParent() instanceof JComponent) {
                        ((JComponent) draggedComponent.getParent()).revalidate();
                    } else {
                        draggedComponent.getParent().invalidate();
                        draggedComponent.getParent().validate();
                    }
                    lastLocation = location;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                lastLocation = null;
                draggedComponent = null;
            }

            public void makeDraggable(Component component) {
                component.addMouseListener(this);
                component.addMouseMotionListener(this);
            }

        }

    }

    private Canvas canvas;
    private JPanel panel;

    protected void createAndShowGUI() {
        JFrame frame = new JFrame(TestHeavyweightLightweight.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvas = new Canvas();
        canvas.setBackground(Color.WHITE);
        panel = new JPanel();
        MyLayoutManager mgr = new MyLayoutManager();
        panel.setLayout(mgr);
        panel.add(canvas, new Rectangle(20, 40, 300, 300));
        MyLayoutManager.MouseDragger mouseDragger = mgr.new MouseDragger();
        mouseDragger.makeDraggable(canvas);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

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

}
于 2013-03-21T11:55:23.567 回答