小编典典

在Java中移动椭圆形

java

我做了一个绘制椭圆并相互链接的迷你代码,现在我尝试移动椭圆(圆),但是我在编码时遇到了问题

// Panneau.java
public class Panneau extends JPanel {
    private int R = 20;
    private boolean isDrag = false;
    String text = "stack";
    int x = 250, y = 200;
    int height = 50, width = 50;
    Random Rnd = new Random();
    int rand=Rnd.nextInt();
    int r=Math.abs(rand%250);
    int r2=Math.abs(rand%250);
    public Panneau() {
        addMouseListener(new MouseAdapter() {
            @Override
           public void mousePressed(MouseEvent e) {
                if ((x<=e.getX() && x+R>=e.getX()) && ( y<=e.getY() && y+R>=e.getY())) {
                    moveVertex(e.getX(),e.getY());
                    isDrag = true;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                isDrag = false;
            }
        });

        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (isDrag) moveVertex(e.getX(),e.getY());
            }
        });
    }

    private void moveVertex(int x1, int y1) {
        if ((x!=x1) || (y!=y1)) {
            x=x1-10;
            y=y1-10;
            repaint();
        }
    }

    @Override
    protected void paintComponent(Graphics g){
        // declaration
        super.paintComponent(g);
        g.setColor(Color.black);
        g.drawLine(x,y,x+r,y+r2);
        g.setColor(Color.yellow);
        g.fillOval(x-height/2, y-width/2,width, height);
        g.fillOval((x-height/2)+r, (y-width/2)+r2,width, height);
        FontMetrics fm = g.getFontMetrics();
        double textWidth = fm.getStringBounds(text, g).getWidth();
        g.setColor(Color.blue);
        g.drawString(text, (int) (x - textWidth/2),(int) (y + fm.getMaxAscent() / 2));
        g.drawString(text, (int) (x - textWidth/2)+r,(int) (y + fm.getMaxAscent() / 2)+r2);
    }


}

移动两个圆圈,并且直线一定不能移动(Graph节点),请帮帮我,谢谢:)更新后(感谢MadProgrammer),现在我可以移动所有
图形了


阅读 304

收藏
2020-09-28

共1个答案

小编典典

基本上,因为reapint(int, int)可以使用而不是使用repaint()

private void moveVertex(int x1, int y1) {
    int OFFSET = 1;
    if ((x != x1) || (y != y1)) {
        x = x1 - 10;
        y = y1 - 10;
        repaint();
    }
}

这将确保整个组件被重新粉刷。

虽然我不反对使用repaint(int, int),因为您的绘画过程相对简单,但是在现阶段它不会为您带来很多好处

更新了其他示例

如果我理解,您希望能够移动单个节点并使该
行保持连接状态。

虽然可以在可用的代码中实现,但更简单的解决方法是利用2D Graphics ShapeAPI,这提供了许多真正有用的功能,包括确定点是否位于给定的形状内。

这也意味着您无需跟踪大量参数,而是获得一个自包含的对象,该对象只知道应如何绘制…

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestGraphNode {

    public static void main(String[] args) {
        new TestGraphNode();
    }

    public TestGraphNode() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Panneau());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Panneau extends JPanel {

        private int radius = 50;
        private String text = "stack";

        private List<Ellipse2D> nodes;

        private Ellipse2D dragged;
        private Point offset;

        public Panneau() {
            nodes = new ArrayList<>(25);

            nodes.add(new Ellipse2D.Float(50 - (radius / 2), 100 - (radius / 2), radius, radius));
            nodes.add(new Ellipse2D.Float(350 - (radius / 2), 100 - (radius / 2), radius, radius));

            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {

                    for (Ellipse2D node : nodes) {

                        if (node.contains(e.getPoint())) {

                            System.out.println("Clicked...");
                            dragged = node;
                            // Adjust for the different between the top/left corner of the
                            // node and the point it was clicked...
                            offset = new Point(node.getBounds().x - e.getX(), node.getBounds().y - e.getY());
                            // Highlight the clicked node
                            repaint();
                            break;

                        }

                    }

                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    // Erase the "click" highlight
                    if (dragged != null) {
                        repaint();
                    }
                    dragged = null;
                    offset = null;
                }
            });

            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    if (dragged != null && offset != null) {
                        // Adjust the position of the drag point to allow for the
                        // click point offset
                        Point to = e.getPoint();
                        to.x += offset.x;
                        to.y += offset.y;

                        // Modify the position of the node...
                        Rectangle bounds = dragged.getBounds();
                        bounds.setLocation(to);
                        dragged.setFrame(bounds);

                        // repaint...
                        repaint();
                    }

                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            // declaration
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            // Draw the connecting lines first
            // This ensures that the lines are under the nodes...
            Point p = null;
            for (Ellipse2D node : nodes) {

                g2d.setColor(Color.BLACK);
                Point to = node.getBounds().getLocation();
                to.x += radius / 2;
                to.y += radius / 2;
                if (p != null) {
                    g2d.draw(new Line2D.Float(p, to));
                }
                p = to;

            }
            // Draw the nodes...
            for (Ellipse2D node : nodes) {

                g2d.setColor(Color.yellow);
                g2d.fill(node);
                if (node == dragged) {
                    g2d.setColor(Color.BLUE);
                    g2d.draw(node);
                }
                g2d.setColor(Color.BLUE);

                FontMetrics fm = g.getFontMetrics();
                int textWidth = fm.stringWidth(text);
                int x = node.getBounds().x;
                int y = node.getBounds().y;
                int width = node.getBounds().width;
                int height = node.getBounds().height;
                g.drawString(text,
                                x + ((width - textWidth)) / 2,
                                y + ((height - fm.getHeight()) / 2) + fm.getAscent());

            }

            g2d.dispose();

        }

    }
}
2020-09-28