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 < 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(); } }
Advertisement
Answer
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 = "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 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
.