java - 当我触发火球创建时,它会重置我的角色 JLabel

标签 java swing jlabel

package clickrpg2;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.Timer;

public class MainFrame extends javax.swing.JFrame implements ActionListener {

    static MainFrame mainFrame = new MainFrame();
    static Hero hero = new Hero();
    static JLabel fireballButton[] = new JLabel[1000000];
    static int fireballTotal = 0;
    Timer timer = new Timer(10, this);

    public MainFrame() {
        addKeyListener(new KeyThing());
        addMouseListener(new MouseThing());
        initComponents();
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/clickrpg2/StickMan1.png"))); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(1454, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(597, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    public static void main(String args[]) {
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                mainFrame.setVisible(true);
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        int c = 0;
        int x = 0;
        int y = 0;
        int xChar = jLabel1.getX();
        int yChar = jLabel1.getY();
        while (true) {
            x = fireballButton[c].getX();
            y = fireballButton[c].getY();
            fireballButton[c].setBounds(x + 5, y, 64, 32);
            c++;
            if (c == fireballTotal) {
                break;
            }
        }
        jLabel1.setBounds(xChar,yChar,64,64);
    }

    class KeyThing extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            int x = jLabel1.getX();
            int y = jLabel1.getY();
            int speed = hero.getSpeed();
            jLabel1.setBounds(x, y, 64, 64);
            int keycode = e.getKeyCode();

            switch (keycode) {
                case KeyEvent.VK_LEFT:
                    jLabel1.setBounds(x - speed, y, 64, 64);
                    break;
                case KeyEvent.VK_RIGHT:
                    jLabel1.setBounds(x + speed, y, 64, 64);
                    break;
                case KeyEvent.VK_DOWN:
                    jLabel1.setBounds(x, y + speed, 64, 64);
                    break;
                case KeyEvent.VK_UP:
                    jLabel1.setBounds(x, y - speed, 64, 64);
                    break;
                case KeyEvent.VK_SPACE:
                    x = jLabel1.getX();
                    y = jLabel1.getY();
                    fireballButton[fireballTotal] = new JLabel();
                    fireballButton[fireballTotal].setPreferredSize(new Dimension(x, y));
                    mainFrame.getContentPane().add(fireballButton[fireballTotal], BorderLayout.CENTER);
                    ImageIcon label = new ImageIcon("C:\\Users\\Nick\\Documents\\NetBeansProjects\\ClickRPG2\\src\\clickrpg2\\Fireball.png");
                    fireballButton[fireballTotal].setIcon(label);
                    mainFrame.setVisible(true);
                    fireballButton[fireballTotal].setBounds(x, y, 64, 64);
                    mainFrame.add(fireballButton[fireballTotal]);
                    fireballTotal++;
                    timer.start();
                    if (fireballTotal > 900000) {
                        fireballTotal = 0;
                    }
                    break;
            }
        }
    }

    class MouseThing extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            int x = mainFrame.getX();
            int y = mainFrame.getY();
            fireballButton[fireballTotal] = new JLabel();
            ImageIcon label = new ImageIcon("C:\\Users\\Nick\\Documents\\NetBeansProjects\\ClickRPG2\\src\\clickrpg2\\Fireball.png");
            fireballButton[fireballTotal].setIcon(label);
            fireballButton[fireballTotal].setBounds(x, y, 64, 64);
            fireballTotal++;
            timer.start();
            if (fireballTotal > 900000) {
                fireballTotal = 0;
            }
        }
    }
    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    // End of variables declaration
}

基本上,我只需要它在我制作火球 jLabel 时不重置 jLabel1。\

有什么建议吗?预先感谢,我是新来的,所以我希望代码块。因为我不知道错误发生在哪里,所以我需要保留大部分代码。抱歉。

最佳答案

好吧,这就是你的问题......

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);

您的容器受布局管理器的控制。任何更改任何组件的位置或大小的尝试(通过 setBoundssetLocation 和/或 setSize )都将失败,因为布局管理器将放弃这些更改以支持其自己的更改...

当您添加或删除任何组件时,布局管理器会将所有组件更新到它认为应该在的位置。

这行不通,而且是个坏主意。

while (true) {
    x = fireballButton[c].getX();
    y = fireballButton[c].getY();
    fireballButton[c].setBounds(x + 5, y, 64, 32);
    c++;
    if (c == fireballTotal) {
        break;
    }
}

任何耗时或阻塞的操作(如循环)都会阻止 EDT 更新图形,基本上意味着您实际上不会看到火球......而且我不敢相信您使用了 Timer有了这个(这将是在正确的方向)并且仍然使用循环......

我的建议...

使用 JLayerPane 反而。这允许您使用绝对定位(尽管如果您确实想要的话,您可以对其应用布局管理器...但它只是 JPanel )

另外,请通读 Concurrency in Swing

使用示例更新

enter image description here

public class TestFireBall {

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

    public TestFireBall() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new FireBallPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class FireBallPane extends JLayeredPane {

        private JLabel character;
        private List<JLabel> fireBalls;
        private ImageIcon icoFireBall;
        private Timer timer;
        private Timer coolOffTimer;
        private int vX = 12;
        private boolean coolOff = false;

        public FireBallPane() {
            fireBalls = new ArrayList<JLabel>(25);

            ImageIcon icoCharacter = null;
            ImageIcon fireBall = null;

            try {
                icoCharacter = new ImageIcon(ImageIO.read(getClass().getResource("/BlackMage.png")));
                icoFireBall = new ImageIcon(ImageIO.read(getClass().getResource("/FireBall.png")));
            } catch (Exception e) {
                e.printStackTrace();
            }

            character = new JLabel(icoCharacter);

            add(character);

            setFocusable(true);
            requestFocusInWindow();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "fire");
            ActionMap am = getActionMap();
            am.put("fire", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!coolOff) {
                        coolOff = true;
                        JLabel fireBall = createFireBall();
                        fireBalls.add(fireBall);
                        if (!timer.isRunning()) {
                            timer.start();
                        }
                        coolOffTimer.restart();
                    }
                }
            });

            timer = new Timer(125, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (fireBalls.size() > 0) {
                        JLabel[] balls = fireBalls.toArray(new JLabel[fireBalls.size()]);
                        for (JLabel fireBall : balls) {
                            if (fireBall.getParent() == null) {
                                add(fireBall);
                            }
                            Point p = fireBall.getLocation();
                            p.x += vX;
                            if (p.x + fireBall.getWidth() >= getWidth()) {
                                remove(fireBall);
                                fireBalls.remove(fireBall);
                            } else {
                                fireBall.setLocation(p);
                            }
                            repaint();
                        }
                    } else {
                        timer.stop();
                    }
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);

            coolOffTimer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    coolOff = false;
                }
            });
            coolOffTimer.setRepeats(false);
            coolOffTimer.setCoalesce(true);
        }

        protected JLabel createFireBall() {
            JLabel fireBall = new JLabel(icoFireBall);

            fireBall.setSize(fireBall.getPreferredSize());
            int x = character.getX() + character.getWidth();
            int y = character.getY() + ((character.getHeight() - fireBall.getHeight()) / 2);
            fireBall.setLocation(x, y);

            return fireBall;
        }

        @Override
        public void invalidate() {
            super.invalidate();

            character.setSize(character.getPreferredSize());
            int height = getHeight();
            int y = (height - character.getHeight()) / 2;
            character.setLocation(0, y);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }
}

关于java - 当我触发火球创建时,它会重置我的角色 JLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13170002/

相关文章:

java - request.getParameter() 不存在时表示其为 null

java - Swing:如果在数字键盘上按下数字,则 Ctrl+数字的操作无法正常工作

Java 简单字符串差异工具

java - 如何动态更新图像到jlabel

java - 通过分阶段下载加速应用程序加载

java - hadoop windows(工作正常)linux java堆空间

java - JComboBox的ActionListener并初始化JPanel

java - 逻辑错误导致 if 语句不起作用

java - 更改 JLabel 的一部分的字体?

java - Swing : Write in a JLabel