I have the following window. I need to be able to edit the text when I click on the JTextField.
Explanation: JTextField is inside a JComponent called PriorityPanel. When I click on JTextField, it calls this.requestFocus(); meaning that the PriorityPanel will gain focus.
This way I cannot edit the text of the TextField.
In comparison, I can still modify the value of JSlider even if it bahaves exactly the same way. When I click on JSlider, the PriorityPanel will gain focus.
The described problem is in this part:
//constructor
public PriorityPanel(Priority p, int row) {
this.Slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
this.model = p;
this.rowName = row;
this.TextField = new JTextField(model.getTitle());
setLayout(new GridLayout(1, 2));
add(TextField);
add(Slider);
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
TextField.setBackground(new Color(220, 220, 255));
Slider.setBackground(new Color(220, 220, 255));
JPriorityEditor.this.selectedRow = rowName;
}
@Override
public void focusLost(FocusEvent e) {
TextField.setBackground(Color.WHITE);
Slider.setBackground(Color.WHITE);
}
});
Slider.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
requestFocus();
}
});
TextField.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
requestFocus();
}
});
//atc
}
Here is the SSCCE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import static test.Priority.staticPriorities;
class Main{
public static void main(String[] args) {
staticPriorities.add(new Priority("AutoGen1"));
staticPriorities.add(new Priority("AutoGen2"));
GridBagConstraints gbc = new GridBagConstraints();
JPanel panelAll = new JPanel(new GridBagLayout());
JPanel panelBottom = new JPanel(new GridLayout(1,2));
JButton buttonNew = new JButton("buttonNew");
JButton buttonRemove = new JButton("buttonErase");
final JPriorityEditor priorityEditor = new JPriorityEditor();
//Add to panelBottom
panelBottom.add(buttonNew);
panelBottom.add(buttonRemove);
//Add to panelAll
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
panelAll.add(priorityEditor, gbc);
gbc.weighty = 0;
gbc.gridy = 1;
panelAll.add(panelBottom, gbc);
buttonNew.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
priorityEditor.AddNewPriority();
}
});
buttonRemove.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
priorityEditor.RemovePriority();
}
});
JFrame d = new JFrame("windowPrioritiesTitle");
d.add(panelAll, BorderLayout.CENTER);
d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.pack();
d.setMinimumSize(d.getSize());
d.setLocationRelativeTo(null);
d.setVisible(true);
}
}
/**
* This is only an object
* @author Daniel
*/
class Priority {
public static ArrayList<Priority> staticPriorities = new ArrayList<>();
private String Title;
private int Percent;
public Priority(String title) {
this.Title = title;
int sum = 0;
for (Priority p : staticPriorities) {
sum += p.Percent;
}
this.Percent = 100 - sum;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
this.Title = title;
}
public int getPercent() {
return Percent;
}
public void setPercent(int newValue) {
this.Percent = newValue;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Priority) {
return ((Priority) obj).getTitle().equals(this.getTitle());
} else {
return false;
}
}
}
/**
* My own component
*/
public final class JPriorityEditor extends JScrollPane {
private PriorityPanel[] priorityPanels;
private int selectedRow;
private JPanel con;
public JPriorityEditor() {
super(new JPanel());
this.selectedRow = -1;
ArrayList<Priority> Priorities = Priority.staticPriorities;
priorityPanels = new PriorityPanel[Priorities.size()];
this.con = (JPanel) getViewport().getView();
con.setLayout(new GridBagLayout());
con.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
int i = 0;
for (; i < Priorities.size(); i++) {
gbc.gridy = i;
priorityPanels[i] = new PriorityPanel(Priorities.get(i), i);
con.add(priorityPanels[i], gbc);
}
gbc.weighty = 1;
gbc.gridy = i;
con.add(new JComponent(){},gbc);
}
public void AddNewPriority(){
con.removeAll();
Priority p = new Priority("NewTitle");
Priority.staticPriorities.add(p);
ArrayList<Priority> Priorities = Priority.staticPriorities;
priorityPanels = new PriorityPanel[Priorities.size()];
con.setLayout(new GridBagLayout());
con.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
int i = 0;
for (; i < Priorities.size(); i++) {
gbc.gridy = i;
priorityPanels[i] = new PriorityPanel(Priorities.get(i), i);
con.add(priorityPanels[i], gbc);
}
gbc.weighty = 1;
gbc.gridy = i;
con.add(new JComponent() {
}, gbc);
con.updateUI();
}
public void RemovePriority() {
if (selectedRow != -1) {
Priority.staticPriorities.remove(Priority.staticPriorities.get(selectedRow));
con.removeAll();
ArrayList<Priority> Priorities = Priority.staticPriorities;
priorityPanels = new PriorityPanel[Priorities.size()];
con.setLayout(new GridBagLayout());
con.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
int i = 0;
for (; i < Priorities.size(); i++) {
gbc.gridy = i;
priorityPanels[i] = new PriorityPanel(Priorities.get(i), i);
con.add(priorityPanels[i], gbc);
}
gbc.weighty = 1;
gbc.gridy = i;
con.add(new JComponent() {
}, gbc);
con.updateUI();
}
}
/**
* Another custom component
*/
private class PriorityPanel extends JComponent {
int rowName;
JSlider Slider;
JTextField TextField;
Priority model;
public PriorityPanel(Priority p, int row) {
this.Slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
this.model = p;
this.rowName = row;
this.TextField = new JTextField(model.getTitle());
setLayout(new GridLayout(1, 2));
add(TextField);
add(Slider);
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
TextField.setBackground(new Color(220, 220, 255));
Slider.setBackground(new Color(220, 220, 255));
JPriorityEditor.this.selectedRow = rowName;
}
@Override
public void focusLost(FocusEvent e) {
TextField.setBackground(Color.WHITE);
Slider.setBackground(Color.WHITE);
}
});
Slider.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
requestFocus();
}
});
TextField.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
requestFocus();
}
});
Slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int value = Slider.getValue();
model.setPercent(value);
}
});
TextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
SetText();
}
@Override
public void removeUpdate(DocumentEvent e) {
SetText();
}
@Override
public void changedUpdate(DocumentEvent e) {
SetText();
}
private void SetText() {
model.setTitle(TextField.getText());
}
});
}
}
}
From the looks of things, you are trying to modify the state of the parent container when one of the child components becomes focused.
Instead of trying to add a focus listener to the parent container, which is going to cause you some considerable havoc, try adding a single
FocusListener
to all the child components, for example...Now, I would be taking a peek at the
KeyBoardFocusManager#getFocusOwner
and back tracking it's container hierarcy when everfocusLost
is called to try and determine if the component who now has focus is a child of mine...