Я создаю графический интерфейс с качанием для Java-игры. Игра по существу представляет собой сетку 4x4, состоящую из пользовательских объектов Cell
, которая по сути является обычным JButton. Код для этого нижеИконки в JButtons не удаляются?
package gamePack;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JButton;
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
ArrayList
позволяет мне хранить объекты различной Players
. Все Players
наследуют от того же класса, поэтому я по существу перерисовываю ячейку и добавляю значки на основе типа объекта в ArrayList. Для каждой ячейки есть ArrayList, так как каждая ячейка может иметь несколько Players
.
GUI initialization:
package gamePack;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.border.Border;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class StarFight {
public JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StarFight window = new StarFight();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public StarFight() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setVisible(true);
frame.setBounds(100, 100, 487, 349);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
final JPanel gamePanel = new JPanel();
gamePanel.setBounds(0, 0, 365, 310);
frame.getContentPane().add(gamePanel);
int i = 4;
int j = 4;
final Cell[][] panelHolder = new Cell[i][j];
gamePanel.setLayout(new GridLayout(4, 4, 0, 0));
//91.25 x 77.5 rectangles
Border border = BorderFactory.createLineBorder(Color.white);
for(int m = 0; m < i; m++) {
for(int n = 0; n < j; n++) {
panelHolder[m][n] = new Cell();
panelHolder[m][n].co_x = m;
panelHolder[m][n].co_y= n;
panelHolder[m][n].setBackground(Color.black);
panelHolder[m][n].setEnabled(false);
panelHolder[m][n].setBorder(border);
gamePanel.add(panelHolder[m][n]);
}
}
JPanel controlPanel = new JPanel();
controlPanel.setBounds(375, 0, 86, 310);
frame.getContentPane().add(controlPanel);
controlPanel.setLayout(null);
final JButton Move = new JButton("Move");
Move.setEnabled(false);
Move.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
panelHolder[0][0].current.clear();
BattleCruiser q = new BattleCruiser();
panelHolder[3][2].current.add(q);
Redraw.draw(gamePanel, panelHolder);
}
});
Move.setBounds(1, 82, 84, 65);
controlPanel.add(Move);
final JButton Undo = new JButton("Undo");
Undo.setEnabled(false);
Undo.setBounds(1, 158, 84, 65);
controlPanel.add(Undo);
JButton Exit = new JButton("Exit");
Exit.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
});
Exit.setBounds(1, 234, 84, 65);
controlPanel.add(Exit);
final JButton btnStart = new JButton("Start");
btnStart.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
Move.setEnabled(true);
Undo.setEnabled(true);
btnStart.setEnabled(false);
PlayChar p = new PlayChar();
BattleCruiser q = new BattleCruiser();
BattleStar s = new BattleStar();
BattleShooter sh = new BattleShooter();
panelHolder[0][0].current.add(p);
Redraw.draw(gamePanel, panelHolder);
}
});
btnStart.setBounds(1, 6, 84, 65);
controlPanel.add(btnStart);
}
}
Игра меняется при нажатии кнопки «Переместить». Здесь я добавляю в спрайт игрока, когда я нажимаю start, и вызывается метод перерисовывания. Метод перерисовки ниже:
package gamePack;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class Redraw {
public static void draw(JPanel gamePanel, Cell[][] panelHolder){
gamePanel.setBounds(0, 0, 365, 310);
int i = 4;
int j = 4;
gamePanel.setLayout(new GridLayout(4, 4, 0, 0));
//91.25 x 77.5 rectangles
Border border = BorderFactory.createLineBorder(Color.white);
for(int m = 0; m < i; m++) {
for(int n = 0; n < j; n++) {
panelHolder[m][n].setBackground(Color.black);
panelHolder[m][n].setEnabled(false);
panelHolder[m][n].setBorder(border);
panelHolder[m][n].setIcon(null);
for(Players p: panelHolder[m][n].current){
if(p instanceof PlayChar){
String arg = "Player.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleStar) {
String arg = "BattleStar.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleCruiser){
String arg = "BattleCruiser.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleShooter){
String arg = "BattleShooter.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
}
}
}
}
gamePanel.revalidate();
gamePanel.repaint();
}
}
метод перерисовки проверяет ArrayList в каждой ячейке, а затем добавляет значок соответствующим образом. На данный момент, когда я нажимаю «Переместить», он должен удалить все JButtons, а затем добавить их обратно с соответствующими спрайтами.
Проблема заключается в том, что когда я делаю это, даже с помощью current.clear()
перед добавлением другого спрайта спрайт в позиции 0,0 по-прежнему нарисован. Выполнение кода показывает, что оператор if для объекта PlayChar
не вызывается, поэтому я должен предположить, что это как-то связано с методом перерисовывания. Я делаю что-то явно неправильно?
EDIT: на основе обратной связи я изменил его, поэтому функция перерисовки не заменяет JButtons, но изменяет их свойства. Я также добавил его так, чтобы значок был установлен на нуль для каждого из них до того, как будут установлены какие-либо значки, чтобы убедиться, что он удален. Та же проблема, однако, все еще происходит
whatever.setIcon (NULL) ;, Дон»заменить JComponents во время выполнения, чтобы использовать, чтобы изменить его свойства с помощью SetIcon/Граница/фон ... – mKorbel
@mKorbel нормально , поэтому я отредактировал код так, чтобы он не заменял компоненты, но менял их и добавлял в 'setIcon (null);' для запуска, прежде чем он попытается изменить значок на что-то еще. Тем не менее, это по-прежнему вызывает те же проблемы. –
есть причина, по которой вы используете JLabel и вызываете add, чтобы установить значок на JButton, а не напрямую использовать .setIcon (значок). – faljbour