So, I'm currently working on making a ball that moves on keyboard command. My problem is that when I call repaint();
, it gives me an error saying that it "Cannot make a static reference to the non-static method repaint() from the type Component." What am I doing wrong?
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
public class App extends JFrame{
JFrame f = new JFrame();
public static int keyVal = 0, x = 10, y = 10;
public static void main(String[] args) {
new App();
Ball();
while(true){
System.out.println(keyVal);
try{
Thread.sleep(50);
}
catch(Exception e){}
}
}
public static void Ball(){
while(true){
if(keyVal == 65){
x = x -1;
}
else if(keyVal == 68){
x = x + 1;
}
repaint();
//repaint(x, y, 10, 20);
}
}
public App(){
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Pong");
f.setSize(30,40);
f.setLocationRelativeTo(null);
f.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e){
keyVal = e.getKeyCode();
}
public void keyReleased(KeyEvent e){
keyVal = 0;
}
public void keyTyped(KeyEvent e){}
});
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
class MyPanel extends JPanel {
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize() {
return new Dimension(500,200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("test");
g.setColor(Color.orange);
g.fillRect(x, y, 10, 20);
}
}
}
Your class is already a JFrame
subclass. There's no need to create another JFrame
. Take out the JFrame f = new JFrame()
and all the f.method(..)
just use method(..)
Don't use while(true)
or Thread.sleep()
. You will run into problem. Instead look into How to use a Swing Timer . Here is a simple example . You could also find many other examples just doing a simple google search on how to use Swing Timer
No need to setSize()
to the frame, you already pack()
it.
You should look into How to use Key Bindings . If not now, you will come to find that there are focus issues, among other things, with using a KeyListener
.
Run your program from the Event Dispatch Thead , like this
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { new App(); } }); }
Freebie
A simple implementation of a javax.swing.Timer
would be something like this
public App() {
...
Timer timer = new Timer(50, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// do something
}
});
}
Here is the basic construct of the Timer
Timer( int dalay, ActionListener listener )
The delay it the amount of milliseconds delayed for each time the event is fired. So in the above code, for every 50 milliseconds, something will happen. This will achieve what you are trying to do with the Thread.sleep
. You can call the repaint()
from inside the actionPerformed
Here's a simple refactor of your code, that you can test out
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class App extends JFrame {
private MyPanel panel = new MyPanel();
public static int keyVal = 0, x = 10, y = 10;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new App();
}
});
}
public App() {
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x = x + 5;
panel.repaint();
}
});
timer.start();
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Pong");
pack();
setLocationRelativeTo(null);
setVisible(true);
}
class MyPanel extends JPanel {
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize() {
return new Dimension(500, 200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("test");
g.setColor(Color.orange);
g.fillRect(x, y, 10, 20);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.