2013-02-08 56 views
-2

我有两点,我画了一条线drawline(x1,y1,x2,y2); 我想在这条线上移动一个标签(在这两点之间)。如何在两点之间移动jlabel?

m=y2-y1/x2-x1; 

if(x1<x2) 
    for (int i=x1;i<x2;i++) 
    { 
    label.setbound(i,y1+(x-i)*m,label.getwidth(),label.gethigh()); 
    } 
    else{ 
    for (int i=x1;i<x2;i--) 
    { 
    label.setbound(i,y1+(x-i)*m,label.getwidth(),label.gethigh()); 
    } 
    } 

我使用线程来移动。

//

我问这个问题,因为我正在写旅行商问题的代码,我想移动的东西的路线上,使用线程标签的改变位置。 例如:drawline(23, 65, 231,124);移动销售员就行了。

我的IDE是NetBeans和JPanel的布局设计无

+1

为什么和在哪里需要帮助?什么是问题(非编译代码除外)? – 2013-02-08 22:52:15

+1

标签是使用布局管理器连接到的容器吗?如果没有,你尝试重新绘制容器吗? – MadProgrammer 2013-02-08 22:52:56

+0

发布代码的一个问题是,在设置标签的位置后,您永远不会睡觉()。由于代码执行速度如此之快,它看起来就像是从一开始就一直移动到结束位置。 – camickr 2013-02-09 01:50:39

回答

1

有信息很少走,为什么你可能会碰到问题上和这么多的理由的。

下面是我如何解决您的问题的一个简单示例。请注意 - 我个人不喜欢null布局,他们与Swing的内部工作方式混淆很多,并倾向于产生更多的问题,然后他们解决。相反,当我想取消布局管理器时,我使用了JLayeredPane

public class BouncingLabel { 

    public static void main(String[] args) { 
     new BouncingLabel(); 
    } 

    public BouncingLabel() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JLayeredPane { 

     private JLabel label; 
     private Point p; 
     private int dv = 2; 

     public TestPane() { 
      p = new Point(); 
      label = new JLabel("Look Ma, no hands!"); 
      add(label); 

      Timer timer = new Timer(60, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        p.y = (getHeight() - label.getHeight())/2; 
        p.x = p.x + dv; 
        if (p.x + label.getWidth() > getWidth()) { 
         dv *= -1; 
         p.x = getWidth() - label.getWidth() + dv; 
        } else if (p.x < 0) { 
         dv *= -1; 
         p.x = 0 + dv; 
        } 
        label.setLocation(p); 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 100); 
     } 

     @Override 
     public void doLayout() { 
      super.doLayout(); 
      label.setSize(label.getPreferredSize()); 
      label.getLocation(p); 
     } 

    } 

} 

更新

在代码的仔细检查,你似乎是违反事件调度线程 - 没有阻止规则。所有UI更新都保存在单个线程(EDT)中,任何阻止此线程的操作都将阻止EDT将事件分派给所有组件,包括重新绘制请求。

做这样的事情..

for (int i=x1;i<x2;i++) 
{ 
    label.setbound(i,y1+(x-i)*m,label.getwidth(),label.gethigh()); 
} 

你从调度所需的任何更新事件UI的休息,防止它更新屏幕,直到退出方法停止EDT手段。

查看Concurrency in Swing了解更多详情。

对于某些解决方案,我还会仔细查看How to use Swing TimersSwing Worker

+0

+1,为定时器显示动画。不知道我是否理解了您关于使用JLayeredPane的意见,当您想要取消布局管理器时。 JLayeredPane确实使用“空布局”。 JLayeredPane被设计为包含许多专门的功能,这对于这个问题并不是必需的。所以我会保持简单,只需使用带有空布局的JPanel。 – camickr 2013-02-09 01:49:02

+0

@camickr你可能是对的,在使用空布局和JLayeredPane似乎工作的时候,我似乎有更新面板的问题...... – MadProgrammer 2013-02-09 02:13:42

+0

不知道为什么你会有问题。根据你发布的代码,唯一的区别是在构造函数的顶部添加一个setLayout(null)。我同意,通常在使用空布局时会出现问题,通常应避免使用空布局。我希望看到一个SSCCE,其中空布局分层窗格解决方案比空布局JPanel解决方案的效果更好。当然,我正在讨论在单个面板上使用组件,而不是多层面板。 – camickr 2013-02-09 02:41:00