-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ん or 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 に答える