Should Swing games only have a drawing component? - java

I've been using a JPanel and overriding paintComponent() in order to perform my drawing in Swing games. I'm now trying to add an inventory, which will contain different items the player can drag around and move to different slots in his "backpack" on the screen. Should Swing games only draw on a single JPanel or other component (example: draw images of item at mouse location) or can you add JButtons whose icons are pictures of the items?
Should the game only have the one drawing component, or can you include more?

Principally, you can have any number of components that you want to have. Swing – as any other sufficently elaborate library such as SWT for Java or Qt and WxWidgets for C++ – is intelligent enough to draw to the screen only what actually really is necessary.
As long as you do not run into performance issues, there is no problem with that. If this actually happens, you might first want to look at your own paintComponent implementation as this is the most probable location where you lose efficiency.

Related

Visual feedback in a card game with Java Swing

I'm working on a card game and I'm stuck on how to proceed with giving a simple visual feedback when the players are interacting with the cards that are placed on board.
As you can see in the image I'd like to implement drawing arrows between the cards that interact with different object on the board (for example when the player attacks with a starship a arrow will appear between the ship and its target). When the player commits his move, the arrow needs to be drawn on the opponents gui aswell when the opponent starts his defending phase.
The whole client gui aswell as the cards are coded with swing library and are JPanels with various layouts. The cards is one class and the board gui is composed of several gui classes (handGui, heroGui, unitFieldGui etc) added together in a mainWindow gui class.
I don't really know how to proceed to achieve this kind of visual feedback and would appreciate if you could point me in the right direction, what kind of technique would help me solve this problem?
Check out the section from the Swing tutorial on Glass Panes. a Glass Pane is a component that is painted over top of the frame and you can do custom painting.
You can use the SwingUtilities.convertPoint(...) method to convert the two card components location relative to the Glass Pane. Then you do your custom painting to draw the arrow from one component to the other.

How do I change the color of a drawn item after pressing a JButton? [duplicate]

This question already has an answer here:
How to define multiple JButton actions from a different class
(1 answer)
Closed 6 years ago.
So the program draws a car and I'm going to make three buttons, one for flash to initialize the flashing ability, one left, to move the car one space to the left and one right, to move the car one space to the right. My question is how do I make it change color each time I press the button? So to sum it up, I don't know how to have an object change it's color each time the button is pressed while flashing is on. I assume I use paint()
Any help would be appreciated.
If you are drawing an image, you will need to load a different image file which is a different color, and then draw that image instead. You will do this inside whatever method you are currently using to draw the car.
If you are drawing a shape or text of some kind, you can call g.setColor() on the graphics object passed to the paint() or paintComponent() method before drawing the shape.
There are any number of ways to do it. The basic requirement though, is to have a Object of some kind which you can tell when it should change color, it would then undertake the appropriate action and update the UI accordingly.
You could...
Use a simple JPanel as the representation of the object and simply call it's setBackground color method when you want it to change color.
This assumes you want to make use of a LayoutManager to position the panel. While it is certainly doable, it will require some thought into the overall design
You could...
Use a JPanel and override it's paintComponent method and paint the color change there. At the simplest level, this is overkill, but if you also want to draw a "car" or an image of "car", then this becomes a little more meaningful, especially if you want to rotate the car based on the direction it's moving
See Painting in AWT and Swing, Performing Custom Painting and 2D Graphics for more details
Flashing
I assume you mean you want the object to be animated in some way and "blink" on and off.
This can easily be accomplished through the use of a Swing Timer which can be used to change the state of a simple flag which changes the way in which the component is rendered.
See How to use Swing Timers for more details
The important concept to take away from this is to create a object which encapsulates the requirements in away which is ease for you to use, so when you enable flashing for example, all you do is call the setFlashing(boolean) method and the object takes care of the rest

Flickering when updating overlapping JPanels inside a JLayeredPane using timestep

I am making a game in Java. Basically, I have two different "planes" of updating that I need to take care of the. The base layer is the actual game painting itself. It is simply a JPanel that covers the entire JFrame, and is drawn to using its Graphics object.
I use a fixed timestep to take care of these first graphical updates. I have overwritten the paintComponent() method to do absolutely nothing, as I have written a custom render(float interpolation) method that takes care of that, as to prevent unwanted updates.
However, this panel can take no input beyond primitive mouse clicks and keyboard input. I need the ability to create various menus, text boxes, etc, that are also on the screen. Like various abilities, or even the "Menu" button that usually appears in the upper left corner of most games.
To take care of that input, such as creating buttons, I have a second JPanel that has setOpaque(false) applied to it. Then I create various Swing components that I might need, such as a JButton.
To contain the two JPanels, I use a JLayeredPane, and set their layers appropriately, as seen below. This way the input layer should always be on top of the actual game layer.
The code below shows how I create and add the Swing components to each other. addLoginDialog() is a method that adds a Swing component for the login. It has been tested and works properly, and isn't the problem.
private void initComponents()
{
//This code is inside of the JFrame
wholePane = new JLayeredPane();
add(wholePane);
guiPanel = new GUIPanel();
guiPanel.setOpaque(false);
gamePanel = new RPGPanel();
gamePanel.setOpaque(false);
wholePane.add(gamePanel, JLayeredPane.DEFAULT_LAYER);
wholePane.add(guiPanel, JLayeredPane.POPUP_LAYER);
guiPanel.addLoginDialog();
}
So when I run the code, I get horrible flickering. This is the code that is run from my fixed timestep ~60 times per second.
public void handleRepaint()
{
//I don't use repaint() for the game drawing so I can be sure that fps is controlled.
Graphics g = gamePanel.getGraphics();
gamePanel.render(g);
g.dispose();
wholePane.repaint();
}
The problem is, I think, that the two different systems of updating the screen are clashing. The standard paintComponent() system is great for more static screens, but when I need to update consistently and keep track of the fps, I can't have updates going off randomly.
However, for the input layer, I only want to update as Swing normally does. When the mouse moves over a button, when I component is moved or is resized, etc.
Also, note the way the screen flickers: The Background image goes blank and then comes back again repeatedly. The input panel is always there, but is actually painted behind the game drawing, which shouldn't happen, because it is put in the default layer. The reason I know it isn't completely disappearing is because the game painting is partially transparent, so I can see underneath it, and the buttons I added are still there.
My main question is, how can I stop the flickering? Why is the game drawing being drawn on top of the input components when the game drawing is being done on the Panel that is in a lower layer in the JLayeredPane? And I supposed most importantly, what is causing the flickering? Thank you for any help.
Why is the game drawing being drawn on top of the input components
when the game drawing is being done on the Panel that is in a lower
layer in the JLayeredPane?
Mostly because you've circumvented how Swing works.
Let's start with the fact that the Graphics context is a shared resource (typically there is a single Graphics context per native peer), that is, every component gets the same context, this means, when you use your own painting routine, you are basically painting over every thing else.
The RepaintManager is responsible for making decisions about what and when something should be painted. So what you now have is two artist fighting over the same canvas, wanting to paint on it simultaneously, which is just making a mess.
Add into the fray that Swing's painting process is not thread safe and you end up with a complete mess.
If you absolutely must have control, then you need to remove Swing's painting engine from the equation.
Start by taking a look at Passive vs. Active Rendering
ps- There is also hard ware acceleration benefits to using a BufferStrategy

Using a paintComponent with layout

How do I convert a paintComponent to something that I can manipulate with a layout in a JFrame?
So, I'm running into an issue. I haven't really been taught (and don't have access to a book) how to use layouts/GUI stuff in my courses yet.
My issue is this: I have a program that the user inputs a number. Based on this number, the program calculates a circle and draws it out with a paintComponent method that has a for loop inside of it. The "pixels" that the circle is drawn with are actually fillRect methods. The current method of getting a user-input that I am using is a JOptionPane showInputDialog. This is MOSTLY fine, but I want the user to be able to select from a set of pre-defined numbers. Somebody suggested that I use a JComboBox, but I don't know how I would convert the paintComponent to something that would be usable by a layout manager (which a JComboBox must use, as far as I've learned). I know the dimensions of the paintComponent (805px by 805px) and there is no situation where it will change. If I could get some help with this bit, I am confident that I can figure out using a layout manager myself.
Another way to paint (besides custom painting) is to paint to a BufferedImage. The image can then be displayed in a JLabel.
Examples:
Painting in a BufferedImage inside Swing A fairly complicated one.
Dynamic Graphics Object Painting Another one.
Yet another one.
You don't know the dimensions of paintComponent because it's a method, and methods don't have dimensions. You probably know the dimensions of a JPanel or a JFrame or whatever your component is.
You should separate the panel where you do the painting, and a different panel which would contain any comboboxes or other inputs you decide to put in. That way you can keep your drawing panel as is, and they won't interfere with each other. You'll want to search for the tutorial on LayoutManagers.

Jpanel / Jframe / buffering graphics etc game structure direction

I'd like some advice regarding structure of a game I'm working on. Specifically where to place painting methods.
Currently there is a applet wrapper class for a Jpanel which runs the game loop.
The game itself is meant to simulate a very large area. objects will have x&y values which themselves will part of a larger x&y grid.
i.e. object1 position is 150000x30000 in grid block 1,5.
objects will need to be able to move into neighbouring grids, however I'd rather not run each grid block until needed as 99% of them will be empty.
Currently the UI is a Jpanel with a few buttons + listeners, a large drawing pane is needed to display the objects.
my question is:
what class should this internal drawing pane be based on? I'd like to have control to zoom and pan around the grid. it only needs to draw what is visible, but object movements will continue in the game loop.
what painting strategy would be applicable for simple (icons really when zoomed out) moving around vast areas, I'm guessing relying on the EDT to repaint isn't going to be good enough?
I'm not really after specific code, I want to learn myself how to do this, I just need pointing in the right direction, as most things I read don't seam to quite cover what I'm after, or don't make use of JRE6+ features.
Many Thanks
Rather than paint each grid cell in your drawing pane, why don't you have each object repaint itself onto the grid?

Categories