-2

我有两个点,我画一条线,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 布局是免费设计的

4

1 回答 1

1

几乎没有什么信息可以继续,而且您可能遇到问题的原因有很多。

以下是我如何解决您的问题的简单示例。注意-我个人不喜欢null布局,它们对 Swing 的内部工作方式造成了很大的困扰,并且往往会产生比它们解决的更多的问题。相反,当我想取消布局管理器时,我使用 aJLayeredPane代替。

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 的其余部分,阻止它更新屏幕,直到您退出该方法。

查看Swing 中的并发以获取更多详细信息。

我还将仔细研究如何使用 Swing TimersSwing Worker来获得一些解决方案。

于 2013-02-08T23:02:50.747 回答