java - 从 JPanel 添加/删除

标签 java swing jpanel jlabel keylistener

我正在尝试制作一个基本 map ,按下按钮即可移动角色。 我正在使用 Netbeans,到目前为止一切顺利!除了尝试从 JPanel 中删除 JLabel 然后向其中添加新的 JLabel 之外。

这是我的完整代码:

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

public class startMap extends JFrame {

public int locX = 1;
public int locY = 1;
ImageIcon tile = new ImageIcon("src/tile.png");
JLabel tileLabel = new JLabel(tile);
ImageIcon berry = new ImageIcon("src/berry.png");
JLabel berryLabel = new JLabel(berry);
ImageIcon blank = new ImageIcon("src/blank.png");
JLabel blankLabel = new JLabel(blank);
JLabel testL = new JLabel("LOL");
JPanel[][] map = new JPanel[7][7];

public startMap() {
    setBackground(Color.BLACK);
    setFocusable(true);
    keyHandler kh = new keyHandler();
    addKeyListener(kh);
    mapGUI();
}

public void mapGUI() {
    JPanel mainP = new JPanel();
    mainP.setBackground(Color.BLACK);
    mainP.setLayout(new FlowLayout());
    for (int x = 0; x < 7; x++) {
        for (int i = 0; i < 7; i++) {
            map[x][i] = new JPanel();
            System.out.println("1");
            blankLabel = new JLabel(blank);
            map[x][i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
            map[x][i].add(blankLabel);
        }
    }
    for (int x = 1; x < 6; x++) {
        for (int i = 1; i < 6; i++) {
            System.out.println("2");
            map[x][i].removeAll();
            revalidate();
            repaint();
            tileLabel = new JLabel(tile);
            map[x][i].add(tileLabel);
            revalidate();
            repaint();
        }
    }
    System.out.println("3");
    map[locX][locY].removeAll();
    revalidate();
    repaint();
    map[locX][locY].add(berryLabel);
    revalidate();
    repaint();
    for (int x = 0; x < 7; x++) {
        for (int i = 0; i < 7; i++) {
            mainP.add(map[x][i]);
        }
    }

    add(mainP);
}

@Override
public void paint(Graphics g) {
    super.paint(g);

}

private class keyHandler extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            locY+=1;
            map[locX][locY].removeAll();
            revalidate();
            repaint();
            map[locX][locY].add(berryLabel);
            revalidate();
            repaint();


        }

    }
}

}

以下是当用户单击“向右”时方 block 发生的变化。

这是 KeyAdapter 代码:

private class keyHandler extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            locY+=1;
            map[locX][locY].removeAll();
            revalidate();
            repaint();
            map[locX][locY].add(berryLabel);
            revalidate();
            repaint();



        }

    }}

注意:系统输出只是我用来检查何时调用什么的调试方法。

所以当我运行时它看起来像这样

向右移动并重新验证$ repaint:

enter image description here

为什么位于 1,1 的框会变成灰色?

帮助弄清楚如何使盒子保持白色方 block 而不是变回灰色。

----------------------------SSCCE------------------ ----------------

使用上面的完整代码 这是主类:

import javax.swing.*;

public class TestGame extends JFrame {

public static void main(String[] args) {
    startMap sm = new startMap();
    sm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    sm.setVisible(true);
    sm.setSize(380,415);
    sm.setResizable(false);
}
}

修复版本:

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

public class startMap extends JFrame {

public int locX = 1;
public int locY = 1;
ImageIcon tile = new ImageIcon("src/tile.png");
JLabel tileLabel = new JLabel(tile);
ImageIcon berry = new ImageIcon("src/berry.png");
JLabel berryLabel = new JLabel(berry);
ImageIcon blank = new ImageIcon("src/blank.png");
JLabel blankLabel = new JLabel(blank);
JLabel testL = new JLabel("LOL");
JPanel[][] map = new JPanel[7][7];

public startMap() {
    setBackground(Color.BLACK);
    setFocusable(true);
    keyHandler kh = new keyHandler();
    addKeyListener(kh);
    mapGUI();
}

public void mapGUI() {
    JPanel mainP = new JPanel();
    mainP.setBackground(Color.BLACK);
    mainP.setLayout(new FlowLayout());
    for (int x = 0; x < 7; x++) {
        for (int i = 0; i < 7; i++) {
            map[x][i] = new JPanel();
            System.out.println("1");
            blankLabel = new JLabel(blank);
            map[x][i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
            map[x][i].add(blankLabel);
        }
    }
    for (int x = 1; x < 6; x++) {
        for (int i = 1; i < 6; i++) {
            System.out.println("2");
            map[x][i].removeAll();
            tileLabel = new JLabel(tile);
            map[x][i].add(tileLabel);
            revalidate();
            repaint();
        }
    }
    System.out.println("3");
    map[locX][locY].removeAll();
    map[locX][locY].add(berryLabel);
    revalidate();
    repaint();
    for (int x = 0; x < 7; x++) {
        for (int i = 0; i < 7; i++) {
            mainP.add(map[x][i]);
        }
    }

    add(mainP);
}

@Override
public void paint(Graphics g) {
    super.paint(g);

}

private class keyHandler extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            berryLabel = new JLabel(berry); //THIS
            tileLabel = new JLabel(tile); //And THIS had to be RE initialized idk why.
            map[locX][locY].removeAll();
            map[locX][locY].add(tileLabel);

            locY += 1;
            map[locX][locY].removeAll();
            map[locX][locY].add(berryLabel);
            revalidate();
            repaint();


        }

    }
}

}

最佳答案

应在添加/删除后调用

revalidate();
repaint();

不要从 paint() 调用 repaint()

关于java - 从 JPanel 添加/删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13968876/

相关文章:

java - 带有从 firebase 到数据库的数据的 TextView 在屏幕上消失

java - x*x 与 Math.pow(x,2) java 性能对比

java - g.fillPolygon 未更新位置(整数数组未更新...?)

java - JPanel 中的多个动画(线程)

java - 自定义矩形类不起作用

java - 从 jpanel 中绘制和删除 jlabel

java - 保存大型短数组android

java - 在 Struts 2 中的身份验证拦截器之后重定向到正确的操作

Java Swing 布局 - 使用哪种布局

Java 简单计算器