简体   繁体   English

获取单击jpanel的顶点的索引

[英]get the index of the vertices clicked on a jpanel

I want to create an app that display graphs and manipulate them like gephi. 我想创建一个显示图形并像gephi一样操作它们的应用程序。 I already write some classes , but I have a problem in an method. 我已经写了一些类,但是方法上有问题。 this method return the index of the node that i click on. 此方法返回我单击的节点的索引。 the method work but if i change vertices position (move) it don't work. 该方法有效,但是如果我更改顶点位置(移动),它将不起作用。

//get the id of the vertices but here I have a problem, if the vertices x,y changed I can't get the id anymore.
    public int getIndex(){
        int i2=-1;
    for(int i=0;i<Vnumber;i++)
    {

        if(gr.s.get(i).x==(dragged.getX()+(radius/2)) && gr.s.get(i).y==(dragged.getY()+(radius/2))){
           i2=i;
           break;}
        else if(cnd)
        if(gr.s.get(i).x==(location.getX()+(radius/2)) && gr.s.get(i).y==(location.getY()+(radius/2))){
          i2=i;
          break;}
}return i2;
    }  

this is my classes: Application.java package graph; 这是我的课程:Application.java包图;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JOptionPane;

public class Application extends javax.swing.JFrame
{
    boolean oval,zoom,cnd=false;            
    static int Vnumber;
    int rand;
    int radius;
    int id;
    Random r;
    Graph gr;
    ArrayList <Ellipse2D> nodes;
    private Ellipse2D dragged;
    private Point offset;
    Point location;
    public Application()
    {
        initComponents();
        gr=new Graph();
        nodes=new ArrayList<>();
        r=new Random();
        radius=40;
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        pan = new javax.swing.JPanel(){
            @Override
            protected void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                int i=0;
                if(oval){
                    DrawCircle(g,i);
                }
                if(zoom){
                    DrawCircle(g,i);
                }
            }
        };
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        unarr = new javax.swing.JButton();
        Vertices = new javax.swing.JToggleButton();
        slider = new javax.swing.JSlider();
        Edges = new javax.swing.JButton();
        unsom = new javax.swing.JButton();
        info = new javax.swing.JLabel();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        pan.setBackground(new java.awt.Color(255, 255, 255));
        pan.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        pan.setForeground(new java.awt.Color(255, 102, 102));
        pan.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                panMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                panMouseEntered(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                panMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                panMouseReleased(evt);
            }
        });
        pan.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                panComponentResized(evt);
            }
        });
        pan.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                panMouseDragged(evt);
            }
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                panMouseMoved(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setName(""); // NOI18N

        jLabel1.setForeground(new java.awt.Color(255, 0, 0));
        jLabel1.setText("Manuel");

        unarr.setText("One Edge");
        unarr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unarrActionPerformed(evt);
            }
        });

        Vertices.setText("Vertices");
        Vertices.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                VerticesActionPerformed(evt);
            }
        });

        slider.setMaximum(85);
        slider.setMinimum(20);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.setToolTipText("");
        slider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                sliderMouseDragged(evt);
            }
        });

        Edges.setText("Edges");

        unsom.setText("One Vertex");
        unsom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unsomActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(352, 352, 352))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(Vertices, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(unarr, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(Edges, javax.swing.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(unsom, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(193, 193, 193)))
                .addComponent(slider, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(unarr)
                    .addComponent(Vertices)
                    .addComponent(Edges)
                    .addComponent(unsom)))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(slider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        info.setText("...");

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(pan, javax.swing.GroupLayout.DEFAULT_SIZE, 568, Short.MAX_VALUE)
                        .addGap(143, 143, 143))
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(info)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pan, javax.swing.GroupLayout.PREFERRED_SIZE, 359, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(info, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void panMouseClicked(java.awt.event.MouseEvent evt)                                 
    {

    }                                

    void DrawCircle(Graphics g,int i)
{
     Graphics2D g2d = (Graphics2D) g.create();
     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(gr.s.get(i).str);
                int xx = node.getBounds().x;
                int yy = node.getBounds().y;
                int width = node.getBounds().width;
                int height = node.getBounds().height;

                g.drawString(gr.s.get(i).str,
                    xx + ((width - textWidth)) / 2,
                    yy + ((height - fm.getHeight()) / 2) + fm.getAscent());
                i++;
            }
             g2d.dispose();
}
    private void VerticesActionPerformed(java.awt.event.ActionEvent evt)                                         
    {
        if(Vertices==evt.getSource())
        {
            //bouton est cliqué
            oval=true; 

            //gestion exeption si Vnumber est un string ou Vnumber<0
            do{
            try
            {
                Vnumber=Integer.parseInt(JOptionPane.showInputDialog("Please Enter vertices number (>0):"));

            }
            catch(NumberFormatException e)
            {
                JOptionPane.showMessageDialog(this,"please enter a number !", "Erreur", JOptionPane.ERROR_MESSAGE);
                return;
            }
            }while(Vnumber<=0);

             //initialisation arraylist de sommet
             for(int i=0; i<Vnumber; i++)
                gr.s.add(i,new Vertices(pan.getWidth(),radius));

            //initialisation arraylist Ellipse2D (argument serot envoyé a g2d.fill ou autre)
            for(int i=0; i<Vnumber; i++)
                nodes.add(i,new Ellipse2D.Float(gr.s.get(i).x - (gr.s.get(i).radius / 2),gr.s.get(i).y - (gr.s.get(i).radius / 2),
                                              gr.s.get(i).radius, gr.s.get(i).radius));
            repaint();
            Vertices.setEnabled(false);
        }
    }                                        


//get the id of the vertices but here I have a problem, if the vertices x,y changed I can't get the id anymore.
    public int getIndex(){
        int i2=-1;
    for(int i=0;i<Vnumber;i++)
    {

        if(gr.s.get(i).x==(dragged.getX()+(radius/2)) && gr.s.get(i).y==(dragged.getY()+(radius/2))){
           i2=i;
           break;}
        else if(cnd)
        if(gr.s.get(i).x==(location.getX()+(radius/2)) && gr.s.get(i).y==(location.getY()+(radius/2))){
          i2=i;
          break;}
}return i2;
    }  

    private void panComponentResized(java.awt.event.ComponentEvent evt)                                     
    {

    }                                    

    private void panMouseReleased(java.awt.event.MouseEvent evt)                                  
    {

        if (dragged != null)
        {
            repaint(); 
        }
        dragged = null;
        offset = null;
         if(cnd){
             gr.s.get(id).x=(int)location.getX()+(gr.s.get(id).radius/2);
        gr.s.get(id).y=(int)location.getY()+(gr.s.get(id).radius/2);
       //nodes.set(id, new Ellipse2D.Float((int)location.getX()-(gr.s.get(id).radius/2),
        //(int)location.getY()-(gr.s.get(id).radius/2),gr.s.get(id).radius,gr.s.get(id).radius));
        }


    }                                 

    private void panMouseDragged(java.awt.event.MouseEvent evt)                                 
    {
        if (dragged != null && offset != null)
        {
            //adjust the click
            Point to = evt.getPoint();
            location=new Point(evt.getPoint());
          //new location of the vertex
            to.x += offset.x;
            to.y += offset.y;
            System.out.println("x="+to.x+"/y="+to.y);
            //change the position of the vertex
            Rectangle bounds = dragged.getBounds();
            cnd=true;
            //set location
            bounds.setLocation(to);
            dragged.setFrame(bounds);
            repaint();
        }
    }                                
    public boolean InsideVertices(java.awt.event.MouseEvent evt){
   for (Ellipse2D node : nodes)
        {

            if (node.contains(evt.getPoint()))
            {
                dragged = node; 

                //old location of vertex
                 //if(dragged.getX()+(gr.s.get(i).radius/2)==gr.s.get(i).x&&dragged.getY()+(gr.s.get(i).radius/2)==gr.s.get(i).y)
                offset = new Point(node.getBounds().x - evt.getX(), node.getBounds().y - evt.getY());  
                repaint();
                return true;
            } 
        }

   //for(int i=0;i<Vnumber;i++)
      // gr.s.set(i,new Vertices((int)location.getX(),(int)location.getY(),i));
   return false;
}

    private void panMousePressed(java.awt.event.MouseEvent evt)                                 
    { 
       System.out.println("x="+evt.getX()+"y="+evt.getY());

       if(InsideVertices( evt))

      {
          info.setText("you are inside vertices , the ID is  = "+getIndex());
          id=getIndex();
      }
      else
          info.setText("outside vertices!");
    }                                

    private void panMouseEntered(java.awt.event.MouseEvent evt)                                 
    {

    }                                

    private void panMouseMoved(java.awt.event.MouseEvent evt)                               
    {

    }                              


    private void sliderMouseDragged(java.awt.event.MouseEvent evt) {                                    
        if(slider==evt.getSource())
        {
            if(id>=0){
                gr.s.get(id).radius=slider.getValue();
                nodes.set(id,new Ellipse2D.Float(gr.s.get(id).x-(gr.s.get(id).radius/2),gr.s.get(id).y-(gr.s.get(id).radius/2)
                        ,slider.getValue(),slider.getValue()));
            }
            else
            {
                gr.s.get(id).radius=slider.getValue();
                nodes.set(id,new Ellipse2D.Float((int)location.getX(),(int)location.getY(),slider.getValue(),slider.getValue()));
            }
        }
        repaint();

    }                                   

    private void unsomActionPerformed(java.awt.event.ActionEvent evt) {                                      

    }                                     

    private void unarrActionPerformed(java.awt.event.ActionEvent evt) {                                      
        // TODO add your handling code here:
    }                                     

    public static void main(String args[])
    {

        try
        {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
            {
                if ("Nimbus".equals(info.getName()))
                {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch (ClassNotFoundException ex)
        {
            java.util.logging.Logger.getLogger(Application.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        catch (InstantiationException ex)
        {
            java.util.logging.Logger.getLogger(Application.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        catch (IllegalAccessException ex)
        {
            java.util.logging.Logger.getLogger(Application.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        catch (javax.swing.UnsupportedLookAndFeelException ex)
        {
            java.util.logging.Logger.getLogger(Application.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                new Application().setVisible(true);

            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton Edges;
    private javax.swing.JToggleButton Vertices;
    private javax.swing.JLabel info;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel pan;
    private javax.swing.JSlider slider;
    private javax.swing.JButton unarr;
    private javax.swing.JButton unsom;
    // End of variables declaration                   
}

Graph.java Graph.java

package graph;

import java.util.ArrayList;


public class Graph {
        ArrayList <Vertices> v;
        ArrayList <Edges> e;
        ArrayList <Boolean> matrix;

        Graph(){
            e=new ArrayList<>();
            v=new ArrayList<>();
            //allocation matrix
        }
        Graph( ArrayList <Vertices> ee, ArrayList <Edges> vv){
    e=new ArrayList<>(ee);
    v=new ArrayList<>(vv);
}
         Graph( ArrayList <Vertices> vv){
              v=new ArrayList<>(vv);
         }
}

Vertices.java Vertices.java

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
 */
package graph;

import java.util.ArrayList;

public class Vertices
{

    static int id = 0;
    int x;
    int y;
    String str;
    int radius;

    Vertices()
    {
        int Min=200;
        int Max=800;
        x= Min + (int)(Math.random() * ((Max - Min) + 1));
        y= Min + (int)(Math.random() * ((Max - Min) + 1));
        str= "S" + (id++);
        radius= 50;
    }
    Vertices(int w,int r)
    {

         int Min=20;
        int Max=w-100;
        x= Min + (int)(Math.random() * ((Max - Min) + 1));
        y= Min + (int)(Math.random() * ((Max - Min) + 1)); 
        str= "S" + (id++);
        radius= r;
    }
    Vertices(int x,int y,int i)
    {
         this.x=x;
         this.y=y;
         id=i;
         str="s"+id;

    }
//formule random : var= Min + (int)(Math.random() * ((Max - Min) + 1));
    Vertices(Vertices s)
    {
        x=s.x;
        y= s.y;
        str   = s.str;
       // radius = s.radius;
        id=(s.id)++;
    }
   void Reset()
   {
       id=0;

   }

} }

在此处输入图片说明

I think you forgot to update the position of the vertex after chaging it. 我认为您忘了在追赶顶点之后更新顶点的位置。 The Vertices.java doesn't contain a method for updating the postion, like a setter or something. Vertices.java不包含用于更新位置的方法,例如二传手或诸如此类。 If you try to access the class variables from another class via a getter you only get a copy of it's value, not the actual variable. 如果尝试通过getter访问另一个类的类变量,则只会得到其值的副本,而不是实际变量。

It's a bit hard to say where exactly the mistake is. 很难说出错误的确切位置。 Could you provide a minimal example? 您能提供一个简单的例子吗?

EDIT: 编辑:

Your variable names are horrible... primary in the Graph.java source code. 您的变量名太可怕了...是Graph.java源代码中的主要变量。

REDIT: 编辑:

if(cnd){
         gr.s.get(id).x=(int)location.getX()+(gr.s.get(id).radius/2);
         gr.s.get(id).y=(int)location.getY()+(gr.s.get(id).radius/2);
}

If i got the idea right, you try to get a point with a special id from the graph, but gr.s.get(id).x returns an integer by value and you are just overwriting it's value in the copy, not in the actual graph. 如果我的想法正确,则尝试从图形中获取具有特殊ID的点,但是gr.s.get(id).x将按值返回整数,而您只是在副本中覆盖其值,而不是实际图。 You need a getter for the point you want to change, afterwards change the value of the x and y variable. 您需要使用吸气剂来更改要更改的点,然后更改x和y变量的值。

By the way: A foreign language is no excuse for bad variable names. 顺便说一句:外语不是不好的变量名的借口。 These names could stand for literally anything. 这些名称实际上可以代表任何东西。 Also I can't figure out what gr.s should be... 我也不知道应该是什么gr.s ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM