簡體   English   中英

在Jpanel上畫一個可移動的畫布

[英]draw a movable canvas on Jpanel

我想畫一塊可以在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來使用畫布。

您不想擴展JPanel的事實似乎很奇怪,但這並非不可行。 但是,由於混合了輕量級組件和重量級組件,因此您有時可能會遇到問題。 您可能會遇到視覺故障和其他顯示問題。

但是,我會提醒您注意您在當前代碼中犯的幾個重要錯誤:

  1. 如果不需要,不要擴展類(不需要擴展JFrameCanvas
  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();
            }
        });
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM