我做了一个绘制椭圆并相互链接的迷你代码,现在我尝试移动椭圆(圆),但是我在编码时遇到了问题
// 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),现在我可以移动所有 图形了
基本上,因为reapint(int, int)可以使用而不是使用repaint()
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(); } } }