Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
410 views
in Technique[技术] by (71.8m points)

swing - Move an Oval in java

I made a mini code that draw oval and link each other , now i try to move the oval(Circle) but I have a problem (in coding)

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


}

enter image description here I must move the two circles and the line must not move(Graph node) please help me and thanks :) After the update ( thanks to MadProgrammer) now I can move all the figure ( but if I clicked in the red circle only) , I want to move just circles thanks :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Basically, because instead of using reapint(int, int) you could use repaint()

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

This will ensure that the entire component is repainted.

While I wouldn't discount the use of repaint(int, int), because your painting process is relatively simple, it's not going to provide you with a great deal of benefit at this stage

Updated with additional example

IF I understand, you want to be able to move a single node and have the line remain joined.

While it might be possible to implement within the code you have available, a simpler soltution would be to take advantage of the 2D Graphics Shape API, this provides a number of really useful functions, including determining of points fall within a given shape.

It also means you don't need to keep track of a large number of parameters, but instead, get a self contained object that just knows how it should be painted...

enter image description here

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

        }

    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...