Reputation: 353
I'm trying to repaint a panel but it won't work. Basically my panel takes in an ArrayList and then for each element in the ArrayList, it prints it out. When I click on a button, it removes that respective element of the ArrayList and then calls for the entire panel to repaint itself. I expect it after the repaint to show the same panel but without that politician but clicking the button does nothing. It does affect the message though so clearly the politician is being removed from the list but it is not being removed from the JPanel.
class fakeMPTable extends JPanel //table using Grid Layout
{
public void refresh()
{
revalidate();
repaint();
}
public fakeMPTable()
{
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
for (int i=0; i<politicians.size();i++)
{
final int j=i;
JLabel politician = new JLabel(politicians.get(j));
JButton delete = new JButton();
delete.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int selectedOption = JOptionPane.showConfirmDialog(null,
"Are you sure you want to delete \'" + politicians.get(j)+"\'?",
"Warning",
JOptionPane.YES_NO_OPTION);
if (selectedOption==0)
{
politicians.remove(j);
refresh();
}
}
}
c.gridy++;
add(delete, c);
add(politician,c);
}
Upvotes: 1
Views: 616
Reputation: 347334
Basically, you are not removing the components associated with the select politician.
You have a couple of possible solutions.
Create a seperate List
for the labels and buttons, where each item match the same item in the politicians
list.
This would mean that when you access the n
politician, you could access the associated label and button using the same index...
class FakeMPTable extends JPanel //table using Grid Layout
{
private List<String> politicians;
private List<JLabel> labels;
private List<JButton> buttons;
public void refresh() {
revalidate();
repaint();
}
public FakeMPTable() {
politicians = new ArrayList<>(25);
for (int index = 0; index < 26; index++) {
politicians.add(Character.toString((char) ('A' + index)));
}
labels = new ArrayList<>(25);
buttons = new ArrayList<>(25);
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
for (int i = 0; i < politicians.size(); i++) {
final int j = i;
JLabel politician = new JLabel(politicians.get(j));
JButton delete = new JButton();
labels.add(politician);
buttons.add(delete);
delete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int selectedOption = JOptionPane.showConfirmDialog(null,
"Are you sure you want to delete \'" + politicians.get(j) + "\'?",
"Warning",
JOptionPane.YES_NO_OPTION);
if (selectedOption == 0) {
politicians.remove(j);
remove(labels.remove(j));
remove(buttons.remove(j));
refresh();
}
}
});
c.gridy++;
add(delete, c);
add(politician, c);
}
}
}
This has problems in the fact that it is to easy for the list to become unsynced, meaning that the indexes no longer match up...
Map each button and label to a politician...
class FakeMPTable extends JPanel //table using Grid Layout
{
private List<String> politicians;
private Map<String, JLabel> labels;
private Map<String, JButton> buttons;
public void refresh() {
revalidate();
repaint();
}
public FakeMPTable() {
politicians = new ArrayList<>(25);
for (int index = 0; index < 26; index++) {
politicians.add(Character.toString((char) ('A' + index)));
}
labels = new HashMap<>(25);
buttons = new HashMap<>(25);
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
for (int i = 0; i < politicians.size(); i++) {
final int j = i;
JLabel politician = new JLabel(politicians.get(j));
JButton delete = new JButton();
labels.put(politicians.get(j), politician);
buttons.put(politicians.get(j), delete);
delete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int selectedOption = JOptionPane.showConfirmDialog(null,
"Are you sure you want to delete \'" + politicians.get(j) + "\'?",
"Warning",
JOptionPane.YES_NO_OPTION);
if (selectedOption == 0) {
String key = politicians.remove(j);
remove(labels.remove(key));
remove(buttons.remove(key));
refresh();
}
}
});
c.gridy++;
add(delete, c);
add(politician, c);
}
}
}
This is a slightly better solution as it maps the politician name directly to the buttons and labels, making it more difficult for the lists to become unsynced.
Upvotes: 1
Reputation: 133619
You need to alter the structure of the JPanel
itself, otherwise you ask for revalidate()
but nothing has changed.
You should factor out the part of code which adds the entries and button to the JPanel
so that you can call it in the beginning and then in the ActionListener
by first removing elements:
this.removeAll();
this.addEntriesAccordingtoList();
this.revalidate();
Upvotes: 3