Java:使用Button Adder创建GUI

时间:2015-08-14 18:16:18

标签: java user-interface jframe

我正在尝试使用按钮创建JFrame。当我按下那个按钮时,另一个按钮出现在框架中作为“按钮1”,如果我再次点击然后出现“按钮2”并继续...如果我点击“按钮X”(X是一个数字)它应该消失。我想我在actionListener中遇到了问题,但我无法识别它。

public class ButtonAdder {

    private JFrame frame;
    private JButton button;
    private AddButtonListener listener;

    public ButtonAdder(){
        frame = new JFrame("ButtonAdder");
        button = new JButton("Add new button");
        frame.setLayout(new BorderLayout()); 
        listener = new AddButtonListener();

        frame.add(button, BorderLayout.NORTH);
        button.addActionListener(listener);

        frame.setSize(300, 200);
        frame.setLocation(500, 500);
        frame.setResizable(false); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    }

    public void execute() {
        frame.setVisible(true);
    }
}


 public class AddButtonListener implements ActionListener  {
   private JFrame frame;
    private JButton button;
    private AddButtonListener listener;
     int current_button_number = 1;  

        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == button) {
                // Create a new button:
                JButton newButton = new JButton("Button " + current_button_number++);

                // Change the appearance of the button:
                newButton.setForeground(Color.GREEN);
                newButton.setBackground(Color.BLACK);

                newButton.addActionListener(this);
                frame.add(newButton);      
            } else {
                // The source of the event is the button that was pressed 
                // and that we should remove:
                JButton button_pressed = (JButton) e.getSource();

                // We remove the button from the content pane:
                frame.remove(button_pressed);                               

                // Ask the content pane to eventually redraw itself:
                frame.repaint();                                
            }
            // validate() causes the content pane to re-layout the buttons:
            frame.validate();      
         }

}

public class Main {

 public static void main(String[] args) {
    ButtonAdder button = new ButtonAdder();
    button.execute();

 }

}

1 个答案:

答案 0 :(得分:0)

我在代码中看到的一个问题是对象的引用。一个例子是frameframe中的AddButtonListenerframe中的ButtonAdder不同。如果您将所有代码放在一个类文件中并删除private JFrame frame;中的AddButtonListener,则可以解决此问题。此外,buttonAddButtonListener的测试也存在问题。测试正确按钮的一种方法是测试其文本。在下面的代码中,我放了if(((JButton)e.getSource()).getText().equals("Add new button"))。您的框架布局也是Borderlayout。我只需将其更改为Flowlayout即可让您看到添加新按钮的效果。如果你想坚持使用BorderLayout,你必须找到一种方法,以便AddButtonListener知道将要添加的下一个按钮(中心,左,右,南)的位置。

如果一个文件中的所有代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonAdder {
    private JFrame frame;
    private JButton button;
    private AddButtonListener listener;

    public ButtonAdder(){
        frame = new JFrame("ButtonAdder");
        button = new JButton("Add new button");
//      frame.setLayout(new BorderLayout());
        frame.setLayout(new FlowLayout());
        listener = new AddButtonListener();

//      frame.add(button, BorderLayout.NORTH);
        frame.add(button);
        button.addActionListener(listener);

        frame.setSize(300, 200);
        frame.setLocation(500, 500);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void execute() {
        frame.setVisible(true);
    }


    class AddButtonListener implements ActionListener  {
        //private JFrame frame;
        private JButton button;
        private AddButtonListener listener;
        int current_button_number = 1;

        public void actionPerformed(ActionEvent e) {
            if(((JButton)e.getSource()).getText().equals("Add new button")) {
                // Create a new button:
                JButton newButton = new JButton("Button " + current_button_number++);

                // Change the appearance of the button:
                newButton.setForeground(Color.GREEN);
                newButton.setBackground(Color.BLACK);

                newButton.addActionListener(this);
                frame.add(newButton);
            } else {
                // The source of the event is the button that was pressed
                // and that we should remove:
                JButton button_pressed = (JButton) e.getSource();

                // We remove the button from the content pane:
                frame.remove(button_pressed);

                // Ask the content pane to eventually redraw itself:
                frame.repaint();
            }
            // validate() causes the content pane to re-layout the buttons:
            frame.validate();
        }

    }



    public static void main(String[] args) {
        ButtonAdder button = new ButtonAdder();
        button.execute();

    }
}

如果你真的想像原始代码那样分离类,我的建议是将frame对象传递给AddButtonListener类。然后创建一个以JFrame为参数的构造函数。然后,您应将其分配到frame中的本地AddButtonListener

如果ButtonAdder类在单独的文件中:

public class ButtonAdder {
    private JFrame frame;
    private JButton button;
    private AddButtonListener listener;

    public ButtonAdder(){
        frame = new JFrame("ButtonAdder");
        button = new JButton("Add new button");
//      frame.setLayout(new BorderLayout());
        frame.setLayout(new FlowLayout());
        listener = new AddButtonListener(frame); // pass frame

//      frame.add(button, BorderLayout.NORTH);
        frame.add(button);
        button.addActionListener(listener);

        frame.setSize(300, 200);
        frame.setLocation(500, 500);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void execute() {
        frame.setVisible(true);
    }
}

如果AddButtonListener类位于单独的文件中:

class AddButtonListener implements ActionListener  {
    private JFrame frame;
    private JButton button;
    private AddButtonListener listener;
    int current_button_number = 1;


    public  AddButtonListener(JFrame f) { // create constructor
        frame = f;
    }
    public void actionPerformed(ActionEvent e) {
        if(((JButton)e.getSource()).getText().equals("Add new button")) {
            // Create a new button:
            JButton newButton = new JButton("Button " + current_button_number++);

            // Change the appearance of the button:
            newButton.setForeground(Color.GREEN);
            newButton.setBackground(Color.BLACK);

            newButton.addActionListener(this);
            frame.add(newButton);
        } else {
            // The source of the event is the button that was pressed
            // and that we should remove:
            JButton button_pressed = (JButton) e.getSource();

            // We remove the button from the content pane:
            frame.remove(button_pressed);

            // Ask the content pane to eventually redraw itself:
            frame.repaint();
        }
        // validate() causes the content pane to re-layout the buttons:
        frame.validate();
    }

}