【问题标题】:Move an Oval in java在java中移动椭圆
【发布时间】:2014-01-14 14:07:18
【问题描述】:

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

// 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);
    }


}

我必须移动两个圆圈并且线不能移动(图形节点) 请帮助我,谢谢:) 更新后(感谢 MadProgrammer)现在我可以移动所有图形(但如果我只点击红色圆圈),我只想移动圆圈谢谢 :)

【问题讨论】:

    标签: java swing awt paintcomponent mouselistener


    【解决方案1】:

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

    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 Shape API,这提供了许多真正有用的功能,包括确定点落在给定的形状内。

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

    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();
    
            }
    
        }
    }
    

    【讨论】:

    • 我将 repaint(int,int) 更改为现在重新绘制所有图形移动而不是圆圈:x
    • 我已经更新了答案。我做的测试,我有两个节点,线和文本移动......
    • 是的,谢谢你的代码和解释,但我只想移动两个圆圈,这可以用我的代码吗?
    • 你是什么意思?你不想移动线条和文本吗?你想同时移动两个圆圈吗?
    • 非常感谢您的回答这就是我想要的(移动圆圈)再次感谢您! :)
    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 2018-03-10
    • 2015-07-28
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    相关资源
    最近更新 更多