通过按JButton在随机JPanel上绘制圆圈

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过按JButton在随机JPanel上绘制圆圈相关的知识,希望对你有一定的参考价值。

我有一个带JPanels的网格,通过按下顶部的按钮,我想要一个随机生成器在3个随机面板上绘制圆圈。从理论上讲,我认为我必须用圆形覆盖每个JPanel的PaintComponent,将标志置于false状态,当我按下按钮时,动作监听器将3个随机JPanels的标志置为true。

但我真的不知道该怎么做。有可能这样做吗?如果是的话,你能告诉我如果没有,你能告诉我还有什么我必须做的吗?非常感谢。到目前为止,这是我的代码:

package feld;

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

public class Spielplan {

public static void main(String[] args) {



JFrame f1 = new JFrame();
f1.setLayout(new BorderLayout());
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setPreferredSize(new Dimension(800, 800));

JButton tokens = new JButton("Spielsteine setzen");
f1.add(tokens, BorderLayout.NORTH);

JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(3,3));
f1.add(p1, BorderLayout.CENTER);

JPanel g1 = new JPanel();
g1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g1.setPreferredSize(new Dimension(100, 100));
g1.setVisible(true);
p1.add(g1);


JPanel g2 = new JPanel();
g2.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g2.setPreferredSize(new Dimension(100, 100));
g2.setVisible(true);
p1.add(g2);

JPanel g3 = new JPanel();
g3.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g3.setPreferredSize(new Dimension(100, 100));
g3.setVisible(true);
p1.add(g3);

JPanel g4 = new JPanel();
g4.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g4.setPreferredSize(new Dimension(100, 100));
g4.setVisible(true);
p1.add(g4);

JPanel g5 = new JPanel();
g5.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g5.setPreferredSize(new Dimension(100, 100));
g5.setVisible(true);
p1.add(g5);

JPanel g6 = new JPanel();
g6.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g6.setPreferredSize(new Dimension(100, 100));
g6.setVisible(true);
p1.add(g6);

JPanel g7 = new JPanel();
g7.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g7.setPreferredSize(new Dimension(100, 100));
g7.setVisible(true);
p1.add(g7);

JPanel g8 = new JPanel();
g8.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g8.setPreferredSize(new Dimension(100, 100));
g8.setVisible(true);
p1.add(g8);

JPanel g9 = new JPanel();
g9.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g9.setPreferredSize(new Dimension(100, 100));
g9.setVisible(true);
p1.add(g9);

f1.pack();
f1.setVisible(true);    




}
}
答案

我能想到的最简单的方法是使用布尔值创建JPanel的子类,以确定是否应该绘制圆。我把它命名为CirclePanel

public class CirclePanel extends JPanel{

    public static final Color circleColor = Color.BLACK;

    private boolean drawCircle;

    public CirclePanel() {
        drawCircle=false;
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        setBackground(Color.WHITE);
    }

    public void setDrawCircle(boolean drawCircle) {
        this.drawCircle = drawCircle;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        if(drawCircle) {

            Graphics2D g2d = (Graphics2D) g;
            Color tmp = g2d.getColor();
            g2d.setColor(circleColor);

            g2d.fillOval(0, 0, getWidth(), getHeight());

            g2d.setColor(tmp);
        }
    }
}

然后我为框架创建了一个JFrame的子类,但你也可以用main方法完成它。我将圆形面板放在一个数组中,以避免重复代码并将它们放在网格中。单击该按钮时,将创建一个List索引,并随机删除三个索引。然后使用该列表设置面板的布尔变量。见下文:

public class CircleGrid extends JFrame implements ActionListener{

    private CirclePanel[] panels;
    private JButton button;


    public CircleGrid() {
        super("Circle test");

        setLayout(new BorderLayout());

        panels = new CirclePanel[9];
        JPanel center = new JPanel();
        center.setLayout(new GridLayout(3, 3));

        for (int i = 0; i < panels.length; i++) {
            panels[i] = new CirclePanel();
            center.add(panels[i]);
        }

        button = new JButton("Color in");
        button.addActionListener(this);

        this.add(button, BorderLayout.NORTH);
        this.add(center, BorderLayout.CENTER);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(800, 800));
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(button)) {
            // select three random circle indices -
            // https://stackoverflow.com/a/42353488/7015661
            ArrayList<Integer> indices = new ArrayList<Integer>();
            int numRandom = 3; // three indices

            for (int i = 0; i < panels.length; i++) {
                indices.add(i);
            }

            Random r = new Random();

            for (int i = 0; i < numRandom; i++) {
                int rndPos1 = r.nextInt(indices.size());
                indices.remove(rndPos1); // remove three indices from the list
            }

            // change panel boolean
            for (int i = 0; i < panels.length; i++) {
                CirclePanel pi = panels[i];

                if(indices.contains(i)) {
                    // no circle
                    pi.setDrawCircle(false);
                }else {
                    //draw circle
                    pi.setDrawCircle(true);
                }
            }

            repaint(); // redraw panels
        }
    }

    public static void main(String[] args) {
        new CircleGrid();
    }
}

我最终得到以下结果:

Test UI

另一答案

你要做的事情基本上是你在你的jPanel上画出白色整个面板然后画出你的圆圈应用下面的代码希望有所帮助。

int name=(int) Math.random() * 100;
int name1=(int) Math.random() * 100;

然后,您将使用图形方法和相应的代码在JPanels上绘制圆圈。以下是在随机位置绘制圆圈的代码:

g.draw/fillOval (name,name1,100,100);

以上是关于通过按JButton在随机JPanel上绘制圆圈的主要内容,如果未能解决你的问题,请参考以下文章

如何通过单击 JButton 添加 JPanel?

为什么我的JButton在放入JPanel的构造函数时不显示?

在 Java 中创建自定义 JButton

让 JButton 打开一个新的 JPanel

如何使 JPanel 中的组件尽可能伸展?

如何使用默认 FlowLayout 在 JPanel 中将 JButton 居中?