使用SwingWorker移动组件

时间:2016-01-17 23:05:39

标签: java swing position swingworker

我目前正试图让JLabel使用SwingWorker.在屏幕上移动我可以让JLabel更新SwingWoker中的文字但我无法改变它的立场。

以下是我目前正在尝试的内容

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class MainFrame
{
    public MainFrame()
    {
        addComponents();
    }

    public void addComponents()
    {
        JFrame mainFrame = new JFrame("Some Frame");
        JLabel enemyLabel = new JLabel("Enemy");
        mainFrame.add(enemyLabel);

        moveEnemies(enemyLabel, mainFrame);

        mainFrame.setLocationRelativeTo(null);
        mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrame.pack();
        mainFrame.setVisible(true);
    }

    public void moveEnemies(JLabel label, JFrame frame)
    {
        SwingWorker<Void, Integer> enemyMover = new SwingWorker<Void, Integer>()
        {
            @Override
            protected Void doInBackground() throws Exception
            {
                for (int i = 0; i <= 5; i++)
                {
                    int x = 50 * i;
                    Thread.sleep(1000);
                    publish(x);
                }

                return null;
            }

            @Override
            protected void process(List<Integer> chunks)
            {
                label.setSize(50, 50);
                for(int num : chunks)
                {
                    label.setText(String.valueOf(num));
                    label.setLocation(num, 250);
                }
            }

            @Override
            protected void done()
            {
                label.setText("Finished");
            }
        };
        enemyMover.execute();
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(MainFrame::new);
    }
}

我还打印了JLabel.getLocation()并在循环结束时打印了预期位置[250,250],但屏幕上的位置没有变化。我也试过revalidate(),&amp; repaint()但似乎都不起作用。

1 个答案:

答案 0 :(得分:3)

您正在与框架的默认布局管理器(BorderLayout)进行斗争,这非常希望将标签保持在其认为应该的位置。

查看Laying Out Components Within a Container

To&#34; fix&#34; &#34;立即&#34;问题,你&#34;可能&#34;将框架的布局管理器设置为null,但这会打开一堆非常恶毒和令人讨厌的蠕虫。更好的解决方案是以这种方式停止使用组件,并使用自定义绘制在组件中呈现文本。

请查看Painting in AWT and SwingPerforming Custom Painting2D Graphics了解详情。

虽然可以使用Swing组件做一些有趣的动画,但还有很多需要考虑的因素。如果您只是创建某种游戏,那么使用基于自定义绘画的方法会更好