How to rewrite the text of buttons that are not separately defined - java

I have started trying to write a code similar to the game 2048, however the size of the board can have any value depending on what the user inputs. I decided to make the numbers on the board, for style purposes, separate buttons.
This is the current GUI:
How can I make it so that when the buttons: up, down left, or right are pressed each of the button's in the board texts are changed? I know about event listeners I just mean how can I replace the button's in the same grid with different values when I defined the buttons on the board as:
`for(int i = 2; i < rows + 2; i++) {
for(int j = 2; j < columns + 2; j++) {
gbc.gridx = j;
gbc.gridy = i;
num = new JButton(board.board[j-2][i-2].getValue()+"");
num.setFont(new Font("monospaced", Font.PLAIN, screenSize.height/50));
num.setEnabled(false);
this.add(num, gbc);
}
}`
The only ideas I've had was to create an array of buttons and then change the button's text in the array of buttons and then replace the old array of buttons with the new one. Also sorry if it has some super simple answer that I just couldn't find, I am just about finished with one semester of coding courses in college.

You could store the JButtons on a HashMap and use column number and row number as a key to find the correct button.
Something like:
Map<String, JButton> grid = new HashMap<String, JButton>;
for(int i = 2; i < rows + 2; i++) {
for(int j = 2; j < columns + 2; j++) {
grid.put(String.valueOf(i) + String.valueOf(i), new JButton("some text"));
// we transform the integers into String, otherwise the operator "+" will sum them
// instead of concatenate them.
}
}
Now you cant get the desired button with grid.get(row + column);
JButton bt;
JButton bt = grid.get("4" + "6");
bt.setText("different text");
grid.put("4" + "6", bt);

I don't think you should use Buttons to do such a game button it's something that you can click on it since your are not supposed to click on numbers. If I were you I would use a gamePanel which contains fixed labels since it's easier changing text of label than moving label.
I would add MouseListener to the gamePanel and then fill implemented methods in order to manage when the mouse left button is pressed and move to left and so on.
So create an array of Label.
Create a method which add and move numbers according to the direction of the move. For instance if you make a left to right move you will start to add the numbers of the first column into the second column when they have same values. Next you just have to do it recursively until the last column.
If you need a bit more explainations ,I'll be pleased to help you.

Related

How to create references to objects created in a loop?

I'm sure this question has been asked but I cannot find it (on SO or Google) for my life.
How can I most effectively create a reference to multiple objects that I create in a loop?
In this specific case, I am using Swing to add JButtons to a GridLayout.
int numOfButtons = 10;
for (int i = 0; i < numOfButtons; i++){
add(new JButton("" + i));}
If later I want to change the text on the buttons, how would I do so? Say, if I wanted to change button number 8:
buttonEight.setText("DO NOT CLICK!!!);
How would I create a reference to the button with the 8 on it from buttonEight?
The only thing I can think of is creating a bunch of instance variables before the loop. Except... Well. Actually , that wouldn't work (I don't think)
Something that would do this:
JButton button8;
for (int i = 0; i < numOfButtons; i++){
button + i = new JButton(""+ i);
//like, if i = 8 then button + i gets me button8 to reference it or something?
//obviously that doesn't work
}
button8.setText("DO NOT CLICK!!!);
and also I'd be in trouble creating the right number of instance variables if numOfButtons is variable.
How should I do this?
Use an ArrayList:
ArrayList<JButton> list=new ArrayList<>();
int numOfButtons = 10;
for (int i = 0; i < numOfButtons; i++){
JButton jb=new JButton("" + i);
list.add(jb);
add(jb);
}
Later (assuming you want to change the text of 8th button (which is 7 in list)):
list.get(7).setText("...");
The list only create a reference to JButton object. Then any change made to it will reflect on the UI.
Or, if you wanted to set the text of only the eighth button, you could use a conditional to single out that button:
for (int i=0;i<numOfButtons;i++) {
if (i==7) {
add(new JButton("DO NOT CLICK!");
} else {
add(new JButton(""+i);
}
}
which will save memory space in your program than if you use an ArrayList.

How to find the ID Name of a JLabel Array in Java with MouseListener

What I have done.
I have created an array of JLabel like that:
static JLabel numbers[] = new JLabel[25];
I Have given to each of the numbers[each of this] a random number between 1 and 80.
I have added to each of numbers[] array a MouseListener.
I want to make something like, once I press a specific label to change itself background. But to do that I have to detect the ID of the JLabel has been pressed.
The Question:
How can I get the name or the number of the array on JLabel that has been pressed?
So far I only know how to get the text from it with the following code:
JLabel l = (JLabel) e.getSource();
int strNumber = Integer.parseInt(l.getText());
I want the ID of numbers[THIS], not the text but the number of array.
In Button listener, I know how to do that, but in MouseListener is not working...
(At least with the methods I tried to...(e.getSource().getName(); etc.)
You've got the array, you've got a reference to the pressed JLabel: e.getSource();, so simply iterate through the array to find the one that matches the other. e.g.,
#Override
public void mousePressed(MouseEvent e) {
Object source = e.getSource();
int index = -1;
for (int i = 0; i < numbers.length; numbers++) {
if (numbers[i] == source) {
index = i;
break;
}
}
}
// here index either == the array item of interest or -1 if no match
Side issue: that array should not be static, and that it is static suggests that you have some design issues with your program that need to be fixed.

Java GUI - Getting random value from array

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;
}

how to update a container in java that already has data in it

Hi all i need to update a containers data for a sudoku game i am creating but am struggling to get the field to update with the new data.the container uses a grid layout and each cell contains a button with the appropriate number for sudoku in it and i need to know how to update the text in these buttons. any help with what methods i could use or any help in general would be greatly appreciated. please see the code i currently have to try and update below i know its probably messy and completely on the wrong track but ive just been trying to mess with stuff hoping it would work.
public void update(int[][] grid2)throws NullPointerException{
myGrid = new Container();
try{
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
JButton button = new JButton(appropriateNumber);
button.addActionListener(new sudokuListener());
myGrid.add(button);
}
}
}
catch(NullPointerException e){
}
myGrid.setLayout(new GridLayout(9, 9));
myGrid.setPreferredSize (new Dimension(400, 400));
add(myGrid);
puzzleGUI.update();
}
puzzlGUI.update simply contains puzzle.validate() (puzzle being the GUI)
[edit]
ok i have changed things around a bit and used the JButton arrya as suggested and i have been able to set the text of the buttons in this array (i know through a system.out.print) but this does not update the text which is in the actual GUI. aaaaahhh coding is not fun at the end of a semester please help anyone
To re-iterate, if you have a grid of JButtons, why re-create them every time? Why not simply iterate through the components that are already in the grid and update their state, such as perhaps the text showing on the JButtons?
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
someButtonArray[i][j].setText(appropriateNumber);
// no longer need this stuff
// JButton button = new JButton(appropriateNumber);
// button.addActionListener(new sudokuListener());
// myGrid.add(button);
}
}
Your update method is creating new Swing components every time it is called which is unnecessary if you just need to update the text. To directly update the text in any JButton you could create a button array like so:
JButton[][] buttons = new JButton[9][9];
and create like this (called only once):
for (int i = 0; i<9; i++) {
for(int j = 0; j < 9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
button[i][j] = new JButton(appropriateNumber);
button[i][j].addActionListener(new sudokuListener());
myGrid.add(button[i][j]);
}
}
then to update :
buttons[row][column].setText("New Text");

JCombobox and JTextfield

I'm trying to work to display a number of jtextfield according to one of the given values in a combobox.
So, I will have a drop down menu with let's say 1 to 4. If the user selects number 3, 3 textfields will be displayed. I've created the jcombobox with a selection of numbers. But I'm not sure how to implement this. If I'm not mistaken I need to use
ItemEvent.SELECTED
I think I need to create a reference to the JTextField object that will be available to the JComboBox's itemListener object.
Any help would be greatly appreciated.
I've added this to my class :
// aOption is the combobox I declared
aOptionComboBox.setModel(new DefaultComboBoxModel(new String[]{"1","2","3"}));
public void itemStateChanged(ItemEvent event) {
String num = (String)aOptionComboBox.getSelectedItem();
int num1 = Integer.parseInt(num);
JTextField[] textfields = new JTextField[num1];
for (int i = 0; i < num1; i++)
{
textfields[i] = new JTextField("Field");
getContentPane().add(textfields[i]);
textfields[i].setBounds(200, 90, 100, 25);
}
}
am I on a right track?
use the getSelectedItem() on the combobox. This will either yield a string or an integer (depending on how you implemented it). Next use a for-loop to determine the amount of JTextField's and store them in an array.
int amount = myJComboBox.getSelectedItem();
JTextField[] textfields = new JTextField[amount];
for (int i = 0; i < amount; i++) {
textfields[i] = new JTextField("awesome");
this.add(textfields[i]);
}
this way you can easily store the textfields and add them to your panel.
Some added information.
The textfield-array must be accesible outside the eventListener, so you must implement it in your class. that way the whole class can use it.

Categories