Java 无法从JPanel中删除JLabel

Java 无法从JPanel中删除JLabel,java,swing,user-interface,jpanel,jlabel,Java,Swing,User Interface,Jpanel,Jlabel,我有一个棋盘,上面有64个棋盘,代表棋盘上的每个方块。使用放置在JPanel上的JLabel表示这些片段。我正在尝试从板上移除所有jLabel。我不明白为什么这不起作用: private void removePieces() { for(int i = 0; i < 64; i ++) { Component c = chessBoard.getComponent(i); if(c instanceof JLabel)

我有一个棋盘,上面有64个棋盘,代表棋盘上的每个方块。使用放置在JPanel上的JLabel表示这些片段。我正在尝试从板上移除所有jLabel。我不明白为什么这不起作用:

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();
        }
    }
}
private void removePieces()
{
对于(int i=0;i<64;i++)
{       
组件c=棋盘。getComponent(i);
if(JLabel的c实例)
{
容器父级=c.getParent();
删除((JLabel)c);
parent.revalidate();
parent.repaint();
}
}
}

棋盘是一个大棋盘,里面有64个棋盘。经过一些调试后,似乎从未进入if循环。我不明白,如果其中一个组件是JLabel,为什么它不会进入if循环?

思考一下,当您执行以下操作时:

Component c = chessBoard.getComponent(i);
您将获得一个JPanel,其中包含您的JLabel。当然,它们不是JLabel的实例。
因此,您需要从该JPanel获取JLabel,然后将其删除。

为什么要删除标签,而不是简单地将图标设置为
null
或将文本设置为

例如,使用文本作为片段

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;
        }
    }
}


看起来,如果JPanel是JLabel,您试图将其从棋盘上移除(这显然毫无意义,这就是为什么
if
代码从未触发的原因)。相反,您希望删除
棋盘
的组件的JLabel组件。下面的例子

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();
            }
        }
    }
private void removePieces(){
对于(int i=0;i<64;i++){
if(chessBoard.getComponent(i)JPanel实例){
JPanel c=(JPanel)chessBoard.getComponent(i);
c、 removeAll();
c、 重新验证();
c、 重新油漆();
}
}
}

我使用的是
removeAll()
,因为我假设您的JPanel中除了潜在的JLabel之外没有其他组件。

如果我不确定JPanel是否有JLabel,如何从JPanel中获取JLabel。基本上,我应该如何检查JPanel中是否包含JLabel?此外,我以前使用过instanceof来检查JPanel是否包含JLabel并且它是否工作正常。例如,我用它来检查用户何时将一个部件移动到一个被占用的jpanel。问题是要弄清楚哪些面板实际上有标签。如果我只是在整个64个面板中循环,并将标签设置为null,我会得到错误,因为有些面板没有标签。“问题是要弄清楚哪些面板实际上有标签”我忘了添加“删除所有块”按钮,但请注意,在我的示例中只有一个
JPanel
。此外,该面板的
GridLayout
中的每个空间都有一个
JLabel
!你不能从那开始解决问题吗?嗯。。在我的实现中,我没有在每个面板上都放置JLabel。就在有一块的面板上有一个jlabel.BTW——我想我迄今为止的努力(一个带有屏幕截图的SSCCE)可能已经赢得了我的支持票。至少是问问题的人,如果只是为了努力的话。就您的设计而言,如果您希望坚持这种方法,我建议您编辑该问题以包括您自己的SSCCE。我拒绝使用这样一个主题上的不可编译代码片段,其中包含一个自包含的示例是微不足道的。+ 1用于一个真实的,以及一个很好的查找表。也考虑在适当的位置更新组件。component@SKLAK在我这方面似乎效果不错。我真的不知道该建议什么。我假设棋盘上包含64个JPanel。@SKLAK对不起,我的错,那是因为
组件
没有
removeAll()
,即使
JPanel
有。您无法从
组件
引用访问
removeAll()
,即使它包含
JPanel
。我将编辑代码以反映更改。