Java 是否可以使图形对象成为内部循环的最终对象?
如果我的图形对象是最终的,就像错误所说的那样,我将永远无法更改它。在我的计时器循环中使用变量之前,我一直在阅读关于将变量分配给最终变量的内容,以便绕过这个问题,但我甚至不知道如何开始处理图形对象。是否需要将最终图形对象复制回普通图形对象?下面是一些代码Java 是否可以使图形对象成为内部循环的最终对象?,java,graphics,error-handling,timer,2d,Java,Graphics,Error Handling,Timer,2d,如果我的图形对象是最终的,就像错误所说的那样,我将永远无法更改它。在我的计时器循环中使用变量之前,我一直在阅读关于将变量分配给最终变量的内容,以便绕过这个问题,但我甚至不知道如何开始处理图形对象。是否需要将最终图形对象复制回普通图形对象?下面是一些代码 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import ja
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.util.ArrayList;
public class Test extends JPanel{
abstract class graphic {
public Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public int[] location = new int[] {screenSize.width/2,screenSize.height/2};
}
public class gladiator extends graphic {
void draw(Graphics g) {
g.setColor(Color.green);
g.fillArc(location[0], location[1], 100, 100, 45, 90);
g.setColor(Color.black);
g.fillArc((location[0]+50-10),(location[1]+50-10), 20, 20, 0, 360);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
gladiator[] gladiator = new gladiator[2];
ArrayList<gladiator> gladiatorList = new ArrayList<gladiator>();
for (int a =0; a < 2; a++) {
final gladiator[a] = new gladiator();
final gladiatorList.add(gladiator[a]);
}
new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (int a = 0; a < gladiatorList.size(); a++) {
gladiator[a].draw(g);
}
repaint();
System.out.println("repainting");
}
}).start();
}
public void setLocation(int x, int y){
//this.location[0] = x;
//this.location[1] = y;
}
public static void main(String[] args){
JFrame jf=new JFrame();
jf.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
jf.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
jf.add(new Test());
jf.pack();
jf.setVisible(true);
}
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.Graphics2D;
导入java.awt.Graphics;
导入java.util.ArrayList;
公共类测试扩展了JPanel{
抽象类图形{
公共维度screenSize=Toolkit.getDefaultToolkit().getScreenSize();
public int[]location=new int[]{screenSize.width/2,screenSize.height/2};
}
公共级角斗士扩展图形{
虚线绘制(图形g){
g、 setColor(Color.green);
g、 填充弧(位置[0],位置[1],100,100,45,90);
g、 设置颜色(颜色为黑色);
g、 填充弧((位置[0]+50-10),(位置[1]+50-10),20,20,0,360);
}
}
@凌驾
受保护组件(图形g){
超级组件(g);
角斗士[]角斗士=新角斗士[2];
ArrayList gladiatorList=新ArrayList();
对于(int a=0;a<2;a++){
最后的角斗士[a]=新的角斗士();
最后的角斗士。添加(角斗士[a]);
}
新计时器(200,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
对于(int a=0;a
这是返回for循环中几乎所有行都应该是final的位
new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (int a = 0; a < gladiatorList.size(); a++) {
gladiator[a].draw(g);
}
repaint();
System.out.println("repainting");
}
}).start();
新定时器(200,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
对于(int a=0;a
谢谢 要在同一方法中定义的匿名类中使用局部变量,必须使局部变量为final 这不会阻止您修改引用变量指向的对象 在您的例子中,您的匿名类使用的是
g
、gladiator
和gladiatorList
。因此,将所有这些标记为最终:
protected void paintComponent( final Graphics g) {
...
final gladiator[] gladiator = new gladiator[2];
final ArrayList<gladiator> gladiatorList = new ArrayList<gladiator>();
受保护的组件(最终图形g){
...
最后的角斗士[]角斗士=新的角斗士[2];
最终ArrayList角斗士列表=新ArrayList();
要在同一方法中定义的匿名类中使用局部变量,必须将局部变量设置为final
这不会阻止您修改引用变量指向的对象
在您的情况下,您的匿名类使用的是g
、gladiator
和gladiatorList
。因此,请标记所有这些最终选项:
protected void paintComponent( final Graphics g) {
...
final gladiator[] gladiator = new gladiator[2];
final ArrayList<gladiator> gladiatorList = new ArrayList<gladiator>();
受保护的组件(最终图形g){
...
最后的角斗士[]角斗士=新的角斗士[2];
最终ArrayList角斗士列表=新ArrayList();
如果将变量设置为final,这意味着该变量将始终是对同一对象实例的引用。这并不意味着对象实例的内容无法更改。您不能为该变量指定新的引用,但可以对实例本身执行任何操作(调用可能修改其状态、读/写字段等的方法).如果将变量设置为final,则表示该变量始终是对同一对象实例的引用。这并不意味着无法更改对象实例的内容。您不能为该变量指定新的引用,但可以对实例本身执行任何操作(调用可能修改其状态、读取/写入字段等的方法。)您真的不应该在paintComponent
中使用计时器,只要操作系统想要绘制组件,它就会启动一个新的计时器。您只需将重新绘制sysout
更改为System.out.println(“重新绘制入:+这个);
关于图形
变量的最终性:
final Graphics2D g2d = (Graphics2D) g.create();
在计时器内使用g2d
编辑:
一个完整的例子:
public class ExampleAnimationOfMyStuff extends JPanel {
MovingRectangle[] rectangles = new MovingRectangle[20];
public ExampleAnimationOfMyStuff() {
for (int i = 0; i < rectangles.length; i++) {
rectangles[i] = new MovingRectangle();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Animated rectangles");
ExampleAnimationOfMyStuff anime = new ExampleAnimationOfMyStuff();
frame.getContentPane().add(anime);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
anime.animate();
frame.setVisible(true);
}
@Override
@Transient
public Dimension getPreferredSize() {
return new Dimension(1000, 1000);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (MovingRectangle rectangle : rectangles) {
g.setColor(rectangle.color);
g.fillRect(rectangle.x, rectangle.y, rectangle.width,
rectangle.height);
}
}
public void animate() {
new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (MovingRectangle rectangle : rectangles) {
rectangle.tick();
}
repaint();
System.out.println("repainting");
}
}).start();
}
public static class MovingRectangle extends Rectangle {
public static Random random = new Random();
int speedX, speedY;
Color color;
public void tick() {
if (getX() + speedX > 1000 || getX() + speedX < 0) {
speedX *= -1;
}
if (getY() + speedY > 1000 || getY() + speedY < 0) {
speedY *= -1;
}
setRect(getX() + speedX, getY() + speedY, getWidth(), getHeight());
}
public MovingRectangle() {
super(random.nextInt(1000), random.nextInt(1000), random
.nextInt(40), random.nextInt(40));
this.speedX = (random.nextDouble() > 0.5) ? 4 : -4;
this.speedY = (random.nextDouble() > 0.5) ? 4 : -4;
this.color = new Color(random.nextInt(256), random.nextInt(256),
random.nextInt(256));
}
}
}
public类示例animationofmystuff扩展了JPanel{
移动矩形[]矩形=新的移动矩形[20];
公共示例animationofmystuff(){
对于(int i=0;i