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;
}
Related
I am trying to Randomize the colors automatically on a single button click. I am able to randomize and display the background color, but I have to click the button each time to get a different color. I am trying to click the button once and it automatically loop through the array and display the colors automatically. I know I need some form of loop around the array, but I have no clue where to put it.
private View windowView;
private Button clickMe;
private int[colors];
colors=new int[]{Color.CYAN, Color.GREEN, Color.RED};
for (int i = 0; i < colors.length; i++) {
Random random = new Random();
int randomNum = random.nextInt(colorArrayLength);
windowView.setBackgroundColor(colors[randomNum]);
}
I do not understand why this is not looping through the array. Any hints and assistance would be much appreciated.
I believe you are randomly selecting the color and setting it in the background. However as it is inside a loop, it is changing so fast that the change is not notable in the visual rendering. You need to pause few milliseconds to see the change visually.
You may try out out the following:
private View windowView;
private Button clickMe;
private int[colors];
colors=new int[]{Color.CYAN, Color.GREEN, Color.RED};
final int[] finalColors = colors;
final View finalWindowView = windowView;
for (int i = 0; i < finalColors.length; i++) {
Random random = new Random();
final int randomNum = random.nextInt(finalColors.length);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Do after 500ms
finalWindowView.setBackgroundColor(colors[randomNum]);
}
}, 500 * i);
}
Try out this it will helpful to you
private int getMatColor(String typeColor)
{
int returnColor = Color.BLACK;
int arrayId = getResources().getIdentifier("mdcolor_" + typeColor, "array", getApplicationContext().getPackageName());
if (arrayId != 0)
{
TypedArray colors = getResources().obtainTypedArray(arrayId);
int index = (int) (Math.random() * colors.length());
returnColor = colors.getColor(index, Color.BLACK);
colors.recycle();
}
return returnColor;
}
Your code isn't really randomizing an array, but simply picking a random color from your array.
There's a slight difference in this. Randomizing an array means the order of every item in your array becomes randomized. There is no way for repeats to be possible for this.
Whereas, randomly selecting a color from your array might make it possible for you to have the same color selected.
What you're doing is the latter and it's doing that task properly.
Therefore, your code isn't considered looping through an array. You're simply selecting a random color from the array for n number of times, with n being the size of your array.
Additionally, the colors you're randomly picking aren't displaying to windowView because the colors are being changed immediately.
For example, your for loop might turn windowView to CYAN, but immediately afterwards the loop will change it to RED. Thus, it'll only display the very last random value that is selected from your array and you won't see any of the previous color changes.
If you want to see the changes, you need to add a delay between each random color change.
What's colorArrayLength? no this variable. Codes like below are run normally.
for (int i = 0; i < colors.length; i++) {
Random random = new Random();
int randomNum = random.nextInt(colors.length);
button.setBackgroundColor(colors[randomNum]);
}
But even this, the view's background color is the last color after loop, you can not see the result of color looping effect. If you want to see the process of color changing, maybe add Timer.schedule() method.
I am trying to make a small application in Java Swing using JFrame form. I added buttons from palette to panel in specific positions and now want to add these buttons to an array but I don't know the data type used for array that holds these designed buttons. I searched for it but didn't find anything related to my problem. I am new to coding and have very limited knowledge about Java - any help will be greatly appreciated.
I you want to have a flexible list of buttons, just declare a List of JButton.
List<JButton> listOfButton = new ArrayList<>();
JButton[] buttons = new JButton[10];
Just like any other arrays.
Here i am writing the code by using which i added my buttons to arrayList and getting it back.
// creating an ArrayList
ArrayList<JButton> btn = new ArrayList<JButton>();
// adding Buttons to ArrayList
btn.addAll(Arrays.asList(Button1, Button2, Button3,........));
//instead of writng btn.add(Button1);btn.add(Button2); and so on, use addAll();
// getting buttons from ArrayList
for (int i = 0; i < btn.size(); i++){
btn.get(i);
}
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.
I have a problem regarding loops. I need to access 10 labels which have names like label1, label2, label3 .... etc. I need to know whether I can access those labels by going through a loop in java?
How about using List or an array
List<JLabel> labels = new ArrayList<JLabel>();
labels.get(index);
Change those labels to be an array, and access it using an index.
For example:
JLabel[] labels = new JLabel[10];
for (int i = 0; i < labels.length; ++i) {
labels[i] = new JLabel("Label " + i);
}
for (int i = 0; i < labels.length; ++i) {
// access each label.
}
Put your labels in to LinkList or array
Then you can access those array or linkList on a loop
If you cannot change the labels names / put them into an array you can make an array of references to the labels and fill it at the beginning of your program with the list of your labels.
'Access to labels' is kinda vague. Are you referring to different instances of java.awt.label? If so you can simply loop over them when they're in a list with a for-each statement.
If you are talking about Java labels, you can use a switch statement instead. If you are talking about objects such as a JLabel, use an array or ArrayList.
I am currently writing a sudoku solver in Java. What I need now is some kind of Swing GUI to input the known numbers. I created a JFrame, but manually adding 81 text fields from the toolbox seems like a bad solution. I am also able to add with code like this:
this.setLayout(new GridLayout(9, 9));
for (int i = 0; i < 81; i++)
{
this.add(new JTextField("Field"));
}
However, I do not know how to address these text fields afterwards to collect the user input into a two-dimensional array. How can I do that?
A different solution would be to use a JTable. You could allow for the TableModel to maintain the full data solution, as well as a copy of the user's attempts. The CellRenderers and CellEditors could handle the user experience. See this tutorial.
Struggled a bit with this for my own sudoku solver, but ended up going for painting on a JPanel, and adding a mouse listener to that.. Than determine the current field using mouse position with his function:
addMouseListener(new MouseAdapter() {
private int t(int z) {
return Math.min(z / factor, 8);
};
#Override
public void mouseMoved(MouseEvent e) {
setToolTipPossibilities(t(e.getX()), t(e.getY()));
}
#Override
public void mousePressed(MouseEvent e) {
clickColumn = t(e.getX());
clickRow = t(e.getY());
}
});
First you need to declare array of JTextFields.
So just like your array to store user input you do:
private JTextField[] textFields;
After that you can use some math to map your one-dimensional array to your two dimensions.
something like this should work:
floor(index / 9), index % 9
for x,y
Yes that will work to display the array. To read from the array you just need to call the getText method for each element.
JTable is your friend. Use a DefaultTableModel with editable String values.
String[] columnNames = new String[9];
for(int i=0; i<9; i++){columnNames[i]="";}
String[][] data = new String[9][9];
JTable tab = new JTable(columnNames,data);
When they fill it in, check that each string is an appropriate number and prompt for error.
1st way:
You could put the text fields into an array that mirrors the array that your cell values are in.
The problem with this method tho is that when you need to bind a mouseListener or ActionListener to the TextField you will have a hard time figuring out which cell number it corrisponds to.
2nd way:
You could extend the JTextField into a custom class with new instance variables that store cell number in it.
Using this method you can also implement MouseListener or ActionListener on the extended class too and get whatever information about the field you need, without searching through your array. And combining with the first to put them into an array organizes them for quick access.
Just want to post a little update.
I added an array of textfields as a field on my form:
private JTextField[] fields;
Initialized it:
fields = new JTextField[81];
And finally I am adding the fields to my form like this:
private void addComponents()
{
this.setLayout(new GridLayout(9, 9));
for (int i = 0; i < fields.length; i++)
{
fields[i] = new JTextField("" + i);
this.add(fields[i]);
}
}
The result as of now can be seen here:
Image of my textfields