面板重新绘制后,mouseListener丢失

时间:2014-08-18 10:12:56

标签: java swing

我的程序将允许用户首先登录,如果他已登录, 他将首先点击labelone,然后点击下一个标签。 程序将打印("检测到最后两张卡片。开始新游戏......")并允许用户再次点击两个标签。

我面临的问题是在我的面板重新粉刷之后。我无法点击标签 了。

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

我认为主要关注的是我的控制器类中的代码块。

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

我不确定我的mouselistener发生了什么。请帮忙

这是班级。如果你们无法理解,可以随意运行它。

  • 以用户名登录 - >约翰密码 - > ABC
  • 首先点击标签,然后点击标签2。控制台将显示 "检测到最后2张牌,开始新游戏。" 之后尝试再次单击标签(右侧应该是可点击的,但它不是)

LoginPanel.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);
    }
}

Dealer.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();
            }
        });
    }
}

1 个答案:

答案 0 :(得分:2)

问题是,您要向LabelPanel

添加LabelPanel
labelPanel.add(new LabelPanel(dealer));

但是您将外部面板传递给控制器​​

new Controller(labelPanel, dealer);

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

更好的解决方案是为LabelPanel提供"重置"某种选择......