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
.