Reputation: 1125
I had developed the below window.
I want to develop the DELETE functionality. While clicking the DELETE button, the corresponding TextField should be removed from the window.
I will attached the design code below - Only for the Add More Files
button action.
While clicking the Add More Files
button, another TextField and DELETE button is creating and adding to the headerpanel
. S I have no way to connect these TextField and Button(in the same Line). I know this is not the correct format of developing this type windows.
How can I design(or redesign) to meet the DELETE functionality?
Add More Files
Action code:
cAttach.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt)
{
File file = null;
int returnVal = fc.showOpenDialog(EMailDialog.this);
if ((returnVal == javax.swing.JFileChooser.APPROVE_OPTION))
{
attachments.add(fc.getSelectedFile());
file = fc.getSelectedFile();
fieldPosition += 5;
CTextField cFileNew = new CTextField();
headerPanel.add(cFileNew, new GridBagConstraints(0, fieldPosition,
5, 1, 0.0, 0.0, GridBagConstraints.EAST,
GridBagConstraints.HORIZONTAL, new Insets(7, 80, 5,
185), 0, 0)); // Text field
//thush
CButton cDelete= new CButton("Delete");
headerPanel.add(cDelete, new GridBagConstraints(0, fieldPosition , 5,
1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
new Insets(7, 425, 5, 105), 0, 0)); // thush
cFileNew.setText("" + file);
listOfTextFields.add(cFileNew);
headerPanel.updateUI();
mainPanel.updateUI();
}
}
});
Upvotes: 2
Views: 762
Reputation: 17971
IMO this is a good use case for combining Action and setClientProperty(key, value) / getClientProperty(key) in order to anonymize the action itself as much as possible.
Let me explain a little: you need to add a pair of text field-delete button every time you attach a new file, right? The action to be performed when you press the delete button is always the same: remove both the button and the associated text field from its parent container (I guess it's headerPanel
). This is what I'd do:
1) Define a single and common action as follows. This action should be attached to all delete buttons.
final Action deleteAction = new AbstractAction("Delete") {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
JTextField textField = (JTextField)button.getClientProperty("AssociatedTextField");
if (textField != null) {
JComponent parentContainer = (JComponent)button.getParent();
parentContainer.remove(button);
parentContainer.remove(textField);
parentContainer.revalidate();
parentContainer.repaint();
SwingUtilities.windowForComponent(parentContainer).pack();
}
}
};
As you can see this action is intended to be attached to a button and looks for AssociatedTextField
client property. If the value retrieved by this request is not null then removes both button and associated text field from the parent container, revalidates the components hierarchy and finally packs the frame.
2) To make the previous code work properly you have to add the text field to the button client properties map as follows:
cAttach.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
...
CTextField cFileNew = new CTextField();
...
CButton cDelete = new CButton(deleteAction);
cDelete.putClientProperty("AssociatedTextField", cFileNew);
...
}
});
Note the button is created using the Action defined in the previous step.
3) Finally you don't have to call updateUI
(this method doesn't do what you think it does) but revalidate the components hierarchy and pack the frame in order to reflect the changes:
cAttach.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
...
headerPanel.revalidate();
headerPanel.repaint();
SwingUtilities.windowForComponent(headerPanel).pack();
}
});
Upvotes: 1
Reputation: 39477
You have a way to connect them. Just keep/store them them in e.g. a HashMap
where each Button
is mapped to its corresponding TextField
. When the Button
gets a click, just do a lookup in your HashMap
, pull the respective TextField
and do with it whatever is needed.
Upvotes: 2