Delete a specific button

I have a JPanel in a JFrame that contains 5 buttons. In another JPanel there is a button called "delete button", what I want to do is to click this button and than choose what button of the other 5 to delete by ckicking in one of them. Can anyone help me?

    public class gui extends JFrame implements ActionListener
    {
      JPanel p1 = new JPanel();
      JPanel p2 = new JPanel();
      JPanel p2 = new JPanel();

      JButton b1 = new JButton("Delete");
      JButton b2 = new JButton("A");
      JButton b3 = new JButton("B");
      JButton b4 = new JButton("C");

      gui()
      {
        p1.setLayout(new GridLayout(1,2));
        p1.add(p2);
        p1.add(p3);

        p2.setLayout(new GridLayout(3,1));
        p2.add(b2);
        p2.add(b3);
        p2.add(b4);
        p3.add(b1);

        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        b4.addActionListener(this);

      }

     public void actionPerformed(ActionEvent e)
     {
       if (e.getSource() == b1)
         // When I click this button I want to be able to delete a button of my choice (one of the other 3)
     }
   }

Upvotes: 3

Views: 22623

Answers (5)

MdaCosta
MdaCosta

Reputation: 49

The easiest method:

  1. Add an ActionListener to the button that will remove another one;
  2. Repaint and revalidate the panel where is the button to remove.

Example (in this case the button that will delete another one is called by "deleteBtn" and the button in the another panel that will be removed is called by "btnToDlt" that exists in the "panel"):

deleteBtn.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            panel.remove(btnToDlt);
            panel.revalidate();
            panel.repaint();
            
        }
            
            });

Upvotes: 0

aioobe
aioobe

Reputation: 420991

Here's a snippet of code to kick you off in the right direction:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class FrameTestBase extends JFrame {

    public static void main(String args[]) {
        FrameTestBase t = new FrameTestBase();

        final JPanel p = new JPanel();

        final JButton button = new JButton();

        button.setAction(new AbstractAction("Remove me!") {
            @Override
            public void actionPerformed(ActionEvent e) {
                p.remove(button);
                p.revalidate();
                p.repaint();
            }
        });

        p.add(button);
        t.setContentPane(p);

        t.setDefaultCloseOperation(EXIT_ON_CLOSE);
        t.setSize(400, 400);
        t.setVisible(true);
    }
}

Before click:

enter image description here

After click:

enter image description here


From the comments:

To generalize this, you could create an AbstractAction that takes the to-be-deleted button as argument. Use this AbstractAction, and update it as necessary whenever your delete-policy should change.

Upvotes: 2

Edwin Buck
Edwin Buck

Reputation: 70909

Use a chain of responsibility in the button listeners. One Button listener that listens for the "to be deleted" buttons and the "delete" button. Under normal operation this button listener just sends the "to be deleted" button events to the existing button events, but when it hears a "delete" button event, it then captures the "next" button event without sending it to the existing button listener, and acts to remove the button.

Ok you provided some code. Here is a solution that uses a chain of responsibility. Basically, if one ActionListener can't handle the event, it sends it to the next one, and so on.

import java.awt.GridLayou;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class Gui extends JFrame {

  public static final long serialVersionUID = 1L;

  JPanel p1 = new JPanel();
  JPanel p2 = new JPanel();
  JPanel p3 = new JPanel();

  JButton b1 = new JButton("Delete");
  JButton b2 = new JButton("A");
  JButton b3 = new JButton("B");
  JButton b4 = new JButton("C");

  public Gui() {

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    p1.setLayout(new GridLayout(1, 2));
    p1.add(p2);
    p2.add(p3);

    p2.setLayout(new GridLayout(3, 1));
    p2.add(b2);
    p2.add(b3);
    p2.add(b4);

    p3.add(b1);

    DoItListener doIt = new DoItListener(null);
    DeleteItListener deleteIt = new DeleteItListener(this, doIt);

    b1.addActionListener(deleteIt);
    b2.addActionListener(deleteIt);
    b3.addActionListener(deleteIt);
    b4.addActionListener(deleteIt);

    add(p1);
    pack();
  }

  public void deleteButton(String name) {
    if (b2 != null && "A".equals(name)) {
      p2.remove(b2);
      b2 = null;
      p2.invalidate();
      p2.redraw();
    }
    if (b3 != null && "B".equals(name)) {
      p2.remove(b3);
      b3 = null;
      p2.invalidate();
      p2.redraw();
    }
    if (b4 != null && "A".equals(name)) {
      p2.remove(b4);
      b4 = null;
      p2.invalidate();
      p2.redraw();
    }
  }

  public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        new Gui().setVisible(true);
      }
    });
  }
}

class DoItListener implements ActionListener {

  private ActionListener delegate;

  public DoItListener(ActionListener next) {
    delegate = next;
  }

  public void actionPerformed(ActionEvent e) {
    if (!("Delete".equals(e.getActionCommand()))) {
      System.out.println("doing " + e.getActionCommand());
    } else if (delegate != null) {
      delegate.actionPerformed(e);
    }
  }
}

class DeleteItListener implements ActionListener {

  private Gui gui;

  private boolean deleteNext;

  private ActionListener delegate;

  public DeleteItListener(Gui container, ActionListener next) {
    gui = container;
    delegate = next;
    deleteNext = false;
  }

  public void actionPerformed(ActionEvent e) {
    if ("Delete".equals(e.getActionCommand())) {
      deleteNext = true;
    } else if (deleteNext) {
      gui.deleteButton(e.getActionCommand());
      deleteNext = false;
    } else if (delegate != null) {
      delegate.actionPerformed(e);
    }
  }
}

Upvotes: 5

nIcE cOw
nIcE cOw

Reputation: 24626

Here try this code out :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DeleteButtonExample extends JFrame
{
    private boolean deleteNow = false;
    private JButton deleteButton;
    private JPanel leftPanel;
    private JPanel rightPanel;
    private JButton[] buttons = new JButton[5];

    private ActionListener deleteAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            JButton button = (JButton) ae.getSource();
            if (deleteNow)
            {
                leftPanel.remove(button);
                leftPanel.revalidate();
                leftPanel.repaint();
                deleteNow = false;
            }
            else
            {
                // Do your normal Event Handling here.
                System.out.println("My COMMAND IS : " + button.getActionCommand());
            }
        }
    };

    private void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);
        setLayout(new GridLayout(0, 2));

        leftPanel = new JPanel();
        leftPanel.setLayout(new GridLayout(0, 2));
        leftPanel.setBackground(Color.WHITE);
        for (int i = 0; i < 5; i++)
        {
            buttons[i] = new JButton("" + i);
            buttons[i].addActionListener(deleteAction);
            buttons[i].setActionCommand("" + i);
            leftPanel.add(buttons[i]);
        }

        rightPanel = new JPanel();
        rightPanel.setBackground(Color.BLUE);

        JButton deleteButton = new JButton("DELETE");
        deleteButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                JOptionPane.showMessageDialog(null, "Delete any Button from the Left Panel by clicking it."
                                                                                    , "INFO : ", JOptionPane.INFORMATION_MESSAGE);
                deleteNow = true;                                                                   
            }
        });
        rightPanel.add(deleteButton);

        add(leftPanel);
        add(rightPanel);
        pack();
        setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new DeleteButtonExample().createAndDisplayGUI();
            }
        });
    }
}

OUTPUT :

FIRST WINDOW, WHEN YOU CLICKED DELETE BUTTON, AFTER YOU CLICK THE BUTTON ON LEFT PANEL IT WILL BE DELETED AS SHOWN HERE

Upvotes: 2

Dilum Ranatunga
Dilum Ranatunga

Reputation: 13374

Have a look at the glass pane. This tutorial shows how it is used.

At a high level, clicking the 'Delete' button would put the glass pane listener into a state where it:

  1. detects a click,
  2. determines the target component,
  3. determines whether the component is allowed to be deleted
  4. and if so, delete the component.

As a design note, I would keep a Set of controls that are allowed to be deleted, and thereby separate the concerns. So when you add a button that is allowed to be deleted, it is your responsibility to also add it to the delete candidates set.

Upvotes: 1

Related Questions