I'm looking for a way to populate a gridview from the bottom left going across and up rather than the top left going across and down, but also still be able to use pointToPosition(x, y) to get the correct element in the array (so bottom left would be 0).
I'm not entirely sure if this is possible or not but I guess it must be, however I can't think of any way to do it without messing up the ability to find the array indices properly. Any help would be appreciated.
here is the code to get the string array used to fill the grid:
int num = 0;
//populates a standard array from the grid in the JSONObject
for (int vertical = 0; vertical < puzzleArray.size(); vertical++) //rows
{
for (int horizontal = 0; horizontal < puzzleArray.get(0).length(); horizontal++) //columns
{
//adds each letter of each row stored in puzzleArray to puzzleInputArray
puzzleInputArray[num] = puzzleArray.get(vertical).charAt(horizontal) + "";
num++;
}
}
The puzzleArray comes in as 9 strings of 9 letters which are then separated into a seperate array with the code above.
I fill the GridView with a standard ArrayAdapter:
//fill GridView with the puzzle input array from the puzzle class
ArrayAdapter<String> gridAdapter = new ArrayAdapter<String>(c, R.layout.cell_layout, todaysPuzzle.puzzleInputArray);
wordsearchGrid.setAdapter(gridAdapter);
And I need to be able to call the equivalent of this on the grid:
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
startPosition = wordsearchGrid.pointToPosition((int)downX, (int)downY);
letterDown = (String) wordsearchGrid.getItemAtPosition(startPosition);
Thanks.
to solve your problem, you simply have to use more advances techniques to create your adapter.
Writing an adapter in one line of code is great, but to get a more customized experience of adapting your array to a gridView, you will have to write a BaseAdapter yourself.
From there, it will be quite simple, you can for example have two arrays as its member variables, one to store the "real" indexes, and one to the "displaying" indexes.
Hope I helped you :) !
Related
I am working on a messaging application. The GUI is written in Java Swing. When the client starts, it asks my server for the chats a specific user is involved in. The server will send these in the form of an string array eg: {CHAT_PATH,CHAT_PATH}.
Once the client receives this it feeds it to my GUI class, which is supposed to display each chat name in the list (I will filter out the rest of the path) on screen listed downward. This is where my problem lies. I start by creating a JButton list:
JButton[] chat_names = {};
and then I loop through the list of chats (chat_data) and add to my chat_names list a new JButton for each chat name. Like this:
for (int x=0; x<chat_data.length-1; x++){
chat_names[x] = new JButton(chat_data[x]);
chat_names[x].setBounds(100,100,100,100);
}
for (int x=0; x<chat_names.length; x++){
frame.add(chat_names[x]);
}
When I do this I get the following syntax error:
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of
bounds for length 0
at gui_main.menu_screen(gui_main.java:16)
at Main.main(Main.java:89)
Does anyone know if this is fixable or another way I could display a list of buttons each with a chat_name on them.
Here you created an array of JButtons with length 0
JButton[] chat_names = {};
You can either call
chat_names = new JButton[chat_data.length];
before the for-loops or create a
List<JButton> chatNames = new ArrayList<>();
to have a variable length list of buttons
As a tip use camelCase rather than snake_case for your variables and methods, as that's the convention.
And one more thing don't manually specify the bounds of each JButton, instead use a proper Layout Manager for example GridLayout or BoxLayout may work. If you insist on using setBounds and (more than surely) null-layout you may find yourself in a problem similar to this one when trying to run it on a different computer or a different monitor.
You can also merge these 2 loops:
for (int x=0; x<chat_data.length-1; x++){
chat_names[x] = new JButton(chat_data[x]);
chat_names[x].setBounds(100,100,100,100);
}
for (int x=0; x<chat_names.length; x++){
frame.add(chat_names[x]);
}
Into one, reducing one iteration over all the chats and thus improving performance:
for (int x=0; x<chat_data.length-1; x++){
chat_names[x] = new JButton(chat_data[x]);
chat_names[x].setBounds(100,100,100,100); //Use a layout manager!
frame.add(chat_names[x]);
}
I made me a pixel based sprite class for a simple game in java and swing, and I don't want to let some sprites go through other sprites. So I wrote two loops that are supposed to add the pixels of every other sprite to the "material" array of the level. Material should not be passable. With the level it does work. There the sprite can't pass through its material. But with other sprites it doesn't. It can go through them. And that's the bug I actually want to fix. It seems that the sprites' pixel arrays aren't appended.
Any help is greatly appreciated !
Code :
int applied_pixels=lvl.material.length;
Sprite[] others=new Sprite[] {other sprites};
/*EDIT : others[i].frameborders[others[i].frame].all is the point array of the sprites' pixels
others[i].frame is the frame of the sprite object, because they contain an array of BufferedImages. Frame is the one that should be taken*/
Level lvl=the level; //Containing a couple of point arrays of pixels of some types, for example containing the material array of pixels
int apply_pixels=0; //How many pixels are needed ?
for (int i=0; i < others.length; i++) {
if (others[i] != null) { //Isn't the sprite null
apply_pixels=apply_pixels+others[i].frameborders[others[i].frame].all.length; //How many points does it has to add ?
}
}
level=lvl.clone(); //Copy level to be able to later append points to the material array
level.material=new Point[apply_pixels];
System.arraycopy(lvl.material,0,level.material,0,lvl.material.length); //Copy old material array points
int appending_position=0;
appending_position=lvl.material.length; //Which destination position to append the points at ?
for (int i=0; i < others.length; i++) {
if (others[i] != null) { //Isn't the sprite null
System.arraycopy(others[i].frameborders[others[i].frame].all,0,level.material,appending_position,others[i].frameborders[others[i].frame].all.length); //Copy the points from the sprite to the material array
appending_position=appending_position+others[i].frameborders[others[i].frame].all.length; //Position to append at is now plus the length of appended points
}
}
I see two possible problems with your code as posted.
The first is that level.material=new Point[apply_pixels]; only allocates elements for the new pixels. It should probably read level.material=new Point[lvl.material.length + apply_pixels];. Alternatively, you can initialize apply_pixels as int apply_pixel = lvl.material.length instead of to zero.
The second problem is that you never show us how lvl replaces the original level. Presumably the code you posted is part of a method somewhere and level is an input that is passed in, but is accessed through a field by other parts of the program. Unless the modified lvl is correctly returned and replaces the original, the code here will have no effect. However, this is only speculation because OP refuses to post the relevant code.
I'm new to swing and I've been trying some new things. I'd like to create and place JLabels on a JPanel, but as many as I want, using a loop. I'm trying to make a snake game, btw.
/*Up here I set the number of parts (JLabels) I want and instantiate my ArrayList
to store them later.*/
snakeBodyParts = 3;
snakeBody = new ArrayList<>();
/*This is the part I'm struggling with. First, bodyPartIndex is going to go from 0
to my desired number of parts. On each time it's going to store an int for the X position
of the JLabel and an int for the Y position. That way I'm going to get
JLabels on a horizontal line, each time an unit farther away.*/
for (int bodyPartIndex = 0; bodyPartIndex < snakeBodyParts; bodyPartIndex++) {
snakePositionsX[bodyPartIndex] = 50 - (bodyPartIndex * UNIT_SIZE);
snakePositionsY[bodyPartIndex] = 50;
/*Then, I add a JLabel to my list, and get it back to my "bodyPart" JLabel.*/
snakeBody.add(new JLabel());
bodyPart = snakeBody.get(bodyPartIndex);
/*Here I set the location on my "bodyPart" JLabel, using the coordinates I created before,
and set its icon (it's out of the loop)*/
bodyPart.setLocation(snakePositionsX[bodyPartIndex], snakePositionsY[bodyPartIndex]);
bodyPart.setIcon(imgIconBodyPart);
/*And finally I replace the old bodyPart with the recently modified one, I then add it to my JPanel (this.add) */
snakeBody.set(bodyPartIndex, bodyPart);
this.add(bodyPart, new org.netbeans.lib.awtextra.AbsoluteConstraints(snakePositionsX[bodyPartIndex], snakePositionsY[bodyPartIndex], UNIT_SIZE, UNIT_SIZE));
}
I'm pretty sure I've done a lot of things wrong, I'm still trying to understand what I'm doing, but the end result is a blank screen, can anyone help me? I really need to know how to do this.
So I have this 2d array of buttons and I have an array of images. I want to get the images on the buttons but I want the images to be on random buttons every time the program starts. Like this:What I want it to look like. Right now I can only get one color to be on all of the buttons by changing the value of icons when I make the new JButton. What I think I need to do is have Math.Random() set to a variable and to get a random value from the array of images and then put the variable in icons[] when i declare the new JButton but I don't know if this is right and don't know how to do it. I did some searching and tried using this:
var randomValue = icons[Math.floor(Math.random() * icons.length)];
but I get an error saying
possible loss of precision, required int, found double.
Help would be greatly appreciated. If you want me to post the entire code let me know.
// 2D Array of buttons
buttons = new JButton[8][8];
for(int row=0; row<8; row++)
{
for (int col=0; col<8; col++)
{
buttons[row][col] = new JButton(icons[0]);
buttons[row][col].setLocation(6+col*70, 6+row*70);
buttons[row][col].setSize(69,69);
getContentPane().add(buttons[row][col]);
}
}
// Array of images
public static ImageIcon[] icons = {new ImageIcon("RedButton.png"),
new ImageIcon("OrangeButton.png"),
new ImageIcon("YellowButton.png"),
new ImageIcon("GreenButton.png"),
new ImageIcon("BlueButton.png"),
new ImageIcon("LightGrayButton.png"),
new ImageIcon("DarkGrayButton.png")};
I'd simplify this greatly by putting all my ImageIcons in an ArrayList, calling java.util.Collections.shuffle(...) on the ArrayList, and then passing out the ImageIcons from the shuffled ArrayList in order. Or if your buttons allow for repeated icons, then use a java.util.Random variable, say called random and simply call random.nextInt(icons.length) to get a random index for my array.
As an aside, please for your own sake, don't use null layout and absolute positioning. Your grid of JButtons is begging to be held in a GridLayout-using JPanel. Begging.
As an aside, why are you posting questions on the same project but using different names? You've similar posts but different user names in both of your other posts here:
JButtons won't update on button click
My New Game JButton is not working?
Before you set the icons on the JButton use this shuffle function...
public ImageIcon[] shuffle(ImageIcon[] icons)
{
int index = 0;
ImageIcon temp = 0;
for(int i = icons.length -1; i > 0; i--)
{
index = r.nextInt(i + 1);
temp = icons[index];
icons[index] = icons[i];
icons[i] = temp;
}
return icons;
}
I am trying to make a memory game with Java. The game is basically going to be some squares in a grid that is 4x4 at the moment just for testing purposes. I have created my Square class, and programmed what i want them to do in that class, and then created a square object in another Class that handles the "Normal Mode" of the game. Now since i have a 4x4 grid of squares I need to make 16 different Squares (Or at least that's what i'm thinking at the moment). I also need to draw the Squares in their corresponding place.
My Question: What is the most efficient way of creating 16 of these Square objects while still being able to manipulate them individually? (Sort of like each having their own name; Square, Square1, Square2, etc).
I am also using the Slick2D library.
As mentioned above, Square[][] squareGrid = new Square[4][4] is a good way to go about this;
then you can initialize all 16 of them using:
for (int i = 0; i < squareGrid.length; i++)
for(int j = 0; j < squareGrid[i].length; j++)
squareGrid[i][j] = new Square();
now each square automatically has its own unique (row, col) id.
for example,
squareGrid[1][2].callSomeFunctionInSquareClass();
can be used to manipulate the square at 2nd row, 3rd column.
This way you will avoid scanning through all the squares to get the one at a particular cell on the grid, thus making it much more efficient.
happy coding :)
You can try Square[][] grid = new Square[4][4]
I would use a Square[][] array, e.g. Square[][] squares = new Square[4][4], and then initialise it with all 16 Squares in two nested loops:
for (int x = 0; x < squares.length) x++)
for (int y = 0; y < squares[x].length; y++)
squares[x][y] = new Square(x, y);