[英]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
的事實似乎很奇怪,但這並非不可行。 但是,由於混合了輕量級組件和重量級組件,因此您有時可能會遇到問題。 您可能會遇到視覺故障和其他顯示問題。
但是,我會提醒您注意您在當前代碼中犯的幾個重要錯誤:
JFrame
或Canvas
) static
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.