[英]How do I force a repaint in Java using Swing JPanel?
為什么不為簡單的動畫重新繪制圖像? 我從兩種不同的方法調用repaint(),一種導致重新繪制,而另一種則沒有。 確實重繪的方法是從事件偵聽器生成的。 沒有的是定時動畫線程。 我知道動畫線程正在正確運行,並且只要我不斷滑動滑塊,它就可以完美顯示。 請幫助!
PS:是的,我在這里看到了許多類似的問題,並且嘗試了驗證,重新驗證以及使用paint vs paintComponent。 組成代碼的四個類如下:
import javax.swing.*;
public class gutz{
public static int windowWidth = 640;
public static int windowHeight = 480;
public static void main(String[] args){
hBod hb1 = new hBod(50, 30, 21, 111, 7, -11); //mass, radius, xpos, ypos, xvel, yvel
Thread t1 = new Thread(hb1);
windowmakr w = new windowmakr();
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
w.setSize(windowWidth, windowHeight);
w.setVisible(true);
t1.start();
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class windowmakr extends JFrame {
private JSlider slider;
private drawr panel;
public windowmakr(){
super("Orbit Explorer");
panel = new drawr();
panel.setBackground(Color.BLACK);
slider = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 10);
slider.setMajorTickSpacing(10);
slider.setPaintTicks(true);
slider.addChangeListener(
new ChangeListener(){
public void stateChanged(ChangeEvent e){
panel.setSpeed(slider.getValue());
}
}
);
add(slider, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
}
}
import java.awt.*;
import javax.swing.*;
public class drawr extends JPanel{
private int diameter = 10;
private static int rad;
private static int xpos;
private static int ypos;
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.ORANGE);
g.fillOval((gutz.windowWidth-diameter)/2, ((gutz.windowHeight-diameter)/2)-40, diameter, diameter);
g.setColor(Color.CYAN);
g.fillOval(xpos, ypos, rad, rad);
}
/* public void paint(Graphics g){
super.paint(g);
g.setColor(Color.ORANGE);
g.fillOval((gutz.windowWidth-diameter)/2, ((gutz.windowHeight-diameter)/2)-40, diameter, diameter);
g.setColor(Color.CYAN);
g.fillOval(xpos, ypos, rad, rad);
}
*/
public void setSpeed(int newD){
diameter = (newD >= 0 ? newD : 10);
repaint();
}
public void renderImage(int r, int xp, int yp){
rad=r;
xpos=xp;
ypos=yp;
repaint();
}
public Dimension getPreferredSize(){
return new Dimension(200,200);
}
public Dimension getMinimumSize(){
return getPreferredSize();
}
}
public class hBod implements Runnable{
private int mass;
private int rad;
private int xpos;
private int ypos;
private double xvel;
private double yvel;
public drawr render;
public hBod(int m, int r, int xp, int yp, double xv, double yv){
mass=m;
rad=r;
xpos=xp;
ypos=yp;
xvel=xv;
yvel=yv;
render = new drawr();
}
public void run(){
try{
while(true){
xpos+=xvel;
ypos+=yvel;
yvel+=1;
System.out.printf("rad - %d, xpos - %d, ypos - %d\n", rad, xpos, ypos);
render.renderImage(rad, xpos, ypos);
Thread.sleep(1000);
}
}catch(Exception e){}
}
}
就像我之前說的,問題出在這一行render = new drawr();
在hBod
構造函數中。 在gutz
類中創建一個像private drawr panel = new drawr()
的gutz
,然后使用其構造函數將其傳遞給其他兩個類,例如hBod hb1 = new hBod(50, 30, 21, 111, 7, -11, panel)
和windowmakr w = new windowmakr(panel)
和簡單地使用該引用指向panel.renderImage(...)
內hBod
類和panel.setSpeed(...)
從windowmakr
類。
這是修改后的代碼,請學習Java編碼約定:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class Gutz {
public static int windowWidth = 640;
public static int windowHeight = 480;
public static void main(String[] args){
Drawr panel = new Drawr();
panel.setBackground(Color.BLACK);
HBod hb1 = new HBod(50, 30, 21, 111, 7, -11, panel); //mass, radius, xpos, ypos, xvel, yvel
Thread t1 = new Thread(hb1);
WindowMakr w = new WindowMakr(panel);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
w.setSize(windowWidth, windowHeight);
w.setVisible(true);
t1.start();
}
}
class WindowMakr extends JFrame {
private JSlider slider;
private Drawr panel;
public WindowMakr(Drawr p){
super("Orbit Explorer");
final Drawr panel = p;
slider = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 10);
slider.setMajorTickSpacing(10);
slider.setPaintTicks(true);
slider.addChangeListener(
new ChangeListener(){
public void stateChanged(ChangeEvent e){
panel.setSpeed(slider.getValue());
}
}
);
add(slider, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
}
}
class Drawr extends JPanel{
private int diameter = 10;
private static int rad;
private static int xpos;
private static int ypos;
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.ORANGE);
g.fillOval((Gutz.windowWidth-diameter)/2, ((Gutz.windowHeight-diameter)/2)-40, diameter, diameter);
g.setColor(Color.CYAN);
g.fillOval(xpos, ypos, rad, rad);
}
public void setSpeed(int newD){
diameter = (newD >= 0 ? newD : 10);
repaint();
}
public void renderImage(int r, int xp, int yp){
rad=r;
xpos=xp;
ypos=yp;
repaint();
}
public Dimension getPreferredSize(){
return new Dimension(200,200);
}
public Dimension getMinimumSize(){
return getPreferredSize();
}
}
class HBod implements Runnable{
private int mass;
private int rad;
private int xpos;
private int ypos;
private double xvel;
private double yvel;
public Drawr render;
public HBod(int m, int r, int xp, int yp, double xv, double yv, Drawr panel){
mass=m;
rad=r;
xpos=xp;
ypos=yp;
xvel=xv;
yvel=yv;
render = panel;
}
public void run(){
try{
while(true){
xpos+=xvel;
ypos+=yvel;
yvel+=1;
System.out.printf("rad - %d, xpos - %d, ypos - %d\n", rad, xpos, ypos);
render.renderImage(rad, xpos, ypos);
Thread.sleep(1000);
}
}catch(Exception e){}
}
}
您可以在JFrame類中使用getContentPane()。repaint()方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.