简体   繁体   中英

Unable to remove JLabel from JPanel

I have a chessboard with 64 JPanels representing each square on the board. The pieces are represented using JLabels which are placed on the JPanels. I am trying to remove all the JLabels off the board. I am confused why this doesn't work:

private void removePieces()
{
    for(int i = 0; i < 64; i ++)
    {       
        Component c = chessBoard.getComponent(i);
        if(c instanceof JLabel)
        {
            Container parent = c.getParent();
            parent.remove((JLabel)c);
            parent.revalidate();
            parent.repaint();
        }
    }
}

chessboard is the big JPanel with the 64 JPanels inside it. After some debugging it looks like the if loop is never being entered. I don't understand why it wouldn't enter the if loop if one of the components is a JLabel?

Why remove the labels, rather than simply set the icon to null or text to "" ?

EG using text for the pieces.

棋盘

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.border.LineBorder;

class ChessBoard2 {

    static ChessMoveMouseListener cmml = new ChessMoveMouseListener();
    /** Unicode strings for chess pieces & empty string for blank squares. */
    static String[][] pieces = {
        {"\u2654", "\u2655", "\u2656", "\u2657", "\u2658", "\u2659"},
        {"\u265A", "\u265B", "\u265C", "\u265D", "\u265E", "\u265F"},
        {""}
    };
    static int[] order = new int[]{2, 4, 3, 0, 1, 3, 4, 2};
    static int[] pawns = new int[]{5, 5, 5, 5, 5, 5, 5, 5};
    static int[] blank = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
    static int white = 0;
    static int black = 1;
    static int space = 2;

    public static JLabel getColoredLabel(String string, int color) {
        JLabel l = new JLabel(string);
        l.setFont(l.getFont().deriveFont(50f));
        Color c = (color % 2 == 0 ? Color.WHITE : Color.LIGHT_GRAY);
        l.setBackground(c);
        l.setOpaque(true);
        l.addMouseListener(cmml);

        return l;
    }

    public static void addRowToContainer(
            Container c,
            int[] order,
            int row,
            int count) {

        for (int ii : order) {
            c.add(getColoredLabel(pieces[row][ii], count++));
        }
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel chessboard = new JPanel(new GridLayout(0, 8, 1, 1));
                chessboard.setBackground(Color.BLACK);
                chessboard.setBorder(new LineBorder(Color.BLACK));

                int count = 0;
                // black pieces..
                addRowToContainer(chessboard, order, black, count);
                addRowToContainer(chessboard, pawns, black, ++count);
                // middle squares..
                addRowToContainer(chessboard, blank, space, ++count);
                addRowToContainer(chessboard, blank, space, ++count);
                addRowToContainer(chessboard, blank, space, ++count);
                addRowToContainer(chessboard, blank, space, ++count);
                // white pieces..
                addRowToContainer(chessboard, pawns, white, ++count);
                addRowToContainer(chessboard, order, white, ++count);

                JOptionPane.showMessageDialog(null, chessboard,
                        "Click two squares to move from/to",
                        JOptionPane.INFORMATION_MESSAGE);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

class ChessMoveMouseListener extends MouseAdapter {

    String s = null;

    @Override
    public void mouseClicked(MouseEvent e) {
        JLabel l = (JLabel) e.getSource();
        if (s == null) {
            if (l.getText().trim().length() > 0) {
                s = l.getText();
                l.setText("");
            }
        } else {
            l.setText(s);
            s = null;
        }
    }
}

Looks like your trying to remove your JPanels from your chessboard if they are JLabels (which obviously makes no sense, and is why the if code is never firing). Instead you want to remove the chessBoard 's components' JLabel component. Example below.

private void removePieces() {
        for(int i = 0; i < 64; i ++) {   
            if(chessBoard.getComponent(i) instanceof JPanel) {
            JPanel c = (JPanel)chessBoard.getComponent(i);
            c.removeAll();
            c.revalidate();
            c.repaint();
            }
        }
    }

I am using removeAll() because I am presuming your JPanels have no other components in them other than the potential JLabels.

Think, when you're doing:

Component c = chessBoard.getComponent(i);

you're getting one of the JPanels, that contains your JLabels. And of course they are not instances of JLabel. So you need to get JLabel from that JPanel and then remove it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM