JButtons中的图标没有被删除?

时间:2015-05-25 16:26:00

标签: java swing repaint

我正在为Java游戏构建基于swing的GUI。游戏本质上是一个由自定义data Term a = Var a | Star -- or alternatively, "Type", or "*" | Lam (Type a) (Scope () Term a) | Pi (Type a) (Scope () Term a) | App (Type a) (Term a) deriving (Show, Eq, Functor) -- boilerplate omitted (Monad, Applicative, Eq1, Show1 instances) -- reduce to normal form rnf :: Term a -> Term a rnf = ... -- Note: IIRC "Simply easy" and Augustsson's post reduces to whnf -- when type checking. I use here plain normal form, because it -- simplifies the presentation a bit and it also works fine. -- We rely on Bound's alpha equality here, and also on the fact -- that we keep types in normal form, so there's no need for -- additional reduction. check :: Eq a => Cxt a -> Type a -> Term a -> TC () check cxt want t = do have <- infer cxt t when (want /= have) $ Left "type mismatch" infer :: Eq a => Cxt a -> Term a -> TC (Type a) infer cxt = \case Var a -> cxt a Star -> pure Star -- "Type : Type" system for simplicity Lam ty t -> do check cxt Star ty let ty' = rnf ty Pi ty' . toScope <$> infer (consCxt ty' cxt) (fromScope t) Pi ty t -> do check cxt Star ty check (consCxt (rnf ty) cxt) Star (fromScope t) pure Star App f x -> infer cxt f >>= \case Pi ty t -> do check cxt ty x pure $ rnf (instantiate1 x t) _ -> Left "can't apply non-function" 对象组成的4x4网格,实质上是一个自定义的JButton。以下代码

Cell

package gamePack; import java.awt.Graphics; import java.util.ArrayList; import javax.swing.JButton; public class Cell extends JButton { int co_x = 0; int co_y = 0; ArrayList<Players> current = new ArrayList <Players>(); } 允许我存储不同ArrayList的对象。所有Players都继承自同一个类,因此我基本上重新绘制单元格并根据ArrayList中的对象类型添加图标。每个单元格都有一个ArrayList,因为每个单元格可以有多个Players

Players

单击“移动”按钮时游戏会发生变化。在这里,当我点击start时,我正在添加玩家的精灵,并且会调用重绘方法。下面的重绘方法:

GUI initialization:
package gamePack;

import java.awt.EventQueue;

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

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.border.Border;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class StarFight {

    public JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    StarFight window = new StarFight();
                    window.frame.setVisible(true);


                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public StarFight() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setVisible(true);
        frame.setBounds(100, 100, 487, 349);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        final JPanel gamePanel = new JPanel();
        gamePanel.setBounds(0, 0, 365, 310);
        frame.getContentPane().add(gamePanel);
        int i = 4;
        int j = 4;
        final Cell[][] panelHolder = new Cell[i][j]; 
        gamePanel.setLayout(new GridLayout(4, 4, 0, 0));
        //91.25 x 77.5 rectangles

        Border border = BorderFactory.createLineBorder(Color.white);
        for(int m = 0; m < i; m++) {
            for(int n = 0; n < j; n++) {
                panelHolder[m][n] = new Cell();
                panelHolder[m][n].co_x = m;
                panelHolder[m][n].co_y= n;
                panelHolder[m][n].setBackground(Color.black);
                panelHolder[m][n].setEnabled(false);
                panelHolder[m][n].setBorder(border);
                gamePanel.add(panelHolder[m][n]);

            }
        }


        JPanel controlPanel = new JPanel();
        controlPanel.setBounds(375, 0, 86, 310);
        frame.getContentPane().add(controlPanel);
        controlPanel.setLayout(null);

        final JButton Move = new JButton("Move");
        Move.setEnabled(false);
        Move.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                panelHolder[0][0].current.clear();
                BattleCruiser q = new BattleCruiser();
                panelHolder[3][2].current.add(q);

                Redraw.draw(gamePanel, panelHolder);
            }
        });
        Move.setBounds(1, 82, 84, 65);
        controlPanel.add(Move);

        final JButton Undo = new JButton("Undo");
        Undo.setEnabled(false);
        Undo.setBounds(1, 158, 84, 65);
        controlPanel.add(Undo);

        JButton Exit = new JButton("Exit");

        Exit.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                System.exit(0);
            }
        });
        Exit.setBounds(1, 234, 84, 65);
        controlPanel.add(Exit);

        final JButton btnStart = new JButton("Start");
        btnStart.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                Move.setEnabled(true);
                Undo.setEnabled(true);
                btnStart.setEnabled(false);

                PlayChar p = new PlayChar();
                BattleCruiser q = new BattleCruiser();
                BattleStar s = new BattleStar();
                BattleShooter sh = new BattleShooter();

                panelHolder[0][0].current.add(p);


                Redraw.draw(gamePanel, panelHolder);
            }
        });
        btnStart.setBounds(1, 6, 84, 65);
        controlPanel.add(btnStart); 
    }
    }

重绘方法检查每个单元格中的ArrayList,然后适当地添加一个图标。目前,当我单击Move时,它应该删除所有JButton,然后使用适当的sprite将它们添加回来。

问题在于,当我这样做时,即使在添加另一个精灵之前使用package gamePack; import java.awt.Color; import java.awt.GridLayout; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border; public class Redraw { public static void draw(JPanel gamePanel, Cell[][] panelHolder ){ gamePanel.setBounds(0, 0, 365, 310); int i = 4; int j = 4; gamePanel.setLayout(new GridLayout(4, 4, 0, 0)); //91.25 x 77.5 rectangles Border border = BorderFactory.createLineBorder(Color.white); for(int m = 0; m < i; m++) { for(int n = 0; n < j; n++) { panelHolder[m][n].setBackground(Color.black); panelHolder[m][n].setEnabled(false); panelHolder[m][n].setBorder(border); panelHolder[m][n].setIcon(null); for(Players p: panelHolder[m][n].current){ if(p instanceof PlayChar){ String arg = "Player.png"; ImageIcon icon = new ImageIcon(arg); JLabel label = new JLabel(); label.setIcon(icon); panelHolder[m][n].add(label); } else if (p instanceof BattleStar) { String arg = "BattleStar.png"; ImageIcon icon = new ImageIcon(arg); JLabel label = new JLabel(); label.setIcon(icon); panelHolder[m][n].add(label); } else if (p instanceof BattleCruiser){ String arg = "BattleCruiser.png"; ImageIcon icon = new ImageIcon(arg); JLabel label = new JLabel(); label.setIcon(icon); panelHolder[m][n].add(label); } else if (p instanceof BattleShooter){ String arg = "BattleShooter.png"; ImageIcon icon = new ImageIcon(arg); JLabel label = new JLabel(); label.setIcon(icon); panelHolder[m][n].add(label); } } } } gamePanel.revalidate(); gamePanel.repaint(); } } ,仍会绘制0,0位置的精灵。单步执行代码显示current.clear()对象的if语句未被调用,因此我必须假设它与重绘方法有关。我做错了什么吗?

编辑:基于反馈,我现在已经改变它,所以重绘功能不会取代JButton,而是改变它们的属性。我还添加了它,以便在设置任何图标之前将Icon设置为null,以确保将其删除。然而,同样的问题仍在发生

1 个答案:

答案 0 :(得分:0)

发现问题!感谢@faljbour

  

你有没有理由使用JLabel并调用add来设置JButton上的图标而不是直接使用.setIcon(icon)?

这就是问题所在。该图像被设置为JLabel,然后被添加,因此删除Icon没有任何效果。

代码应为:

String arg = "Player.png";
ImageIcon icon = new ImageIcon(arg);  
panelHolder[m][n].setIcon(icon);