Java移动GUI面板的While循环

huangapple go评论79阅读模式
英文:

Java move GUI panel While loop

问题

我有一个面板。我想在一个while循环内,在按下按钮后并且直到满足某个特定条件之前,将面板向左移动,然后向右移动。但是对于这个问题,让我们假设是连续移动的。在完成一次迭代后,它不会继续向左或向右移动。我使用了repaint()Thread.sleep(1000),但是没有显示任何内容。请帮助我。

while (true) {
    for (int i = 0; i < 5; i++) {
        jPanel1.setLocation(jPanel1.getLocation().x + 5, jPanel1.getLocation().y);
        i++;
        try {Thread.sleep(1000);} catch (InterruptedException ex) {}
        repaint();
    }

    for (int i = 0; i < 5; i++) {
        jPanel1.setLocation(jPanel1.getLocation().x - 5, jPanel1.getLocation().y);
        i++;
        try {Thread.sleep(1000);} catch (InterruptedException ex) {}
        repaint();
    }
}
英文:

I have a panel. I want to move the panel, inside a while loop, to the left and then to the right, after pressing a button and until a certain condition is met. But for this question let's say continuously. After it finishes an iteration, it doesn't move left or right. I used repaint() and Thread.sleep(1000) but nothing shows up. Please help me

while (true) {
    for (int i = 0; i &lt; 5; i++) {
        jPanel1.setLocation(jPanel1.getLocation().x + 5, jPanel1.getLocation().y);
        i++;
        try {Thread.sleep(1000);} catch (InterruptedException ex) {}
        repaint();
    }

    for (int i = 0; i &lt; 5; i++) {
        jPanel1.setLocation(jPanel1.getLocation().x - 5, jPanel1.getLocation().y);
        i++;
        try {Thread.sleep(1000);} catch (InterruptedException ex) {}
        repaint();
    }
}

答案1

得分: 0

我们再次相聚!

我成功地使用 Swing定时器 实现了移动的 JPanel

由于您想要移动 JPanel,您需要将其放置在一个足够大的父级 容器 中,以允许 JPanel 在其中的不同位置放置。您还需要使用一个空的 布局管理器,因为大多数布局管理器会忽略对 setLocation() 方法的调用。

以下是代码后的更多解释。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class MovePane implements ActionListener, Runnable {
    private static final String  START = "Start";
    private static final String  STOP = "Stop";

    private int  diff;
    private JButton  startButton;
    private JButton  stopButton;
    private JFrame  frame;
    private JPanel  jPanel1;
    private Timer  timer;

    public MovePane() {
        diff = 10;
    }

    @Override // jva.awt.event.ActionListener
    public void actionPerformed(ActionEvent event) {
        String actionCommand = event.getActionCommand();
        switch (actionCommand) {
            case START:
                launchTimer();
                break;
            case STOP:
                stopTimer();
                break;
            default:
                JOptionPane.showMessageDialog(frame,
                                              actionCommand,
                                              "Unhandled",
                                              JOptionPane.WARNING_MESSAGE);
        }
    }

    @Override // java.lang.Runnable
    public void run() {
        showGui();
    }

    private JButton createButton(String text, int mnemonic, String tooltip, boolean enabled) {
        JButton button = new JButton(text);
        button.setMnemonic(mnemonic);
        button.setToolTipText(tooltip);
        button.setEnabled(enabled);
        button.addActionListener(this);
        return button;
    }

    private JPanel createButtonsPanel() {
        JPanel buttonsPanel = new JPanel();
        startButton = createButton(START, KeyEvent.VK_M, "Sets panel in motion.", true);
        buttonsPanel.add(startButton);
        stopButton = createButton(STOP, KeyEvent.VK_P, "Stops panel motion.", false);
        buttonsPanel.add(stopButton);
        return buttonsPanel;
    }

    private JPanel createMainPanel() {
        JPanel mainPanel = new JPanel(null);
        mainPanel.setPreferredSize(new Dimension(400, 400));
        jPanel1 = new JPanel();
        jPanel1.setBounds(10, 200, 50, 50);
        jPanel1.setBorder(BorderFactory.createLineBorder(Color.RED, 2, true));
        mainPanel.add(jPanel1);
        return mainPanel;
    }

    private void launchTimer() {
        if (timer == null) {
            timer = new Timer(0, e -> movePanel());
            timer.setDelay(500);
        }
        timer.start();
        startButton.setEnabled(false);
        stopButton.setEnabled(true);
    }

    private void stopTimer() {
        timer.stop();
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
    }

    private void movePanel() {
        Point location = jPanel1.getLocation();
        if (location.x > 180) {
            diff = -10;
        }
        else if (location.x < 10) {
            diff = 10;
        }
        location.x += diff;
        jPanel1.setLocation(location);
    }

    private void showGui() {
        frame = new JFrame("Move");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new MovePane());
    }
}

Swing 是事件驱动的。事件被添加到队列中,然后从队列中读取并执行。设置 JPanel 的位置是一个事件。在循环中调用事件只会向队列中添加大量事件,有些可能会丢失。这就是为什么有 SwingTimer 类。在上面的代码中,我每隔半秒钟更改一次 jPanel1 的位置。

英文:

We meet again!

I managed to implement the moving JPanel using a Swing timer.

Since you want to move the JPanel, you need to place it in a parent container that is large enough to allow the JPanel to be placed in different locations within it. You also need to use a null layout manager because most layout managers will ignore calls to method setLocation().

More explanations after the code.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class MovePane implements ActionListener, Runnable {
    private static final String  START = &quot;Start&quot;;
    private static final String  STOP = &quot;Stop&quot;;

    private int  diff;
    private JButton  startButton;
    private JButton  stopButton;
    private JFrame  frame;
    private JPanel  jPanel1;
    private Timer  timer;

    public MovePane() {
        diff = 10;
    }

    @Override // jva.awt.event.ActionListener
    public void actionPerformed(ActionEvent event) {
        String actionCommand = event.getActionCommand();
        switch (actionCommand) {
            case START:
                launchTimer();
                break;
            case STOP:
                stopTimer();
                break;
            default:
                JOptionPane.showMessageDialog(frame,
                                              actionCommand,
                                              &quot;Unhandled&quot;,
                                              JOptionPane.WARNING_MESSAGE);
        }
    }

    @Override // java.lang.Runnable
    public void run() {
        showGui();
    }

    private JButton createButton(String text, int mnemonic, String tooltip, boolean enabled) {
        JButton button = new JButton(text);
        button.setMnemonic(mnemonic);
        button.setToolTipText(tooltip);
        button.setEnabled(enabled);
        button.addActionListener(this);
        return button;
    }

    private JPanel createButtonsPanel() {
        JPanel buttonsPanel = new JPanel();
        startButton = createButton(START, KeyEvent.VK_M, &quot;Sets panel in motion.&quot;, true);
        buttonsPanel.add(startButton);
        stopButton = createButton(STOP, KeyEvent.VK_P, &quot;Stops panel motion.&quot;, false);
        buttonsPanel.add(stopButton);
        return buttonsPanel;
    }

    private JPanel createMainPanel() {
        JPanel mainPanel = new JPanel(null);
        mainPanel.setPreferredSize(new Dimension(400, 400));
        jPanel1 = new JPanel();
        jPanel1.setBounds(10, 200, 50, 50);
        jPanel1.setBorder(BorderFactory.createLineBorder(Color.RED, 2, true));
        mainPanel.add(jPanel1);
        return mainPanel;
    }

    private void launchTimer() {
        if (timer == null) {
            timer = new Timer(0, e -&gt; movePanel());
            timer.setDelay(500);
        }
        timer.start();
        startButton.setEnabled(false);
        stopButton.setEnabled(true);
    }

    private void stopTimer() {
        timer.stop();
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
    }

    private void movePanel() {
        Point location = jPanel1.getLocation();
        if (location.x &gt; 180) {
            diff = -10;
        }
        else if (location.x &lt; 10) {
            diff = 10;
        }
        location.x += diff;
        jPanel1.setLocation(location);
    }

    private void showGui() {
        frame = new JFrame(&quot;Move&quot;);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new MovePane());
    }
}

Swing is event driven. Events are added to a queue and then read off the queue and performed. Setting the location of a JPanel is an event. Calling events in a loop just floods the queue with events and some may be lost. That's why there is the Swing Timer class. In the above code, every half second I change the location of jPanel1.

huangapple
  • 本文由 发表于 2020年9月25日 20:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64063791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定