2017-02-04 63 views
0

我比初学者对Java的理解稍微好一点,我在学生作业时遇到了问题。我不得不将一个类(student.java)“转换为一个按钮” - 这是我所做的(这就是为什么而不是创建一个JButton的新实例,我的代码创建了一个新的“student”实例)。我需要将按钮重新定位到用户点击鼠标的任何位置。我已经成功完成了这个任务,所以我的任务需求得到了满足。
但是,我想让按钮顺利移动到鼠标点击的位置,而不是突然从前一个位置跳到新位置。以下是我的代码。 mouseClicked()方法内部的数学是我尝试过的,但它对按钮的运动没有影响。顺利地将JButton组件移动到java中的鼠标单击位置

  • 空布局需要
  • 必须使用MouseListener的(不是的ActionListener)
  • 按钮必须是学生类的一个实例

任何提示将不胜感激。谢谢!

public myJPanel(){ 
    super(); 
    setLayout(null); 
    setBackground(Color.decode("#F5F2EB")); 
    setVisible(true); 
    setPreferredSize(new Dimension(640,480)); 
    setMinimumSize(new Dimension(640,480)); 
    setMaximumSize(new Dimension(640,480)); 
    Font f = new Font("Copperplate Gothic Bold", Font.BOLD, 16); 
    student btn = new student("First","Last", num, ""); 
    add(btn); 
    btn.setBounds(100, 150, 400, 90); 
    btn.setText(btn.getInfo()); 
    btn.setBackground(Color.decode("#89A690")); 
    btn.setForeground(Color.decode("#F5F2EB")); 
    btn.setOpaque(true); 
    btn.setFont(f); 
    btn.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40)); 

    // move btn object 
    addMouseListener(new MouseAdapter() { 
    public void mouseClicked(MouseEvent e) { 
     int x = e.getX(); //mouse click x position 
     int y = e.getY(); //mouse click y position 
     int px = btn.getX() - x; //previous btn x position(to get distance between old/new position) 
     int py = btn.getY() - y; //previous btn y position(to get distance between old/new position) 
     double speed = 5; //speed 
     double ang = (float)Math.atan2(py, px) * 180/Math.PI; //angle 
     x += Math.cos(ang * Math.PI/180) * speed; //move to x 
     y += Math.sin(ang * Math.PI/180) * speed; //move to y 
     btn.setLocation(x,y); //relocate button to new location 
    }}); 
+0

是什么你的“学生”按钮看起来像? – MadProgrammer

+0

它看起来像一个普通的JButton。 student.java扩展了JButton。所以当你创建一个新的学生实例时,它有上面的代码(btn.setBounds) – Tiff

回答

3

在代码中需要某种动画概念,只需更新位置就不会平滑移动。您需要

  • 删除setLocation()从小鼠听者代码更改
  • 定时器来触发的按钮位置计算和更新
  • 给定的经过时间的当前位置,角度等的内插

例。这里我计算了总距离,然后根据时间和速度插入了“迄今为止的距离”。

还要注意使用Math.toDegrees()和Math.toRadians(),虽然你并不真正需要它们在所有的,除非你想用昂其他地方度...

public class Foo { 
    private static class Animate extends JPanel { 
     private JButton btn; 
     private int startX; 
     private int startY; 
     private long startTime; 
     private double ang; 
     private double distance; 

     public Animate() { 
      super(); 
      setLayout(null); 
      btn = new JButton("Dr Horse"); 
      btn.setBounds(100, 150, 40, 10); 
      add(btn); 
      addMouseListener(new MouseAdapter() { 
       public void mouseClicked(MouseEvent e) { 
        startX = btn.getX(); 
        startY = btn.getY(); 
        startTime = System.nanoTime(); 
        int px = btn.getX() - e.getX(); 
        int py = btn.getY() - e.getY(); 
        distance = Math.sqrt(px * px + py * py); 
        ang = Math.toDegrees(Math.atan2(py, px)); 

       } 
      }); 
      Timer timer = new Timer(1000/20, new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        double duration = (System.nanoTime() - startTime)/1e6; 
        int speed = 50;// pixels per second 
        double distanceSoFar = Math.min(speed * duration/1000d, distance); 
        int x = startX - (int) (distanceSoFar * Math.cos(Math.toRadians(ang))); 
        int y = startY - (int) (distanceSoFar * Math.sin(Math.toRadians(ang))); 
        btn.setLocation(x, y); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.start(); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.getContentPane().add(new Animate()); 
     frame.setSize(500, 400); 
     frame.setVisible(true); 
    } 

} 
+0

注意到的btn尺寸啊!非常感谢你,亚当 - 这是完美的(它有效)。我试过使用Timer,但是当我收到错误信息,说明它必须连接到ActionListener时,我迷失了方向 - 但我需要使用MouseListener,因此感到困惑 - 现在我明白了。我向你投票赞成,但我是新用户,显然,它不会公开显示;)再次感谢您的帮助和快速响应! – Tiff

+0

不用担心,很高兴提供帮助,如果我的答案解决了您的问题,请点击灰色的勾号来考虑“接受”它。请参阅http://stackoverflow.com/help/someone-answers谢谢 – Adam

+0

完成。再次感谢! – Tiff

相关问题