I am trying to figure out how I can also change my int if my Jlabel is changed. I tried to use AtomicInteger and it works if I only want to change n1, but how do I make it that it looks at the label and then changes the correct int? At the moment I have n1 - n3, but in the future that will be 30.
This is my code at the moment:
public class GUI {
JLabel currentEditLabel = null;
JFrame frame;
int n1 = 6;
int n2 = 5;
int n3 = 8;
GUI() {
frame = new JFrame();//creating instance of JFrame
JLabel l1 = new JLabel(Integer.toString(n1));
JLabel l2 = new JLabel(Integer.toString(n2));
JLabel l3 = new JLabel(Integer.toString(n3));
JTextField t = new JTextField();
l1.setBounds(40, 50, 100, 40);
l2.setBounds(40, 100, 100, 40);
l3.setBounds(40, 150, 100, 40);
t.setBounds(20, 200, 100, 40);
frame.add(l1);
frame.add(l2);
frame.add(l3);
frame.add(t);
t.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (currentEditLabel != null) {
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
n1 = level.intValue();
currentEditLabel = null;
}
}
});
addMouseListener(l1, t);
addMouseListener(l2, t);
addMouseListener(l3, t);
frame.setSize(400, 500);//400 width and 500 height
frame.setLayout(null);//using no layout managers
frame.setVisible(true);//making the frame visible
}
private void addMouseListener(JLabel label, JTextField t) {
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
currentEditLabel = (JLabel) e.getComponent();
t.setText(currentEditLabel.getText());
}
});
}
public static void main(String[] args) {
new GUI();
}
}
Thanks in advance
CodePudding user response:
AtomicInteger? You're barking up the wrong tree since this won't help you in the least.
Your n1
value does in fact change within the listener, but you're not changing the JLabel text at all, and that is what you need to do:
- In the MouseListener, also call
setText(...)
on whatever JLabel (the one clicked perhaps) that you wish to have the text display change on. - While the
l1
JLabel's displayed text is created usingn1
's value, note that ifn1
ever changes,l1
s text will not change on its own. Again, if you wish to changel1
's text, you must do so with code, calling.setText(...)
on it.
Some suggestions based on your new requirements:
- Create an array of int to hold the int values
- Create a
List<JLabels>
to hold all the JLabels that will display the values held in the above collection of numbers - Create your JLabels in a for loop that loops through all the ints, and fill each JLabel with the appropriate number text
- In that same for loop, add your JLabels to the JLabel-list mentioned above
- Add a MouseListener (I usually use a MouseAdapter for this) to each JLabel in the for loop
- Pass the for loop's index into your MouseListener's constructor to set a field of the class, so that the index of the selected JLabel is readily available
- Use a JSpinner and SpinnerNumberModel to display the changable text
- In the MouseLister, set the value that the spinner holds
- Add a ChangeListener to the spinner so that when the numeric value changes, you update the appropriate JLabel with the new value
- You will need to also remove the above ChangeListener before setting the spinner's value in the mouse listener and then re-add the same listener immediately after making this change.
- Do not use AtomicInteger as it is completely unnecessary and is somewhat misleading to you
- Avoid using null layouts but instead use layout managers
Proof of concept:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@SuppressWarnings("serial")
public class GUI2 extends JPanel {
private static final Border UNSELECTED_BORDER = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 3);
private static final Border SELECTED_BORDER = BorderFactory.createLineBorder(Color.PINK, 3);
private int[] intArray = { 6, 5, 8, 13, 17, 22, 55, 33, 2, 0, 23, 51, 0, 111, 200, 6, 5, 8, 13, 17, 22, 55, 33, 2,
0, 23, 51, 0, 111, 200, 6, 5, 8, 13, 17, 22, 55, 33, 2, 0, 23, 51, 0, 111, 200 };
private SpinnerNumberModel spinnerModel = new SpinnerNumberModel(0, 0, 10000, 1);
private JSpinner intSpinner = new JSpinner(spinnerModel);
private ChangeListener spinnerListener = new SpinnerListener();
private List<JLabel> labelList = new ArrayList<>();
private int selectedIndex = -1;
public GUI2() {
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Current Selected Value:"));
topPanel.add(Box.createHorizontalStrut(5));
topPanel.add(intSpinner);
intSpinner.addChangeListener(spinnerListener);
int gap = 3;
JPanel labelGridPanel = new JPanel(new GridLayout(0, 5, gap, gap));
for (int i = 0; i < intArray.length; i ) {
String text = String.valueOf(intArray[i]);
JLabel label = new JLabel(text);
label.setBorder(UNSELECTED_BORDER);
label.addMouseListener(new MyMouse(i));
labelGridPanel.add(label);
labelList.add(label);
}
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new BorderLayout(gap, gap));
add(topPanel, BorderLayout.PAGE_START);
add(labelGridPanel, BorderLayout.CENTER);
}
private class MyMouse extends MouseAdapter {
private int index;
public MyMouse(int index) {
this.index = index;
}
@Override
public void mousePressed(MouseEvent e) {
selectedIndex = index;
JLabel label = labelList.get(index);
int currentValue = Integer.parseInt(label.getText());
// remove change listener before making this change
intSpinner.removeChangeListener(spinnerListener);
intSpinner.setValue(currentValue);
// then re-add the change listener after
intSpinner.addChangeListener(spinnerListener);
// show by border which JLabel has been selected
for (JLabel jLabel : labelList) {
// first make all borders the default border
jLabel.setBorder(UNSELECTED_BORDER);
}
// then set the selected border
labelList.get(index).setBorder(SELECTED_BORDER);
}
}
private class SpinnerListener implements ChangeListener {
@Override
public void stateChanged(ChangeEvent e) {
// if we have not yet selected a JLabel, get out of here
if (selectedIndex < 0) {
return;
}
int value = (int) spinnerModel.getValue();
labelList.get(selectedIndex).setText(Integer.toString(value));
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
GUI2 mainPanel = new GUI2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
CodePudding user response:
In your code, you only update n1
regardless of which label is the currentEditLabel.
Your code:
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
n1 = level.intValue();
currentEditLabel = null;
Solution: You need to know which label is the currentEditLabel so that you can update the correct variable. Your action listener will need access to l1, l2 and l3. So, instead of defining them in the constructor, define them as instance variables same way you defined n1, n2, and n3.
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
if (currentEditLabel == l1)
n1 = level.intValue();
else if (currentEditLabel == l2)
n2 = level.intValue();
else
n3 = level.intValue();
currentEditLabel = null;