如何在两点之间移动jlabel?

时间:2013-02-08 22:48:02

标签: java multithreading graphics jlabel setbounds

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

 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 个答案:

答案 0 :(得分: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());
}

意味着您已停止EDT将任何所需的更新事件发送到UI的其余部分,从而阻止其更新屏幕,直到您退出该方法。

请查看Concurrency in Swing了解详情。

我还会仔细查看How to use Swing TimersSwing Worker的解决方案。