Let's suppose I've a list of String like this
List<String> button_names={"Button1","Button2","Button3","Button4"};
I've to insert JButtons with those texts in a JPanel so I do
for (int i=0; i<button_names.length; i++)
myJPanel.add(new JButton(button_name[i]));
My question is... If my model (in this case, my List button_names) changes for any reasons, how can I refresh my JPanel in order to show that change?
Should I do
myJPanel.removeAll()
and insert again my JButtons()? Thank you in adance
Yes removeAll and then reinserting new buttons is the easiest and generally the best way to go. Otherwise, you have to start figuring out which buttons have been removed, which have been added, and where in the list these new buttons are. Also, buttons in the list should change position I guess, so you'd have to cover that case to.
You can write a method like this that you could use in initial creation, and when you want to reload the list
void addButtonsToPanel(JPanel p) {
p.removeAll();
for (int i=0; i<button_names.length; i++)
myJPanel.add(new JButton(button_name[i]));
validate();
repaint();
}
Related
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);
}
For my Project i have to be able to add/remove boats to a fleet.I would like to use a Jbutton for that. I have 10 buttons which 5 are boats and i want to add them to fleet. Code for 1 of 10 jbutton using addActionListener() the thing im trying to do is that if a press a boat button it will print out in a textarea one after another (like a receipt). i have the same code structer for all buttons my second question is-Is there a way of making the code a bit shorter.
button9.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) {
addBoat.setVisible(true);
button6.setVisible(true);
button7.setVisible(true);
button8.setVisible(true);
button9.setVisible(true);
button10.setVisible(true);
text.setText(john.getText());
text.validate();
okButton.setVisible(true);
}
});
What you did is probably the simplest way that I know of. The only way to make it slightly shorter would be to make an array that includes all of the buttons then make a for loop that does that for you. An example of setting up the array would be:
JButton[] boats = new JButton[5];
And then the for loop would be:
for(int n = 0; n < boats.length; n++){
boats[n].setVisible(true);
}
The only thing I left out is actually adding the JButtons to the array, but this should do it. In the future I would recommend using more helpful names for your buttons to make it easier for others to read your 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.
I intend to take the elements of an integer list and add it to a label and print them in downward fashion one after another. I wrote the following code for it.
public static JFrame ListDraw(JFrame frame , ArrayList<Integer> e)
{
for(int i= 0;i<e.size();i++)
{
JLabel j = new JLabel(e.get(i).toString(),JLabel.CENTER);
frame.add(j);
}
return frame;
}
But it just prints the last array element in the label. What am I doing wrong here?
---------------------(update)
This is just a query that I have regarding the same thing. Therefore I am going to ask it here only. Is there any way to print the label items in a stack as in vertical alignment. Right now I get all the values printed in the horizontal fashion.
I guess you need to set layout for your frame, f.ex: frame.setLayout(new FlowLayout());.
Your frame isn't adapting to the new group of elements- the LayoutManager isn't getting a chance to resize the window. At the end of your function, add frame.pack().
You should use setBounds() to define the size of your frame and give it a LayoutManager of your choice.
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