ОБНОВЛЕНИЕ : Как заметил Дмич, поскольку я рисую вне своего класса панели, это приводит к рекурсивным вызовам инициализации моего класса MyPanel и Animation. Итак, как я могу все еще выполнять рисование на MyPanel, в классе анимации, но без этой проблемы.
У меня очень специфическая проблема с моим кодом, и я не знаю, как описать происходящее, но я буду стараться изо всех сил. Я попытался выполнить поиск в stackOverFLow, но проблема в том, что я даже не знаю что искать.
Вот и я:
Чтобы организовать это как можно лучше, я сначала напишу все классы, с которыми имею дело.
public class MyPanel extends JPanel implements Runnable{
private Animation anim = new Animation();
}
public class Animation extends ??? implements KeyListener{}
Итак, у меня есть класс MyPanel, который расширяет JPanel. Я добавил этот класс в свой JFrame, используя
add(new MyPanel())
Я использую тему в MyPanel, которая вызывает
@Overrid public void paintComponent(Graphics g)
paintComponent вызывает метод в Animation, где я рисую изображение на экране g2d.drawImage(image, int, int, ImageObserver)
. Проблема в том, чтобы использовать этот метод, мне нужен ImageObserver, который я могу получить, если Animation расширяет JPanel. Но если я расширяю JPanel, на моем JFrame ничего не рисуется, потому что это новая jPanel, которая не добавляется в JFrame.
Но если я расширяю MyPanel (который добавлен в мой JFrame), я получаю целую кучу ошибок.
Ошибки затмения:
Exception in thread "main" java.lang.StackOverflowError
at java.awt.Component.setBackground(Unknown Source)
at javax.swing.JComponent.setBackground(Unknown Source)
at javax.swing.LookAndFeel.installColors(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
Под этим сообщением об ошибке эти 2 строки продолжаются до тех пор, пока не завершатся затмением.
at MyPanel.<init>(MyPanel.java:9)
at Animation.<init>(Animation.java:9)
Любая помощь будет принята с благодарностью.
ОБНОВЛЕНИЕ 2 Добавление примера кода в соответствии с предложением:
import javax.swing.JFrame;
public class Simulation extends JFrame {
private MyPanel panel = new MyPanel();
public Simulation() {
initUI();
}
private void initUI() {
add(panel);
setResizable(false);
pack();
setTitle("Simulation");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // centers
}
public static void main(String[] args) {
Simulation ex = new Simulation();
ex.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class MyPanel extends JPanel implements Runnable {
private Animation anim;
public MyPanel() {
anim = new Animation();
initPanel();
}
private void initPanel() {
//other customizables
}
@Override
public void run() {
//Thread that calls repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
anim.step(g2D, this);
}
}
import java.awt.Graphics2D;
public class Animation {
private Sprite player;
private KeyBinder kB;
public Animation() {
player = new Sprite();
kB = new KeyBinder(player);
}
public void step(Graphics2D g2d, JPanel p) {
player.move();
drawSprite(g2d, p);
}
private void drawSprite(Graphics2D g2d, JPanel p) {
g2d.drawImage(player.getImage(), player.getX(), player.getY(), p);
}
}
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class Sprite {
private final String PLAYER_IMAGE_FILE = "Image location";
private Image image;
private int width, height;
private int x, y, dx, dy;
public Sprite() {
x = 0;
y = 0;
loadImage();
}
private void loadImage() {
ImageIcon ii = new ImageIcon(PLAYER_IMAGE_FILE);
image = ii.getImage();
width = image.getWidth(null);
height = image.getHeight(null);
}
public void move() {
x += dx;
y += dy;
}
public void keyPressed(KeyEvent e) {
//assings meaning to keypressed
}
public void keyReleased(KeyEvent e) {
//assings meaning to keyReleased
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getW() {
return width;
}
public int getH() {
return height;
}
public Image getImage() {
return image;
}
}
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyBinder extends MyPanel implements KeyListener {
Sprite p;
public KeyBinder(Sprite player) {
p = player;
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
@Override
public void keyPressed(KeyEvent e) {
p.keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {
p.keyReleased(e);
}
@Override
public void keyTyped(KeyEvent e) {
}
}
Пытаясь отработать код, я внес изменения в свой код, главным образом, пытаясь передать JPanel в метод Animation.step, а также создал отдельный класс для прослушивания клавиш.
Новый список ошибок в основном такой же:
Exception in thread "main" java.lang.StackOverflowError
at java.awt.Component.setBackground(Unknown Source)
at javax.swing.JComponent.setBackground(Unknown Source)
at javax.swing.LookAndFeel.installColors(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
Затем бесконечный цикл до завершения следующих трех строк:
at MyPanel.<init>(MyPanel.java:10)
at KeyBinder.<init>(KeyBinder.java:6)
at Animation.<init>(Animation.java:11)