获取在jpanel上单击的顶点的索引

时间:2014-02-14 18:22:36

标签: java swing graph

我想创建一个显示图形并像gephi一样操作它们的应用程序。 我已经编写了一些类,但是我在方法中遇到了问题。 此方法返回我单击的节点的索引。 该方法有效但如果我改变顶点位置(移动)它就不起作用。

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

这是我的课程: 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

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

/*
* 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;

   }

}

enter image description here

1 个答案:

答案 0 :(得分:0)

我认为忘记在查找顶点后更新顶点的位置。 Vertices.java不包含更新位置的方法,如setter或其他东西。如果你试图通过getter从另一个类访问类变量,你只能获得它的值的副本,而不是实际的变量。

有点难以确定错误的确切位置。你能提供一个最小的例子吗?

修改

你的变量名很糟糕......在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);
}

如果我有了正确的想法,你试图从图中得到一个带有特殊id的点,但gr.s.get(id).x按值返回一个整数,你只是覆盖它在副本中的值,而不是在实际图表中。您需要为要更改的点获取一个getter,然后更改x和y变量的值。

顺便说一下:外语不是坏变量名的借口。这些名字可以代表什么。另外我无法弄清楚gr.s应该是什么......