Question

I have the following piece of code where a custom panel is added to the JTaskPane. The pane has a label which gets removed when I click on it. However, my custom panel is not removed. How can I click on the cross in the panel to remove it?

Following is the snapshot. So, in this case, I can remove the "Close" JLabel but I cannot remove the purple label when I click on the "cross" sign

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.jdesktop.swingx.JXTaskPane;

public class Test {
    private SRLSearchPanel panel = new SRLSearchPanel();

    class SRLSearchPanel extends JPanel {

        private JXTaskPane filterPanel = new JXTaskPane();
        private JTextField searchField = new JTextField(20);

        public SRLSearchPanel() {
            setLayout(new BorderLayout());
            final JLabel lbl = new JLabel("Close");
            filterPanel.add(lbl);
            lbl.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    super.mouseClicked(e);
                    filterPanel.remove(lbl);
                    filterPanel.revalidate();
                }
            });

            filterPanel.add(searchField);
            add(filterPanel, BorderLayout.WEST);

            searchField.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    FilterBox filterBox = new FilterBox(searchField.getText());
                    filterPanel.add(filterBox);
                }
            });
        }

        public void removeFilter(FilterBox filterBox) {
            filterPanel.remove(filterBox);
        }
    }

    class FilterBox extends JPanel {

        private static final int PADDING = 2;
        private static final String PAD_STR = "  ";

        private JLabel filterLbl = new JLabel();
        private JButton closeBtn = new JButton("X");

        public FilterBox(String label) {
            filterLbl.setText(PAD_STR + label + PAD_STR);
            closeBtn.setBorderPainted(false);
            closeBtn.setFocusPainted(false);
            closeBtn.setContentAreaFilled(false);
            closeBtn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            System.err.println("Adding action listener "
                    + FilterBox.this.hashCode());
            closeBtn.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    panel.removeFilter(FilterBox.this);
                }
            });

            this.setLayout(new BorderLayout());
            this.add(filterLbl, BorderLayout.WEST);
            this.add(closeBtn, BorderLayout.EAST);

            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    super.mouseClicked(e);
                    System.err.println("Removing filter");
                    panel.filterPanel.remove(FilterBox.this);
                }
            });
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.setColor(new Color(0f, 0f, 1f, 0.3f));
            g.fillRoundRect(0, 0, this.getWidth(), this.getHeight() - PADDING,
                    20, 20);
            g.setColor(Color.BLACK);
        }
    }

    public static void main(String[] args) {
        Test i = new Test();
        i.testRun();
    }

    public void testRun() {
        final JFrame frame = new JFrame();
        SRLSearchPanel spanel = new SRLSearchPanel();
        frame.add(spanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(800, 800));
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.pack();
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);
            }
        });
    }
}
Was it helpful?

Solution

You're having a context problem.

First you create an instance variable of SRLSearchPanel

private SRLSearchPanel panel = new SRLSearchPanel();

This is used by your FilterBox

But then you create another instance...

SRLSearchPanel spanel = new SRLSearchPanel();
frame.add(spanel);

This is the one that is actually on the screen, so interacting with panel has no effect as it has no relationship to what you've actually put on the screen

Instead, you could try simply requesting that the FilterBox be removed from it's parent...

closeBtn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        getParent().remove(FilterBox.this);
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top