-2

私は2つのポイントを持っていてdrawline(x1,y1,x2,y2); 、このライン上のラベルを移動したい(この2つのポイントの間)で線を引きます。

 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 の内部がどのように機能するかをいじくり回し、解決するよりも多くの問題を引き起こす傾向があります。代わりに、レイアウト マネージャーを廃止したい場合は、JLayeredPane代わりに a を使用します。

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 での同時実行をご覧ください。

また、いくつかのソリューションについては、 How to use Swing TimersSwing Workerも詳しく見ていきます。

于 2013-02-08T23:02:50.747 に答える