[英]New to java can't figure out how to use paint method
I am trying to learn the paint method and get a ball to move across the frame. 我正在尝试学习绘画方法,并使球在框架上移动。 here is my code so far.
到目前为止,这是我的代码。 w=.
w =。
I currently have two classes One is the main and one for the ball. 我目前有两个班级,一个是主班,一个是球班。
this is the main class import java.awt. 这是导入java.awt的主要类。 ;
; import javax.swing.
导入javax.swing。 ;
;
public class PaintTest extends JPanel {
int x = 0;
int y = 0;
public void moveBall(){
x = x + 1;
y = y + 1;
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Ball ball = new Ball(x,y);
while(true){
ball.moveBall();
repaint();
}
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.magenta);
g.drawLine(0,100,500,100);
g.drawLine(0,101,500,101);
g.drawLine(0,102,500,102);
g.drawLine(0,103,500,103);
g2.fillOval(x,y,35,35);
}
}
and here is the ball class 这是球课
public class Ball {
int x,y;
public Ball(int x, int y){
this.x = x;
this.y = y;
}
}
now when i compile I get an error saying cannot find symbol ball in class PaintTest even though I am calling it from the class Ball. 现在,当我进行编译时,出现错误消息,即使我从Ball类调用它也无法在PaintTest类中找到符号ball。 I am aware of the repaint error as i do not know what to put in front of it.
我知道重画错误,因为我不知道在它前面放什么。
paintComponent
method not in its paint method -- this gives you double buffering. paintComponent
方法中而不是在其paint方法中—这为您提供了双重缓冲。 while (true)
loop as this can cause serious Swing threading issues. while (true)
循环,因为这可能会导致严重的Swing线程问题。 Use a Swing Timer instead. repaint()
. repaint()
。 This will tell Swing to repaint the component which will re-draw the oval in the new location. For example: 例如:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class PaintTest extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final int TIMER_DELAY = 20;
private static final Stroke STROKE = new BasicStroke(5f);
private int x;
private int y;
public PaintTest() {
new Timer(TIMER_DELAY, new TimerListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// to smooth graphics
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.magenta);
Stroke initialStroke = g2.getStroke();
g2.setStroke(STROKE);
g.drawLine(0, 100, 500, 100);
g2.setStroke(initialStroke);
g2.fillOval(x, y, 35, 35);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
x++;
y++;
repaint();
}
}
private static void createAndShowGui() {
PaintTest mainPanel = new PaintTest();
JFrame frame = new JFrame("PaintTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You have to put the paintComponent
method in a JPanel. 您必须将
paintComponent
方法放入JPanel中。 You can do it by using something like this. 您可以使用类似的方法来做到这一点。
JPanel panel = new JPanel(){
@Overide
public void paintComponent(Graphics g){
super.paint();
// Draw Stuff Here
}
};
The reason you are not getting the ball to move across the frame is that you are not calling the repaint method. 您没有使球在框架上移动的原因是您没有调用repaint方法。 You should do so on a thread.
您应该在线程上执行此操作。
Thread th = new Thread(new Runnable(){
@Overide
public void run(){
while(frame.isVisible()){
ball.moveBall();
panel.repaint();
try{Thread.sleep(5);}catch(Exception e){e.printStackTrace();}
}
}
});
Also, why are you making ball a instance of the PaintTest class? 另外,为什么要使ball成为PaintTest类的实例? To get only one frame and ball you would want to add a class named
Ball
and use that to make an instance: 要只获得一个框架和球,您需要添加一个名为
Ball
的类,并使用该类创建一个实例:
public class Ball{
int x, y;
public Ball(int x, int y){
this.x = x;
this.y = y;
}
}
That is why you were getting 2 frames. 这就是为什么要获得2帧的原因。
Then you would want to get rid of the x and y variables in the main class. 然后,您将希望摆脱主类中的x和y变量。 To make an instance using this class you would do:
要使用此类创建实例,您可以执行以下操作:
Ball ball = new Ball(x, y);
Then to paint the ball in the paintComponent
method you would do: 然后在
paintComponent
方法中绘制球:
g.fillOval(ball.x, ball.y, 35, 35);
repaint();
repaint();
method. y + 1
part. y + 1
部分。 while(true)
loop, you should use a for
loop. while(true)
循环,而应该使用for
循环。 super.paint()
method. super.paint()
方法。 Thread.sleep()
, which made the ball move across instantaneously. Thread.sleep()
,它使球瞬间移动。 Here is the code: 这是代码:
import java.awt.*;
import javax.swing.*;
public class PaintTest extends JFrame {
int x = 8;
int y = 30;
public void moveBall(){
x = x + 1;
//y = y + 1;
try{
Thread.sleep(500);
} catch(InterruptedException e){
}
repaint();
}
public static void main(String[] args){
PaintTest frame1 = new PaintTest();
PaintTest ball = new PaintTest();
for(int i = 0; i<100; i++){
//while(true){
ball.moveBall();
}
}
public PaintTest() {
super("Paint Test");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
super.paint(g);
super.paint(g2);
g.setColor(Color.magenta);
g.drawLine(0,100,500,100);
g.drawLine(0,101,500,101);
g.drawLine(0,102,500,102);
g.drawLine(0,103,500,103);
g.fillOval(x,y,35,35);
}
}
This code will make the ball move across the screen VERY slowly. 此代码将使球非常缓慢地在屏幕上移动。 If you want to speed it up, change the number of miliseconds in the
Thread.sleep(miliseconds)
part to a smaller number of miliseconds. 如果要加快速度,请将
Thread.sleep(miliseconds)
部分中的毫秒数更改为较小的毫秒数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.