java - 面板重绘后 mouseListener 丢失

标签 java swing

我的程序将允许用户首先登录,如果他登录了, 他将首先单击“labelone”,然后单击“labeltwo”。 程序将打印(“检测到最后两张牌。开始新游戏..”)并允许用户再次单击这两个标签。

我面临的问题是在我的面板重新绘制之后。我无法点击标签 不再了。

我知道我的代码提供的代码太长,但我已经尝试从实际程序中删除我的代码。

我认为主要焦点是我的 Controller 类中的这段代码。

 labelPanel.removeAll();
 Dealer dealer = new Dealer();
 labelPanel.add(new LabelPanel(dealer));
 labelPanel.revalidate();
 labelPanel.repaint();
 new Controller(labelPanel,dealer);

我不确定我的鼠标监听器发生了什么。请帮忙

这是类(class)。如果你们无法理解,请随意运行它。

  • 以用户名登录 -> john 密码 -> abc
  • 首先单击标签一,然后单击标签二。控制台将显示 “检测到最后两张牌,开始新游戏..” 之后尝试再次单击标签(按理说它应该是可单击的,但事实并非如此)

登录面板.java

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

@SuppressWarnings("serial")
public class LoginPanel extends JPanel {

    private JPanel northPanel = new JPanel(new BorderLayout());
    private JPanel southPanel = new JPanel(new BorderLayout());
    private JPanel subSouthPanel = new JPanel(new GridBagLayout());
    private JPanel subSouthPanelTwo = new JPanel(new FlowLayout());
    private GridBagConstraints gbc2 = new GridBagConstraints();
    private JTextField playerUsernameTF = new JTextField(15);
    private JPasswordField playerPasswordTF = new JPasswordField(15);
    private JButton playerLoginBtn = new JButton("Login");

    public LoginPanel() {
        setLayout(new BorderLayout());
        gbc2.gridx = 0;
        gbc2.gridy = 0;
        subSouthPanel.add(new JLabel("Username"),gbc2);
        gbc2.gridx = 1;
        gbc2.gridy = 0;
        subSouthPanel.add(playerUsernameTF,gbc2);
        gbc2.gridx = 0;
        gbc2.gridy = 1;
        subSouthPanel.add(new JLabel("Password"),gbc2);
        gbc2.gridx = 1;
        gbc2.gridy = 1;
        subSouthPanel.add(playerPasswordTF,gbc2);
        southPanel.add(subSouthPanel,BorderLayout.CENTER);
        subSouthPanelTwo.add(playerLoginBtn);
        southPanel.add(subSouthPanelTwo,BorderLayout.SOUTH);
        add(northPanel,BorderLayout.NORTH);
        add(southPanel,BorderLayout.SOUTH); 
    }


    public JTextField getPlayerUsernameTF() {
        return playerUsernameTF;
    }

    public JPasswordField getPlayerPasswordTF() {
        return playerPasswordTF;
    }

    void addListenerForPlayerLoginBtn(ActionListener actionListener) {
        playerLoginBtn.addActionListener(actionListener);
    }

}

LabelPanel.java

import java.awt.BorderLayout; 
import java.awt.FlowLayout;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class LabelPanel extends JPanel {

    private JPanel panel = new JPanel(new FlowLayout());
    private JLabel labelOne;
    private JLabel labelTwo;

    public LabelPanel(Dealer dealer) {
        setLayout(new BorderLayout());
        labelOne = new JLabel(new ImageIcon(dealer.hideCard()));
        labelTwo = new JLabel(new ImageIcon(dealer.hideCard()));
        panel.add(labelOne);
        panel.add(labelTwo);
        add(panel);
    }


    public JLabel getJLabelOne() {
        return labelOne;
    }

    public JLabel getJLabelTwo() {
        return labelTwo;
    }

    void listenerForJLabelOne(MouseListener listenForMouseClick) {
        labelOne.addMouseListener(listenForMouseClick);
    }

    void listenerForJLabelTwo(MouseListener listenForMouseClick) {
        labelTwo.addMouseListener(listenForMouseClick);
    }
}

经销商.java

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class Dealer {  

    public Dealer() {

    }

    public  Image hideCard() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("resources/images/blank.png"));  
        } catch (Exception e) {
        }

        return img;
    }

    public  Image displayFirsCard() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("resources/images/ClubsAce.png"));   
        } catch (Exception e) {
        }

        return img; 
    }

    public  Image displaySecondCard() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("resources/images/ClubsAce.png"));   
        } catch (Exception e) {
        }
        return img;
    }
}

Controller .java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel; 
import javax.swing.Timer;

public class Controller {

    private LabelPanel labelPanel;
    private Dealer dealer;
    private int countdown = 1;
    private Timer timer = new Timer(1000,null);
    private MouseHandler mouseHandler = new MouseHandler();
    private int clicked = 0;

    public Controller(LabelPanel labelPanel,Dealer dealer) {
        clicked = 0;
        this.labelPanel = labelPanel;
        this.dealer = dealer;
        this.labelPanel.listenerForJLabelOne(mouseHandler); 
        this.labelPanel.listenerForJLabelTwo(mouseHandler); 
        this.labelPanel.getJLabelOne().setText("Ace");
        this.labelPanel.getJLabelTwo().setText("Ace");
    }

    private class MouseHandler extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
            JLabel label = (JLabel) e.getSource();  
            clicked++;

            if(clicked == 1) {
                labelPanel.getJLabelOne().setIcon((new ImageIcon(dealer.displayFirsCard())));
            }

            if(clicked == 2) {
                labelPanel.getJLabelTwo().setIcon((new ImageIcon(dealer.displaySecondCard())));;
                if(label.getText().equals(label.getText())) {
                    System.out.println("last 2 cards detected, starting new game..");
                    timer = new Timer(1000,new newGameTimer());
                    timer.start();
                }
            }
        }
    }

    private class newGameTimer implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if(countdown == 0) { 
                timer.stop();
                clicked = 0;
                labelPanel.removeAll();
                Dealer dealer = new Dealer();
                labelPanel.add(new LabelPanel(dealer));
                labelPanel.revalidate();
                labelPanel.repaint();
                new Controller(labelPanel,dealer);
            }
            else {
                countdown--;
            }
        }   
    }
}

MainFrame.java

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MainFrame {

    private CardLayout cardLayout = new CardLayout();
    private Dealer dealer = new Dealer();  
    private JPanel cardLayoutPanel = new JPanel();
    private LoginPanel loginPanel = new LoginPanel();
    private JFrame frame = new JFrame("Mouse CLick Test");
    private JPanel dialogPanel = new JPanel();
    private LabelPanel labelPanel = new LabelPanel(dealer);
    public MainFrame() {
        cardLayoutPanel.setLayout(cardLayout);
        cardLayoutPanel.add(loginPanel,"1");
        cardLayout.show(cardLayoutPanel,"1");
        cardLayoutPanel.add(labelPanel,"2");
        frame.add(cardLayoutPanel);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setSize(1024,768);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setResizable(false);
        loginPanel.addListenerForPlayerLoginBtn(new PlayerLoginBtnActionPerformed());
    }

    public class PlayerLoginBtnActionPerformed implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            String playerUsername = loginPanel.getPlayerUsernameTF().getText();
            String playerPassword = new String(loginPanel.getPlayerPasswordTF().getPassword());
            if(playerUsername.equals("john") && playerPassword.equals("abc")) { 
                JOptionPane.showMessageDialog(dialogPanel,
                        "Login Successfully!" 
                    ,"Player Login",JOptionPane.PLAIN_MESSAGE);
                cardLayout.show(cardLayoutPanel,"2");
                new Controller(labelPanel,dealer);
            }
            else {
                JOptionPane.showMessageDialog(dialogPanel,
                        "Wrong Password or Username!" 
                        ,"Error",JOptionPane.ERROR_MESSAGE);
            }   
        }
    }

    public static void main(String[]args) { 
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MainFrame();
            }
        });
    }
}

最佳答案

问题是,您正在将 LabelPanel 添加到 LabelPanel

labelPanel.add(new LabelPanel(dealer));

但是您正在将外部面板传递给 Controller ​​

new Controller(labelPanel, dealer);

外部面板实际上不再包含任何标签,而仅包含新的 LabelPanel...

更好的解决方案是为 LabelPanel 提供某种“重置”选项......

关于java - 面板重绘后 mouseListener 丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25360878/

相关文章:

java - 使用 Swing + 模型时识别组合框取消选择吗?

java - 处理过程中 GIF 中的动画不起作用

java - 拍摄完整 JFrame 和仅 Jframe 的快照

java - Swing 到 Javafx 转换

java - Eclipse Juno 彩色代码折叠区域

Java程序流程

java - 编码无符号整数

java - 数据没有得到持久化

java - 我有一个在所有项目中重复使用的类。我应该把它变成一个库组件吗?

java - 为什么顶层容器中的覆盖油漆如此糟糕?