I'm about to create a java crossword application but I am unsure of what packages to use to draw the crossword grid. I know you can manually draw grids with Graphics2D etc. but I'm not sure if this is the easiest way to do it as I'll need text fields in the grid squares.
Anyone have any suggestions as to creating the crossword grid.
Actually I don't think you need textfields in the grid squares but just to write down every single letter for every grid cell..
To allow editing you just catch keyboard strokes over the component you use and set crossword cells according to what the user writes.
Doing it this way would be quite easy because you can use a back 2-dimensional array that stores the whole grid, then when the user select a definition you just start filling single letters whenever keys are typed starting from the first cell of the definition.. your draw routine will need just to be able to draw the grid and center letters inside cells, nothing more..
A JTable could work but it think it's oversized for your problem, because you'll end up interfacing with a lot of things you don't need at all..
EDIT (for comment):
I did it something similar this way:
you can have a cell class
class Cell
{
boolean isBlank;
char value;
}
with an array of cells you obtain your grid:
Cell[][] gamefield = new Cell[15][15];
then inside paint() you can easily iterate:
for (int i = 0; i < Scheme.rows; ++i)
{
for (int j = 0; j < Scheme.cols; ++j)
{
g2.drawRect(i*32, j*32, 32, 32);
if (Scheme.scheme[i][j].isBlank)
g2.fillRect(i*32 + 3, j*32 + 3, 32 - 5, 32 - 5);
}
}
Just because I still have a screenshot result was something like
Maybe use a JTable and custom renderer for the cells. That should be at least a simple solution. Of course it takes a little time to get used to JTable, but eventually it's quite simple.
Did you consider JavaFX at all? JavaFX will let you create "scene-graphs" based on vector/graphics edited using Adobe Photoshop/Inkscape etc.
If not, most simple way would be to extend JTextField such that that will just hold 1 char and will be black/or whatever color to indicate non-editable and disabled. Also, add a custom Border to indicate puzzle question number. Put everything in to a GridLayout.
Related
I am meant to create a game in Java that specifically uses looping Arraylists to create a 4x4 grid. I have a Grid class, made up of an ArrayList of 4 Rows, a Row Class made up of an ArrayList of Squares, and Squares Class. As well as other classes of objects, such as a hero and various enemies that will move to a random adjacent spot on the grid or "board" on each new turn.
I have methods in place to randomly assign starting positions, to find all possible adjacent positions and then select a random position out of those possible positions, etc.
The end product should look similar to this:
Is a GUI necessary or is there a much more primitive, simple way to model to the user the 'Grid' with the objects in their current containers?
You can use System.out.println("...") to print out the info to the terminal. You can just put everything in a String and print it out. You'll be able to see each time you make a move and see previous moves and add in more verbose info if you want. Assuming your grid is in an Arraylist grid, the following code should help you see how it can work.
for (Row row: grid){
String str = "";
for(Square square:row){
str += square;
}
System.out.println(str);
}
You can use the Java Scanner to grab input from the user instead of buttons.
I'm currently developping a roguelike game, using Swing. I'm using an array of JLabel to display the tiles. When the user input a direction, I redraw the whole tab using the following method (I'm using simplified variable name here) :
for (int i=0 ; i<array.length ; i++){
for(int j=0 ; j<array[i].length ; j++){
this.remove(array[i][j]);
array[i][j] = new JLabel(new ImageIcon(TILEARRAY[i][j]));
this.add(array[i][j]);
this.validate();
}
}
But it's very heavy to deal with, about 0.5s to redraw the whole panel, and when I press the direction, it can't draw fast enough to have a real-time display (it actually does the loop, along the waiting time, and when the whole displacement has been done, draws). I'd like to know if there's a easier and faster way to achieve this, with a " smooth " feeling (let's say like in Stone Soup Dungeon Crawl (tiles version)), using Swing.
Every suggestion on an efficient 2D library for Java is welcome too. I know there is Slick2D, but is there any good other library for this kind of games ?
Thanks
(sorry if my english is bad, I'm not a native speaker of English)
Call the this.validate(); just once after both loops to avoid layout preferences recalculations
UPDATE. Keep ImageIcons in a Map and reuse them rather than recreating. Key could be i+"_"+j String
Over the past few days, I've coded a (horribly patched together) text RPG game in Java. The positioning in the world is pretty much controlled by a simple 100x100 2D array of Strings. I then convert the Strings into actual objects when the player actually comes upon the grid.
What I have in mind is to have a graphic display showing this 100x100 grid with an image in each section of the grid that corresponds with what is in the array.
For example, if the String at block[10][15] is "rock", the graphic display section of the grid at row 10, column 15 would show a picture of a rock.
Ideally, this graphic would refresh every time I loop in my do-while loop. Oddly, what I have in mind is something that looks remarkably similar to the early pokemon games.
I apologize if my description is badly worded or my question too ambiguous. I have only learned java for half a semester in my computer science course, so my knowledge is limited to the basics we learned in the one semester. I do like to pursue various projects outside of class, like the text chess game that I (proudly) coded. I prefer to create everything from scratch so that I can learn the basics before using various libraries.
Could somebody please point me in the right direction for what I am looking for or offer a better way to go after this display?
Thank you very much in advance. Please let me know if a reference to my code would better help answer my question.
Firstly,you can use enums instead of strings as mentioned by Jack above. Eg
private enum Objects{
Rock(1),Coin(8),Med(45)...and so on
}
In your array, you may store these objects as numbers rather than strings.
eg:
boolean stopFlag=false;
do{
//check each element of your world array with the enum and draw it
for(int i=0;i<yourObjectsArray.length;i++)
{
for(int j=0;j<yourObjectsArray[i].length;j++){
switch(yourObjectsArray[i][j])
{
case Objects.Rock: drawRock(i,j);
break;
case Objects.Coin: drawCoin(i,j);
break;
//and so on....
}
}
}
//you can also put this into a separate function as drawWorld() and pass the objects.
//Key press checking logic here. If user presses exit key [esc] then you set the stopFlag as true
if(keypress==KEY_ESC){ stopFlag=true;}
}while(!stopFlag);
An example of Draw Rock:
private void drawRock(int i,int j){
//i and j are the cols and row values so you need to resolve them to coordinates.
//I am assuming u have a 800*600 screen and you mentioned that your world is 100x100 array. Then each of your object is 8*6 units in size so
xCoord=i*8;
yCoord=j*6;
//So if you have to draw a rock on [10][15] it will resolve as
//xCoord=10*8-> 80
//yCoord=15*6-> 90 so it will draw your rock in (80,90) on the screen
//Now you can either open the rock image from your disk now or u maintain one instance of rock at the beginning of the program so that you can use the same image later rather than opening it everytime you encounter a new Rock object in your array.For now I will open it here.
String path = "C:\\YourGameDirectory\\rock.jpg";
URL url = new File(path).toURI().toURL();
BufferedImage rockImg = ImageIO.read(url);
//draw it to the screen now if you have the graphics instance.
yourUIPanel.getGraphics().drawImage(rockImg,xCoord,yCoord,yourUIPanel);
// You may find many resources that teach you how to draw an image on the screen in Java. You may repeat the same for all the objects.
}
I hope the above codes helped you a-bit. If not,its my bad.
You can try this tutorial series to get started. Although its in C , it has concepts that will help u acheive what you have mentioned above.
Easiest thing to use for such tasks in my personal experience is Processing, which is a light framework which is able to provide a simple API to draw things.
There is a reference, and many tutorials so it shouldn't be that hard to get start with even if you are not expert.
As a side node: why do you use strings to store kinds of blocks? Could you use something better like an enum?
You might want to check out the source code of my old roguelike game Tyrant:
https://github.com/mikera/tyrant
Key ideas:
There is a Map class that is responsible for storing the data that represents the map. In Tyrant, the Map encapsulates storage of both the terrain and the objects places on the map.
There is a MapPanel class that shows the Map in the GUI. This is kept separate from the Map itself - it's generally a good idea to separate the GUI from your core engine data.
There is a Thing class that represents objects on the map. This includes everything from monsters, items, trees and clouds of smoke to the player character itself. Basically anything that isn't terrain.
As for refresh, the way this works is that the MapPanel repaints itself on demand, looking at the contents of the map. Check out MapPanel.paint(Graphics g) and the various methods that it calls.
Hello StackOverflow users!
I have a problem and I did find a solution to the problem, but I feel that the solution is not optimal. I feel like I used brute force to achieve what I wanted to do and am wondering if there might be a better way to achieve what I want.
Essentially what I have is a Java GUI application using the GridBagLayout. I use the GridBagLayout because the layout is essentially always center-aligned. When something else is added in, it shifts everything up, down, left, or right (depending on where the new object is added in). The issue, is that my program also needs to remove certain objects (depending on what happens in other blocks of code). So lets say I have four objects lined up like this [1] [2] [3] [4] and I want to remove [3]. I essentially want the layout to change to [1] [2] [3], essentially shifting everything over after the [3]. There was no problem doing this visually (because of how GridBagLayout works). However, when something new was to be added to the display, there would be overlap because though [4] took the visual position of [3], the GridBagPosition (not sure what else to call it) did not change. So I implemented the code below for the removal process.
public void removeSubImagePanel (int subPanelIdx) {
int x, y, nextX, nextY;
this.remove(this.portraits[subPanelIdx]);
nextX = this.portraits[subPanelIdx].getGbx();
nextY = this.portraits[subPanelIdx].getGby();
for (int i = subPanelIdx; i < this.numberOfPortraits; i++) {
x = nextX;
y = nextY;
this.portraits[i] = this.portraits[i+1];
if (this.portraits[i+1] != null) {
nextX = this.portraits[i+1].getGbx();
nextY = this.portraits[i+1].getGby();
this.portraits[i].getObject().setSubPanelIdx(i);
gbc.gridx = x;
gbc.gridy = y;
this.portraits[i].setGbLocation(x, y);
gb.setConstraints(this.portraits[i], gbc);
}
}
this.portraits[this.numberOfPortraits] = null;
this.numberOfPortraits--;
}
Essentially, I added two integer variables to the "portraits" object to hold the position of the X and Y on the GridBagLayout. That way, I could get the position [3], get the position of [4] set [4]s position to where [3]'s was and then (if there was a [5], set [5]'s position to [4]'s old position and so on until I arrived at the last element.
It feels too "brute force", having to add those integers, and I feel like it would be even worse if I were to make an individual GridBagConstraint for each object. Is there a better way to do this shifting that I need to do?
Sorry, this question is quite long. I didn't think it would be so long. I hope this is still okay. If I was unclear and you need any clarification, please don't hesitate to ask!
Edit: Would it be better if this were on the CodeReview stackexchange? It actually seems to make more sense to have it there. I'm not quite sure though.
This example shows that it is possible to remove all components from a container and completely replace each component in arbitrary order. The time required to validate() the enclosing container is negligible, as the components themselves remain unchanged.
I'm not sure what your requirements are for this project, but I would check out the Spring Layout - this layout lets you specify things like:
the left of [1] should be 10 pixels from the left of the panel
the right of [1] should be 10 pixels from the left of [2]
etc.
It is much easier (imo) to implement a nice fluid layout like you are describing here.
Edit: Just to try and add to the discussion:
maybe you could have a class called PortraitPanel that extends from Panel and in there you could maintain a List of your image panels. You could have public methods:
add(int index);
remove(int index);
So that when you call add(2) it will add that panel to the list at that index - and then take the panel at index - 1 and index + 1 and do the routine to adjust the constraints on these so it lays them out on either side of the newly added panel. Similarly, for remove you could take index - 1 and set it's constraints to lay out next to index + 1 and then remove the item at index. Again, if you use a SpringLayout it will be really easy to set it up so that things remain fluid when the window resizes, etc.
Hopefully this is in line with what you are trying to do.
Okay I have a game I'm working on that sets a 12x16 grid on the screen and then draws a pattern on the screen like so http://oi49.tinypic.com/53odih.jpg
I'm just wondering if there is a way using code to see if the box exists inside of the pattern or not?
This is how I'm looping though my grid boxes
//Set all blocks to default
for(int i=0;i<tilesX;i++){
for(int j=0;j<tilesY;j++){
blocks[i][j] = 0;
}
}
If a block is part of a pattern I set the block to 1. I want the blocks inside the pattern set to 2, but I can't think of a way to do this programmatically. The pattern will always be a complete shape and will always connect back to the starting point.
I hope that's not too confusing and I'm willing to provide you with what ever you need but I'm just lost on how to do it. Thanks
You need to implement the flood fill algorithm. Depending on how you draw the state of 2, you can flood fill the area starting at a known point inside the shape. Then check to see if its 0 (outside), 1 (border), or 2 (inside).
I think I'm grasping what you want here, but let me know if I'm off base.