单击 JButton 将组件动态添加到 JPanel

Dynamically Adding Components to JPanel on click of JButton

这是我的街区class:

public class Block extends JComponent {
    public int width, height;
    public Color colour;

    public Block( int width, int height, Color colour) {
        super();
        setSize(new Dimension(width, height));
        setPreferredSize(new Dimension(width, height));
        setBackground(colour);
        this.width = width;
        this.height = height;
        this.colour = colour;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(colour);
        g.fillRect(0, 0, width, height);
    }
}

还有我的球class:

public class Ball extends JComponent {
    public int width, height;
    public Color colour;

    public Ball(int width, int height, Color colour) {
        super();
        setSize(new Dimension(width, height));
        setPreferredSize(new Dimension(width, height));
        setBackground(colour);
        this.width = width;
        this.height = height;
        this.colour = colour;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(colour);
        g.fillOval(0, 0, width, height);
    }
}

这是我的主class:

public class Main extends JPanel {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setContentPane(new Main());
        frame.setSize(new Dimension(1000, 1000));
        frame.setPreferredSize(new Dimension(1000, 1000));
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public Main() {
        JComboBox<String> shapes = new JComboBox(new String[]{"Square", "Oval"});

        JSpinner width = new JSpinner();
        SpinnerNumberModel widthModel = new SpinnerNumberModel();
        widthModel.setMinimum(1);
        widthModel.setMaximum(200);
        width.setModel(widthModel);

        JSpinner height = new JSpinner();
        SpinnerNumberModel heightModel = new SpinnerNumberModel();
        heightModel.setMinimum(1);
        heightModel.setMaximum(200);
        height.setModel(heightModel);

        JButton submit = new JButton("Add Shape");
        submit.addActionListener((ActionEvent e) -> {
            if (shapes.getSelectedItem().equals("Square")) {
                add(new Block((Integer)widthModel.getValue(), (Integer)heightModel.getValue(), Color.BLUE));
            } else {
                add(new Ball((Integer)widthModel.getValue(), (Integer)heightModel.getValue(), Color.BLUE));                
            }
        });

        add(shapes);
        add(width);
        add(height);
        add(submit);


    }
}

当您单击 "submit" 按钮时,它应该添加一个正方形或椭圆形(取决于您的选择),其高度和宽度由您在微调器中指定。然而,它什么也没有。我打印出宽度和高度,它们是有效的,所以没有问题。另外,我尝试自己添加自定义组件并且成功了。

你忘记了两件重要的事情:

  1. 您需要为 BrickBall
  2. 定义方法 getPreferredSize()
  3. 您需要使用方法 revalidate()repaint()
  4. 更新布局

固定代码如下:

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

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

public class Main extends JPanel {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setContentPane(new Main());
        frame.setSize(new Dimension(1000, 1000));
        frame.setPreferredSize(new Dimension(1000, 1000));
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public Main() {
        JComboBox<String> shapes = new JComboBox(new String[] {"Square", "Oval"});

        JSpinner width = new JSpinner();
        SpinnerNumberModel widthModel = new SpinnerNumberModel();
        widthModel.setMinimum(1);
        widthModel.setMaximum(200);
        width.setModel(widthModel);

        JSpinner height = new JSpinner();
        SpinnerNumberModel heightModel = new SpinnerNumberModel();
        heightModel.setMinimum(1);
        heightModel.setMaximum(200);
        height.setModel(heightModel);

        JButton submit = new JButton("Add Shape");
        submit.addActionListener(e -> {
            if (shapes.getSelectedItem().equals("Square")) {
                add(new Block((Integer) widthModel.getValue(), (Integer) heightModel.getValue(), Color.BLUE));
            } else {
                add(new Ball((Integer) widthModel.getValue(), (Integer) heightModel.getValue(), Color.BLUE));
            }
            revalidate();
            repaint();
        });

        add(shapes);
        add(width);
        add(height);
        add(submit);

    }

    public static class Block extends JComponent {
        public int width, height;

        private final Dimension size;

        public Color colour;

        public Block(int width, int height, Color colour) {
            super();
            setSize(new Dimension(width, height));
            setPreferredSize(new Dimension(width, height));
            setBackground(colour);
            this.width = width;
            this.height = height;
            this.colour = colour;
            this.size = new Dimension(width, height);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(colour);
            g.fillRect(0, 0, width, height);
        }

        @Override
        public Dimension getPreferredSize() {
            return size;
        }
    }

    public class Ball extends JComponent {
        public int width, height;

        private final Dimension size;

        public Color colour;

        public Ball(int width, int height, Color colour) {
            super();
            setSize(new Dimension(width, height));
            setPreferredSize(new Dimension(width, height));
            setBackground(colour);
            this.width = width;
            this.height = height;
            this.colour = colour;
            this.size = new Dimension(width, height);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(colour);
            g.fillOval(0, 0, width, height);
        }

        @Override
        public Dimension getPreferredSize() {
            return size;
        }
    }
}

添加组件后调用repaint()方法。