Grid building for Connect Four gui - java

I have been able to create a grid using an image file (serves as the empty circles), a loop, and GridLayout, but I am well aware that there's more functionality needed (like for dropping the token, though no animation is necessary yet) so I scrapped it and now I'm back to an empty grid. I am stuck and I'm not really sure how I can accomplish this. My code is a mess at the moment so I'm not sure if it'd even make sense for me to post it.
My main problem is how to build a grid, which will then just be filled with a solid color (I'm cancelling using an image file, it seems a little more complicated as far as I'm concerned) with empty circles, that I will be able to fill up with an image file of a token once the player clicks on a button that corresponds to the column he chose (and then reset everything after the game is over). In other words, a rectangle of solid color and with empty circles to be filled up by tokens, but not with solid color, but an image file.
I have been trying to familiarize myself with paint() but I only started learning GUI last week so there are still likely some more things I'll have to learn to probably understand it in a considerable degree.
I am running out of options tantamount to my knowledge of GUI (Swing in particular) and I have been trying to work on this for a week now.
Any hints?

There are multiple possible ways to solve this, but one easy one is to give a JPanel a GridLayout, and then fill it with JLabels with ImageIcons that show empty circles. When the column is selected, the appropriate JLabel is given a new ImageIcon via setIcon that shows a color filled circle.
Also,
Always strive to separate your program logic code from your GUI code, since the better your separation, the easier will be your ability to debug and enhance.
Work on small problems one at a time. Don't move on to the next problem until the current small step is solved.
Work out your logic and ideas on paper first before committing it to code.
Don't "work with paint". If you need to do Swing graphics, you'll want to override a JPanel or JComponent's paintComponent method. The paint method also concerns itself with drawing borders and children, and so overriding it can have nasty and unexpected side effects on these. Also paint is not double buffered by default, and this can lead to bad animation once you start working with animation.
Edit
You state in comment:
Will it be okay to use JButton though? Because that was what i used during my first attempt. I can use setIcon with it too right?
Do you mean use a JButton instead of a JLabel? That would work, and yes you can call setIcon on JButtons, but would make all your rectangles look like buttons. So if that's OK, then do it. Otherwise, you could still use JLabels, and then create a row grid of JButtons to put below or above your game grid, and then have the user press those buttons, and in their ActionListeners have them change the icons of a JLabel in the selected column.
But having said this, I mainly recommend that you use what works best for you. The learning will be in the creating, no matter what you create.
Edit 2
You ask:
do you think it'll be possible/a nice approach to store jlabels in an array and then lay them out in a panel?
Absolutely, either an array of JLabel[] or a List<JLabel> I think is not only possible but in fact essential for this to work well. I think that you're definitely on the right track here.

Related

Why can't GridLayout allow components to be changed by row and column?

This is perhaps more of a whine than a question, and I'm aware there's a workaround to the problem described in this post. But I have a situation where I have to add components to a GridLayout, possibly enlarging the grid as I go; but the components don't get created and inserted in a nice neat order; and I don't know when I'm done being handed components to insert into the grid. In other words, in a 3x3 grid I might get handed a component to put at (0,2) and then another at (1,0) and then one at (0,0). And then I might get one at (5,2) and need to enlarge the grid. And then I might get told to replace the line at (0,0) with something else.
I understand that there's no way to say "put a component at x, y". I get that I'm going to have to build a 2D array to hold my components and then empty and refill the grid from the array, each time it changes, which is going to be quite often in several large grids, so I'd rather not. I get that life is like that and the language is the language and who am I to question why.
But I'm really curious. This seems like the most basic of operations for a grid to support. Not having it feels like I'm working with a spreadsheet that only lets you enter values in order from left to right - it's simple madness.
I haven't taken apart the source code for GridLayout, but any naive understanding of how it "must work" makes me think add(component, row, col) should be trivial to implement. It must not be, because GridLayout isn't exactly new and I can't believe I'm the first to think random access to a grid is a good idea. So it must be really hard. But why?
I realize understanding why the internals of GridLayout can't support this, doesn't solve any real problems, except the problem of me unable to stop thinking about how fundamentally weird the restriction is. In the end I'm going to end up with a parallel array, or messing with the more complex GridBagLayout, unless someone knows a better way. But I just want to know why I have to.
Why not approach the problem from a different angle:
Create your grid using GridLayout
Fill the grid with empty JPanels
JPanels that each uses a BorderLayout
Keep these JPanels where they are
But swap the JPanels that they display within them in each of their BorderLayout.CENTER positions
Alternatively, you could have them use a CardLayout, but the effect would be the same

Use components as JProgressBar on java game

Been building up a little game in java, already asked a few questions about the usage of JPanel in it, and used them to paint the graphics and the main part of the screens.
Now i have a little doubt about other components. My intention is to add on the corner a pair of bars to show health and mana of an entity (like in a rpg game), and wondered which was the best approach for it.
Thought about making a new JPnale with a pair of JProgressBar to set the ammount of it, but then i wondered if it would be better to paint it completely and fill a pair of rectangles.
I mean, doing a pair of new JProgressBar() for it, or a pair of g.fillRect() and then paint the ammounts.
I guess that easiest is to set the JProgress, as i can set values and text if i want, maybe, but not sure about it and if it would run smoother without overwhelming it with JComponents.
Also, if want to add buttons would be better the JButton, or paint a rectangle and check for containment of the mouse pointer with an event (I have this approach at some points where there is not KeyBinding). Should i change that?
Thank you beforehand :)
I'm writing an answer because i haven't got enough reputation to comment :(
I think is better if you paint it in your graphics engine. Use Rectangles is of course a better idea than use a new JPanel with JProgressBar.
But i think that it's even better if you use Images to build your own Progress Bar.
You can create them or find them on internet.
For example you can take an Image for the Progress Bar Background, and another Image for the Foreground (the part that will fill the Bar). Then you can set their X and Y position and then just change the Foreground Width in relation with the entity health to fill or empty the Progress Bar.

Best way for multilayered 2D Graphics on JFrame with partial repaint?

Basicly, I want to make a game of chess.
The idea is that I have a picture of a chessboard and the individual chess pieces. What I could get to work is a JPanel where I would repaint everything everytime with the new positions of the chess pieces, but this would require to get the positions of all chess pieces and repaint the board with up to 33 pictures, with double buffering and all.
A bit resource consuming I think. AFAIK, there is the option to only repaint a certain area, but I guess there're still better ways. What I could imagine is, just moving or removing one or two pictures or rather chess pieces each time rather than repainting something.
I sadly have only very limited knowledge of the classes out there and so I ask if there is such a way or even an entirely different one, that does the job more efficient than painting/repainting.
Instead of inventing the wheel again, use a game engine with sprite support like JGame to do the rendering.
Also note that today, the resource consumption to render chess is so small that spending a minute to optimize it is a minute wasted. What you should aim for is a framework which takes the least time to implement the rendering of the game so you don't have to spend too much time on this part of the game.
If you feel a game engine to be overkill, how about using a table with a custom cell renderer which draws each cell? The table will make sure that updates are rendered in an optimal way. You might even be able to use a custom TableModel to define the playing field.

Suggestion for implementing a drawing program - UML designer

This program will have an infinite canvas (ie as long as the user scrolls, it becomes bigger) with a tiled background image, and you can drag and drop blocks and draw arrows between blocks. Obviously I won't use a layout manager for placing blocks and lines, since they will be absolutely positioned (any link on this, possibily with a snapping feature?). The problem arises with blocks and lines. Basically I'll have two options:
Using a simple layout for each building block. This is the simplest and clearest approach, but does it scale well when you have hundreds of objects? This may not be uncommon, just imagine a database with 50 tables and dozens of relationships
Drawing everything with primitives (rectangles, bitmaps, etc). This seems too complicated (especially things like text padding and alignment) but may be more scalable if you have a large number of objects. Also there won't be any event handler
Please give me some hints based on your experience. I have never drawn with Java before - well I did something rather basic with PHP and on Android. Here is a simple preview
DISCLAIMER
You are not forced to answer this. I am looking for someone who did something like this before, what's the use of writing I can check an open source project? Do you know how difficult it is to understand someone else's code? I'm talking about implementations details here... Moreover, there is no guarantee that he's right. This project is just for study and will be funny, I don't want to sell it or anything and I don't need your authorization to start it.
Measuring and drawing text isn't such a pain, since java has built in classes for doing that. you may want to take a look at the 2D Text Tutorial for more information. In fact, I did some text drawing computations with a different graphics engine which is much more primitive, and in the end it was rather easy (at least for the single-line drawing, for going multiline see the previous link).
For the infinite canvas problem, that's also something I always wanted to be able to do. A quick search here at stackoverflow gives this which sounds nice, althought I'm not sure I like it. What you can do, is use the way GIMP has a scroll area that can extend as you move - catch the click of the middle mouse button for marking the initial intention to move the viewport. Then, when the mouse is dragged (while the button is clicked) move the viewport of the jscrollpane by the offset between the initial click and the current position. If we moved outside the bounds of the canvas, then you should simply enlarge the canvas.
In case you are still afraid of some of the manual drawing, you can actually have a JPanel as your canvas, with a fixed layout. Then you can override it's paint method for drawing the connectors, while having child components (such as buttongs and text areas) for other interaction (and each component may override it's own paint method in case it wants to have a custom-painted rect).
In my last drawing test in java, I made an application for drawing bezier curves (which are basically curves made of several control points). It was a JPanel with overidden paint method that drew the curve itself, and buttons with custom painting placed on the location of the control points. Clicking on the control point actually was clicking on a button, so it was easy to detect the matching control point (since each button had one control point associated with it). This is bad in terms of efficiency (manual hit detection may be faster) but it was easy in terms of programming.
Anyway, This idea can be extended by having one child JPanel for each class rectangle - this will provide easy click detection and custom painting, while the parent will draw the connectors.
So in short - go for nested JPanels with custom drawing, so that you can also place "on-canvas" widgets (and use real swing widgets such as text labels to do some ready drawing) while also having custom drawing (by overriding the paint method of the panels). Note that the con of this method is that some swing look-and-feel's may interfere with your drawing, so may need to mess a bit with that (as far as I remember, the metal and nimbus look-and-feel's were ok, and they are both cross-platform).

mouseListeners and JLabels using images with transparent pixels

I'm willing to make a isometric game but I'm having hard time with the mouseListener.
I'm using Swing and make losanges by using square images with transparent pixels (GIF format).
The problem is that making losanges touch each other edge means having the transparent pixels of one on the top of the others, which is a problem with the mouseListener.
I'm willing to know exactly which losange was clicked on, but as the transparent pixels of the nearby losange get on the top of the one that was clicked on, the wrong losange is selected as the KeyEvent source.
Is there a way to have mouseListener not considering transparent pixels as part of the shape ?
Thanks for reading.
It's not clear
1) why the tiles have to overlap, or
2) why you're using JLabels for the tiles
There's are many ways to solve the problem you're having, but I'd just make a single JComponent that renders the tiles as needed, and is the sole MouseListener.
As mentioned by Jonathan, I think you're using the wrong technology for the job. I've had great success using a 2D graphics framework for software such as this. In my case I'm a big fan of Piccolo. I know you don't want to hear this, but consider starting over with the appropriate toolset.

Categories

Resources