【问题标题】:Remove buttons in JLabel [closed]删除 JLabel 中的按钮 [关闭]
【发布时间】:2016-05-14 23:11:22
【问题描述】:

我有一个如下所示的 java swing 项目:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;

import javax.swing.ImageIcon;
import javax.swing.Box;
import javax.swing.BoxLayout;
import java.awt.BorderLayout;
import java.awt.Color;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;


public class DiceGameReplaceDice extends JFrame
{  
    private JFrame gameFrame;
    private JPanel mainPanel;
    private JPanel centerPanel = new JPanel();
    private JButton diceArray[];
    private DiceListener diceListener = new DiceListener();
    private ButtonListener buttonListener = new ButtonListener();
    private Random rand = new Random();
    private int NUM_DICE = 2;


    private String diceImages[] = {"./src/1.png", "./src/2.png", "./src/3.png",
            "./src/4.png", "./src/5.png", "./src/6.png"};

    public static void main(String[] args)
    {       
        new DiceGameReplaceDice();
    }

    public DiceGameReplaceDice()    
    {
        // Initialize the frame that holds the game
        gameFrame = new JFrame();
        gameFrame.setSize(800, 600);
        gameFrame.setLocation(300, 100); 
        gameFrame.setTitle("Dice Game");
        gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Add Panel
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        // Instantiate a ButtonListener
        buttonListener = new ButtonListener();


        // Add 1 Button and 1 Label to a newly created panel 
        // Add new panel to West 
        JButton buttonW1 = new JButton("Add Die");
        buttonW1.setName("W1");
        buttonW1.addActionListener(buttonListener);
        JPanel panelWest = new JPanel();
        panelWest.setLayout(new BoxLayout(panelWest,BoxLayout.Y_AXIS ));
        panelWest.setBackground(new Color(0, 0, 122));  // set to blue
        panelWest.add(Box.createVerticalGlue());
        panelWest.add(buttonW1);
        panelWest.add(Box.createVerticalGlue());

        mainPanel.add(panelWest, BorderLayout.WEST);


        // Create and display center panel with dice
        displayCenterPanel();

        // Add mainPanel to frame and display the frame
        gameFrame.add(mainPanel);
        gameFrame.setVisible(true);
    }

    private  void displayCenterPanel()
    {
        centerPanel = new JPanel();
        centerPanel.setLayout(new BoxLayout(centerPanel,BoxLayout.X_AXIS ));
        centerPanel.setBackground(new Color(0, 122, 0));  // set to green
        centerPanel.add(Box.createHorizontalGlue());

        diceArray = new JButton[NUM_DICE];

        // Add 2 Buttons to center panel with images of 2 random dice 
        for (int i=0; i<NUM_DICE; i++)
        {
            // Create dice button
            int dieNum = rand.nextInt(6)+1;
            diceArray[i] = new JButton(new ImageIcon(diceImages[dieNum-1]));
            diceArray[i].setName("Dice" + i); 
            diceArray[i].addActionListener(diceListener);

            // Add to center panel
            centerPanel.add(diceArray[i]);
            centerPanel.add(Box.createHorizontalGlue());
        }

        mainPanel.add(centerPanel, BorderLayout.CENTER);

        // Add mainPanel to frame and display the frame
        gameFrame.add(mainPanel);
        gameFrame.setVisible(true);
    }

    // Implement an (inner) class that implements ActionListener
    class DiceListener implements ActionListener
    {

        public void actionPerformed(ActionEvent e) 
        {
            NUM_DICE -= 1;
            displayCenterPanel();
        }
    }

    // Implement an (inner) class that implements ActionListener
    class ButtonListener implements ActionListener
    {

        public void actionPerformed(ActionEvent e) 
        {
            String button = ((JButton)e.getSource()).getName();
            System.out.println("Button Pressed: " + button);
            if (button.equals("W1"))
                NUM_DICE ++;
            System.out.println(NUM_DICE);
            displayCenterPanel();
        }
    }
}

单击“添加模具”按钮时,模具会添加到屏幕并正确格式化。但是,当按下骰子并减少 NUM_DICE 时,单击骰子按钮会导致奇怪的重叠和“幽灵按钮”。你如何解决这个问题?

【问题讨论】:

  • a) 不要显示“近似”代码 - 您错过的部分可能是重要的部分。 b)在调用displayCenter()“再次”之前,您是否清除了面板中所有现有的孩子?
  • a) 我知道,但是,如上所述,我是在手机上写这篇文章的,所以我目前无法访问完整的代码。但是在我犯了一个非常常见/愚蠢的错误的模糊可能性中,我想尽快解决这个问题。 b) 不。你如何删除孩子?
  • 发布MCVE。请务必将您的代码复制粘贴到新项目,并确保在将其发布到此处之前编译并运行。

标签: java swing user-interface button jlabel


【解决方案1】:

快速解决方法是在添加新的之前删除centerPanel。添加行

mainPanel.remove(centerPanel);

作为你在 displayCenterPanel 内部做的第一件事。

但是,您动态操作布局的方式还有很多不足之处。无需每次都创建新面板,只需修改现有面板即可:

public class DiceGame {

    private JPanel centerPanel = new JPanel();
    private Random rand = new Random();
    private int numDice = 2;

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> new DiceGame());
    }

    public DiceGame() {

        JFrame gameFrame = new JFrame();
        gameFrame.setSize(800, 600);
        gameFrame.setTitle("Dice Game");
        gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        JButton buttonW1 = new JButton("Add Die");
        buttonW1.addActionListener(e -> {
            numDice++;
            updateCenterPanel();
        });
        JPanel panelWest = new JPanel();
        panelWest.setLayout(new BoxLayout(panelWest, BoxLayout.Y_AXIS));
        panelWest.setBackground(new Color(0, 0, 122));
        panelWest.add(Box.createVerticalGlue());
        panelWest.add(buttonW1);
        panelWest.add(Box.createVerticalGlue());

        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS));
        centerPanel.setBackground(new Color(0, 122, 0));

        mainPanel.add(panelWest, BorderLayout.WEST);
        mainPanel.add(centerPanel);

        gameFrame.add(mainPanel);
        gameFrame.setVisible(true);
    }

    private void updateCenterPanel() {

        centerPanel.removeAll();
        centerPanel.add(Box.createHorizontalGlue());

        JButton[] diceArray = new JButton[numDice];

        for (int i = 0; i < numDice; i++) {
            diceArray[i] = new JButton(Integer.toString(rand.nextInt(6) + 1));
            diceArray[i].setName("Dice" + i);
            diceArray[i].addActionListener(e -> {
                numDice--;
                updateCenterPanel();
            });
            centerPanel.add(diceArray[i]);
            centerPanel.add(Box.createHorizontalGlue());
        }
        centerPanel.revalidate();
        centerPanel.repaint();
    }
}

使组件层次结构失效后需要重新验证和重新绘制。

注意事项:

  • 如果可以使用局部变量,请不要创建字段。
  • NUM_DICE 不是final,所以应该命名为numDice
  • gameFrame.setVisible(true); 已经可见时调用它不会执行任何操作。
  • 当您拥有正在执行的工作的工作版本时,请将 JFrame 上的 setSize(...) 替换为 pack,并确保正确计算其子项的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 2016-10-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    相关资源
    最近更新 更多