Java:按钮被激活而不被单击

时间:2015-03-26 07:42:22

标签: java eclipse swing

问题:我的代码应该在按下按钮时创建一个JPanel,而是在代码开始运行时立即创建JPanel。

我在Eclipse Luna上用Java SE7编写,我的操作系统是Windows 8.1。

我一直在尝试编写一个具有固定“窗口”(我正在使用JFrame)的程序,并且可以在“屏幕”(JPanels)之间切换。切换应该使用按钮完成。目前我已经在我的主要功能中创建了第一个面板和框架,以及添加了一个按钮。然后我添加了一个actionPerformed方法,它创建了第二个面板。我将JFrame作为字段变量,以便方法识别它。

问题是第二个面板出现在我运行代码的那一刻,根本没有任何按钮的迹象。

这是我的主要课程(包括actionPerformed方法):

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

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;

public class WindowOne implements ActionListener{
    //A JFrame field is created
    public static JFrame frame = new JFrame("JFrame");

    public static void main(String[] args) {

        //Not sure what this line does
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Sets dimensions of frame
        frame.setBounds(100, 100, 600, 600);

        //Create an instance of GamePanel (a separate class)
        GamePanel gamePanel = new GamePanel();
        //Set this panel to the frame
        frame.setContentPane(gamePanel);

        //Create new button panelButton
        JButton panelButton = new JButton("Welcome");
        //Create instance of WindowOne
        WindowOne listener = new WindowOne();
        //Adds action listener to panelButtom
        panelButton.addActionListener(listener);

        //Add panelButton to the panel
        gamePanel.add(panelButton);

        //Display frame AFTER adding all components to it
        frame.setVisible(true);
    }


    //This method is called when the panelButton is clicked (at least, that's what's supposed to happen)
    public void actionPerformed(ActionEvent e) {
        GamePanel gamePanel2 = new GamePanel();
        gamePanel2.paint(null);
        frame.setContentPane(gamePanel2);
    }
}

这是另一个类,GamePanel,我用来创建和“绘制”面板(我的朋友,一个更有经验的程序员,坚持我使用这个类,而不仅仅是制作面板的基本方式)。

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;


public class GamePanel extends JPanel {

    public GamePanel(){

    }

    public void paint(Graphics g){
        //Use this method with instances of GamePanel to design different panels
        g.fillRect(10,10,10,10);
    }
}

回答!我将所有内容简化为一个类,如果将来有人发现它有用,这里是更正后的代码。

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

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Color;

public class WindowOne{
    //A JFrame field is created
    public static JFrame frame = new JFrame("JFrame");

    public static void main(String[] args) {

        //FRAME STUFF
        //Not sure what this line does
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Sets dimensions of frame
        frame.setBounds(100, 100, 600, 600);

        //PANEL STUFF
        //Create the first panel
        JPanel panelOne = new JPanel();
        //Set this panel to the frame
        frame.setContentPane(panelOne);

        //BUTTON STUFF
        //Create new button panelButton
        JButton panelButton = new JButton("Welcome");
        //Add anonymous action listener to panelButton
        panelButton.addActionListener(new ActionListener(){
            @Override public void actionPerformed(ActionEvent ae){
                //What happens when button is clicked:
                JPanel panelTwo = new JPanel();
                panelTwo.setBackground(Color.black);
                frame.setContentPane(panelTwo);
                frame.setVisible(true);
            }
        });

        //OTHER STUFF

        //Add panelButton to the panel
        panelOne.add(panelButton);

        //Display frame AFTER adding all components to it
        frame.setVisible(true);
    }
}

2 个答案:

答案 0 :(得分:2)

您添加的第一个面板也是GamePanel实例,这就是您看到正方形的原因。这是因为第一个面板也绘制了正方形,而不是因为第二个面板已经在JFrame上。

编辑:一些额外提示:

- 无论是直接调用组件的paint方法,框架都会为您完成。如果您想告诉它您想要再次绘制一个组件,请调用repaint()方法。

- 当覆盖paint(Graphics g)上的Component方法时,最好先调用超类'方法:super.paint(g)。这将做一些事情,比如画背景。

- 不要覆盖paint(Graphics g)方法,而应覆盖swing组件中的paintComponent(Graphics g)类。更多信息here

- 您可以创建匿名ActionListener个实例,而不是让您的组件像这样实现它们:

panelButton.addActionListener(new ActionListener(){
    @Override public void actionPerformed(ActionEvent ae){
        //your code when button is clicked
    }
});

(如果你使用的是java 8,甚至只是一个lambda)

答案 1 :(得分:0)

如上所述,actionPerformed很可能无法调用,因为它会导致NullPointerException

相反,您看到的仍然是gamePanel。它绘制了这个小方块,因为当你调用frame.setVisible(true);时会调用paint方法。

不幸的是,按钮没有被绘制,因为通过覆盖paint方法,gamePanel的孩子不会收到他们的paint电话。

在GamePanel中尝试:

public void paint(Graphics g){
    super.paint(g);
    //Use this method with instances of GamePanel to design different panels
    g.fillRect(10,10,10,10);
}