JCombobox and JTextfield - java

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.

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.

Adding a new button after an event

Writing a program to increment a counter when a +1 button is pressed, then when the counter reaches a certain number, remove the +1 button and replace it with a +2 button and so on. I create both buttons at first but just set btnCount1 to setVisible(false). When the certain number passes, I make btnCount invisible and btnCount1 visible and increment by two from there. When it reaches 10 clicks, the btnCount disappears, but btnCount1 does not appear.
I have tried making an if(arg0.equals(btnCount1)), and incrementing by two from there. I tried putting the add(btnCount1) inside the else if statement to create it after the elseif condition is true.
public class AWTCounter extends Frame implements ActionListener
private Label lblCount;
private TextField tfCount;
private Button btnCount;
private Button btnCount1;
private int count = 0;
public AWTCounter() {
setLayout(new FlowLayout());
lblCount = new Label("Counter");
add(lblCount);
tfCount = new TextField(count + "",10);
tfCount.setEditable(false);
add(tfCount);
btnCount = new Button("Add 1");
btnCount1 = new Button("Add 2");
add(btnCount);
add(btnCount1);
btnCount1.setVisible(false);
btnCount.addActionListener(this);
btnCount1.addActionListener(this);
setTitle("AWT Counter");
setSize(500,500);
}
public static void main(String[]args) {
AWTCounter app = new AWTCounter();
}
public void actionPerformed(ActionEvent arg0) {
if(count <= 10) {
++count; //Increase the counter value
tfCount.setText(count + "");
}else if(count > 10) {
btnCount.setVisible(false);
btnCount1.setVisible(true);
count += 2;
tfCount.setText(count + "");
}
}
The better solution here is to just have one button object and a separate variable for the current increment amount. When you hit the required count, increase the increment amount and change the button's label to the new value.
There are also a few other things you could do better here.
Use String.valueOf() instead of int + "" for String representations of integers if you're not adding words before or after the integer.
Don't add obvious comments for code. (e.g. 'increment variable x', 'set textString to the new value')
Use descriptive names for method parameters and variables.
Use Labels instead of TextFields for text that doesn't need to be editable or selectable like counter displays.
I'd personally change the name of lblCount to something like lblTitle as well, since changing your tfCount to a Label would logically take up that name and lblTitle makes more sense.
Here's a better way to implement actionPerformed:
private int increment = 1;
private Label lblCount;
...
public void actionPerformed(ActionEvent ignore) {
if(count == 10) {
btnCount.setLabel("Add " + (++increment));
}
lblCount.setText(String.valueOf(count += increment));
}

How to make some of jtextfield & jlabel not appear in JPanel

I am currently making a GUI that prints a textarea. In this textarea I am required to receive the "weights" for the ID of the variable.
I have created multiple labels showing from ID1: - ID8: & their textfields, and use if statements instead but the with the amount of if and else if.
if (id.size = 1){
id1.setvisible(true);
weight1TField.setvisible(true);
}else if (id.size = 2){
id1.setvisible(true);
weight1TField.setvisible(true);
id2.setvisible(true);
weight2TField.setvisible(true);
}
else if (if.size = 3){
id1.setvisible(true);
weight1TField.setvisible(true);
id2.setvisible(true);
weight2TField.setvisible(true);
id3.setvisible(true);
weight3TField.setvisible(true);
}
So on... untill ID8.
The values are added to the array from a jtable in another Jframe when user has selected the rows(maximum 8 rows).
List<String> ID = new ArrayList<>();
I want to create text fields to allow the user to input their weights and jlabels showing the ID beside the textfield e.g ID: TextField. Image is shown below
ID[i] is replaced with the value in the array if there is one while the rest is hidden if there is no value. How can i create the Jlabels and JTexFields without doing the following below.
ID1.setText(ID[0]);
ID2.setText(ID[1]);
ID3.setText(ID[2]);
ID4.setText(ID[3]);
ID5.setText(ID[4]);
ID6.setText(ID[5]);
ID7.setText(ID[6]);
ID8.setText(ID[7]);
What about instead of using fields (I am not sure you are using fields, but the only thing i can do without more code is guess) to store the components into arrays? I have done an example with JLabels, you can do the same with textfields.
private static int idsCount = 6; //The number of ids. Let's say 6
private JLabel[] labels = new JLabel[8]; // Keep the array as a field. (8 = max capacity)
private void initIDLabels {
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel();
// add this font to all labels.
labels[i].setFont(new Font("Tahoma", Font.BOLD, 12));
}
changeLabelsVisibility();
}
private void changeLabelsVisibility() {
// Hide all labels.
for (JLabel label : labels) {
label.setVisible(false);
}
// Show all labels that supposed to be visible
for (int i = 0; i < idsCount; i++) {
labels[i].setVisible(true);
}
}

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.

Collecting data from a large number of Swing text fields

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

Categories