Jpanel in Puzzle Game Not Updating

JPanel in puzzle game not updating

After changing the components, you need to 'refresh' the Swing component by calling invalidate() or revalidate().

Smooth components automatic refresh after modifications or loops (ex: timer)

JPanel in puzzle game not updating

After changing the components, you need to 'refresh' the Swing component by calling invalidate() or revalidate()

Flickering while revalidating JPanel

Using labels (or generally GUI components) to represent quickly animating, dynamically created/moved objects is not practical. Its like using a car to drive from the living room to the kitchen.

The Swing components come with a lot of nice features, e.g. they can determine the space they require and a layout manager can use that to automatically place them nicely. Unfortunately for a game, you neither need all the nice stuff, nor do you want to pay the processing overhead involved with it. Matters are further complicated by swings multi-platform capabilities which mandate that each component has a peer component (the peer deals with rendering the component to the active look).

To solve this, you do not represent individual game objects as swing components. Instead you use a single swing component (usually JPanel) as a canvas to paint your game objects on to. You simply call repaint() for that JPanel periodically (e.g. 30 or 60 times a second). Of course you will override paintComponent() on the JPanel to do paint all the game objects using your own code.

Edit: To outline how you do your own rendering

You need to decide how to organize your game related objects. A very simple skeleton could look like this (getters/setters omitted):

public class GameObject {
public int x;
public int y;
public Image image;
}

In practice this class will have additional members (like a behavior that controls how the object moves, and maybe some states/counters for animation). It may also be abstract with a concrete subclass for each possible behavior (like ship, asteroid and bullet). All instances of GameObject are managed in some kind of collection, I assume you use a List.

When implementing the paintComponent it comes down to just loop through the list and render each objects's image:

public void paintComponent(Graphics g) {
List<GameObject> list = ... // however you obtain it in your game
for (GameObject gobject : list) {
g.drawImage(gobject.image, gobject.x, gobject.y, (ImageObserver) null);
}
}

More elaborate games may order the gameobjects to get control of how game objects overlap each other. But in principle its incredibly simple.

KeyListener not being triggered after I swap JPanels

I even set back the setFocusable(true) property back on the game JPanel after I remove the Inventory JPanel

Key events only go the the component that has focus. You need to invoke:

panel.requestFocusInWindow();

after swapping the panels to make sure the panel has focus again.

However, a better approach is to use Key Bindings itead of a KeyListener.

Programmatically swap two JPanels in JFrame

  • there wouldn't need to move with JPanels into container, otherwise you woud need to use bunch of quite useless code to remove two JPanels from from contianer with two indexes then to layout back to container with swaping indexes,

  • (if is about Color only) only to swap setBackground(Color.Xxx) betweens two JPanels

  • puzzle-like game is about Images, puzzle or minesweaper is about, (not clear from your ...)

    1. put Images as Icon/ImageIcons to JLabel instead of JPanel and on Mouse Events to switch (setIcon()) with Icons betweens JLabels, load Icons to local variables

    2. (easiest of ways) JToggleButton and Icon, there is logic similair as for JLabel, but about showing Icon on setPressedIcon()

Dynamically rearrange layout with Swing

Although dynamic layouts are possible, as shown here and here, I'd use a one-column JTable with a TableModel that reflects the pushdown stack effect you want, perhaps one having an internal Queue<Tweet>. JTable rendering is efficient, and the component works well in a JScrollPane.

Java: JPanel cannot receive key events after button is clicked (which has no registered event listener)?

not all Keys are accesible for KeyListener, part of them are registred as built-in short-cuts for JComponents, depends of JComponent's type and used Look and Feel, if you want to listening for Keys from keyboard, then you have to implements KeyBindings, Swing JComponents are designated to use this listener rather that KeyListener

working example for key A

import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test2 extends JPanel {

private static final long serialVersionUID = 1L;
private JButton a = new JButton("A");

public Test2() {
setFocusable(true);
setLayout(new GridLayout(3, 3));
a.setEnabled(false);
add(a);
addKeyListener(new KeyAdapter() {

@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_A) {
remove(a);
JButton b = new JButton("B");
add(b);
add(a);
revalidate();
repaint();
}
}
});
}

public static void main(String... args) {
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Test2());
frame.pack();
frame.setVisible(true);
}
}


Related Topics



Leave a reply



Submit