【问题标题】:Drawing circle inside an existing JPanel在现有的 JPanel 内绘制圆圈
【发布时间】:2015-01-05 19:39:29
【问题描述】:

我已经关注了 peeskillet,并根据他最后的想法更改了我的代码。这是修改后的代码

CriclePanel 类

    public class CirclePanel extends JPanel {
    int centerX, centerY, radius;
    Color circle_color;

    public void setCircle(int centerX, int centerY, int radius, Color c) {
        this.centerX = centerX;
        this.centerY = centerY;
        this.radius = radius;
        circle_color = c;
        revalidate();
        repaint();
    }

    protected void paintComponent(Graphics g) {
        System.out.println("Trying to draw circle");
        super.paintComponent(g);
        g.fillOval(centerX, centerY, radius*2, radius*2);
    }
}

网格面板(从调色板添加并自定义构造)

myGridPanel = new JPanel(new GridLayout(8,8));
panels = new CirclePanel[8][8];
    for (int i = 0; i < panels.length; i++) {
        for (int j = 0; j < panels[i].length; j++) {
            CirclePanel panel = new CirclePanel();
            panels[i][j] = panel;
            myGridPanel.add(panel);
        }
    }

尝试添加画圈:

if(dType==DiceType.blackDice){
            System.err.println("black @"+i+","+j);
            panels[i][j].setCircle(x, y, radius, Color.BLACK);
        }else{
            System.err.println("white @"+i+","+j);
            panels[i][j].setCircle(x, y, radius, Color.WHITE);
        }

但是网格面板上没有绘制圆圈,母面板“myGridPanel”上也没有网格。我看到没有调用 CirclePanel 的 paintComponant()。

输出:http://s25.postimg.org/v8u398dun/no_Gridnd_Circle.png

【问题讨论】:

  • 查看Refining the Design 以不制作圈子面板
  • 另外,如果要在运行时添加面板,则需要重新验证并重新绘制容器,但请记住,在网格面板顶部添加面板会导致网格线不显示。您必须使每个圆形面板不透明。此外,您将很难尝试将它们布置出来。我会按照上面的链接进行一些重构
  • 无法理解@peeskillet。你能帮我修改一下我的代码吗?
  • 点击链接。忘记整个第二条评论。基本上,我要说的是不要让每个 Circle 都成为一个面板。该链接将显示我的意思
  • 还有example here

标签: java swing jpanel


【解决方案1】:

正如我在 cmets 中提到的,您可以通过不将每个 Circle 都设置为面板来 Refine your Design。这里是an example

另一个适合您当前设计的选项是在每个圆形面板中都有一个设置器,您可以为其传递一个圆形模型。

public class CirclePanel extends JPanel {
    private Circle circle;

    public void setCircle(Circle cirlce) {
        this.circle = circle;
        repaint();
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (circle != null) {
            // get the state from circle and paint
            g.fillOval(circle.getX(), circle.getY(), getWidth(), getHeight());
        }
    }
}

注意:Circle 在这种情况下不是面板

然后为gridPanel 给它一个GridLayout 并将所有CirclePanel 添加到它。

JPanel gridPanel = new JPanel(new GridLayout(5, 5));
CirclePanel[][] panels = new CirclePanel[5][5];
for (int i = 0; i < panels.length; i++) {
    for (int j = 0; j < panels[i].length; j++) {
        CirclePanel panel = new CirclePanel();
        panels[i][j] = panel;
        gridPanels.add(panel);
    }
}

这样做,gridPanel 中将有空的CirclePanel。然后,当您想在其中一个面板中画一个圆圈时,您可以执行类似的操作

Circle circle = new Circle(...);
panels[1][1].setCircle(circle);

更新

或者现在我想起来了,你甚至不需要 Circle 类,因为你可以只画一个 0, 0, getWidth(), getHeight() 的圆圈。您可以简单地设置一个标志来绘制。但是,如果您想为圆添加更多状态,那么也许您可以保留一个圆类。但如果不是,它可能看起来像

public class CirclePanel extends JPanel {
    private boolean draw;
    private Color color;

    // setter for color
    // setter for draw

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (draw) {
            // get the state from circle and paint
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }
}

更新示例

见方法setDraw。这就是我设置平局或不平局标志的地方。我在Circle 类的鼠标监听器中调用它,但你可以从任何地方调用它。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CircleDemo {
    private static final int GRID_SIZE = 5;
    private Circle[][] circlePanels 
            = new Circle[GRID_SIZE][GRID_SIZE];
    private JPanel gridPanel 
            = new JPanel(new GridLayout(GRID_SIZE, GRID_SIZE));

    public CircleDemo() {
        initCircles();
        JFrame f = new JFrame();
        f.add(gridPanel);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private void initCircles() {
        for (int i = 0; i < circlePanels.length; i++) {
            for (int j = 0; j < circlePanels[i].length; j++) {
                Circle circle = new Circle();
                circlePanels[i][j] = circle;
                gridPanel.add(circle);
            }
        }
    }

    class Circle extends JPanel {
        private boolean draw = false;
        private Color color = Color.BLUE;

        public Circle() {
            setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
            addMouseListener(new MouseAdapter(){
                public void mousePressed(MouseEvent e) {
                    if (isDraw()) {
                        setDraw(false);
                    } else {
                        setDraw(true);
                    }  
                }
            });
        }

        public boolean isDraw() {
            return draw;
        }

        public void setDraw(boolean draw) {
            this.draw = draw;
            repaint();
        }

        public void setColor(Color color) {
            this.color = color;
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(75, 75);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (draw) {
                g.setColor(color);
                g.fillOval(0, 0, getWidth(), getHeight());
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new CircleDemo();
            }
        });
    }
}

【讨论】:

  • 我已采纳您的第二条建议并更改了我的代码。仍然无济于事。没有绘制圆圈,也没有网格
  • UPDATE 中的建议?您是否创建了方法setDraw(boolean),并设置了draw 值和repaint()?您是否从一开始就将所有面板添加到网格中。更新部分实际上是两者的结合。我很快就会发布一个例子
  • 查看我最近的更新。当你运行它时,只需单击一个单元格使圆圈出现,然后再次单击它使其消失
猜你喜欢
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 2015-07-04
  • 2015-07-08
  • 2018-08-09
  • 2021-10-15
相关资源
最近更新 更多