如何在 JPanel 上用 Java 绘制彩色圆圈?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3795502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I draw colored circles in Java on a JPanel?
提问by Zach Dziura
I'm doing another Java project for my class. In this assignment, we have to create a checkerboard and populate it with the appropriate number of checkers. I built the checkerboard correctly which displays nicely, but I'm having a hard time using the Graphics class to draw.
我正在为我的班级做另一个 Java 项目。在这个作业中,我们必须创建一个棋盘格并用适当数量的棋子填充它。我正确构建了显示效果很好的棋盘格,但是我很难使用 Graphics 类进行绘制。
Here's the code that I have so far:
这是我到目前为止的代码:
import javax.swing.*;
import java.awt.*;
public class Checkerboard extends JFrame {
//Define the default values for the separate checker pieces
private final int RED_PIECE = 0;
private final int BLACK_PIECE = 1;
/** Construct the default checker board */
public Checkerboard() {
this.setSize(600, 600);
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setTitle("Checkerboard Lab");
this.setLayout(new GridLayout(8, 8));
this.setVisible(true);
for (int a=0; a<2; a++) {
for (int i=0; i<4; i++) {
add(new WhiteSpace());
add(new GraySpace(RED_PIECE));
}
for (int j=0; j<4; j++) {
add(new GraySpace(RED_PIECE));
add(new WhiteSpace());
}
}
for (int b=0; b<2; b++) {
for (int k=0; k<4; k++) {
add(new WhiteSpace());
add(new GraySpace(RED_PIECE));
}
for (int l=0; l<4; l++) {
add(new GraySpace());
add(new WhiteSpace());
}
}
for (int c=0; c<2; c++) {
for (int m=0; m<4; m++) {
add(new GraySpace());
add(new WhiteSpace());
}
for (int n=0; n<4; n++) {
add(new GraySpace(BLACK_PIECE));
add(new WhiteSpace());
}
}
for (int d=0; d<2; d++) {
for (int o=0; o<4; o++) {
add(new WhiteSpace());
add(new GraySpace(BLACK_PIECE));
}
for (int p=0; p<4; p++) {
add(new GraySpace(BLACK_PIECE));
add(new WhiteSpace());
}
}
}
/** White Space constructor */
public class WhiteSpace extends JPanel {
public WhiteSpace() {
setBackground(Color.WHITE); //Sets the panel's background color to white
}
}
/** Gray Space constructor */
/* GraySpace is a little different, since this color space is the only space that will be holding checker
* pieces. There is a default constructor to create a space without a checker piece on it, and another
* constructor that places either a red or black piece on the space, pending an optional parameter.*/
public class GraySpace extends JPanel {
//Initial variable for the checker piece
int checkerPiece;
//Default GraySpace constructor
public GraySpace() {
setBackground(Color.LIGHT_GRAY);
}
//The GraySpace constructor with the optional parameter to determine if it holds a checker piece
public GraySpace(int piece) {
this.checkerPiece = piece;
setBackground(Color.LIGHT_GRAY); //Sets the panel's background color to white
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//Default width and height variables
int width = getWidth() -10;
int height = getHeight() - 10;
//This switch statement determines which checker piece type appears on the square
switch (checkerPiece) {
case RED_PIECE:
g.setColor(Color.RED);
g.fillOval(5, 5, width, height);
break;
case BLACK_PIECE:
g.setColor(Color.BLACK);
g.fillOval(5, 5, width, height);
break;
}
}
}
/** Initiate the Checker board */
public static void main(String[] args) {
JFrame checkerboard = new Checkerboard();
}
}
It's fairly straight forward. I have my Checkerboard class be a subclass of JFrame, which I put colored panels on in an 8x8 square. The panels are inner classes of the Checkerboard class, each extending JPanel (WhiteSpace and GraySpace respectfully). Since GraySpace is the only class that will have to hold a checker, I thought that I'd simply put the Graphics code into the GraySpace inner class.
这是相当直接的。我的 Checkerboard 类是 JFrame 的子类,我将彩色面板放在 8x8 正方形中。面板是 Checkerboard 类的内部类,每个面板都扩展了 JPanel(分别为 WhiteSpace 和 GraySpace)。由于 GraySpace 是唯一必须持有检查器的类,我认为我只需将 Graphics 代码放入 GraySpace 内部类。
Anyhow, for my question: How do I go about using Graphics to draw that? I know I have to explicitly declare the paintComponent() method in order to draw the circle, but I don't have any clue how to specify the dimensions of the GraySpace so it will draw effectively. Any advice?
无论如何,对于我的问题:我如何使用 Graphics 来绘制它?我知道我必须显式声明 PaintComponent() 方法才能绘制圆,但我不知道如何指定 GraySpace 的尺寸以使其有效绘制。有什么建议吗?
EDIT: NEW QUESTION!
编辑:新问题!
Alright, so I figured out exactly how I would be adding pieces onto my board, and that works perfectly. My GraySpace inner class has an optional constructor that takes in an int
value, and from that determines what color piece will go on the GraySpace panel. I tested that out, and it works.
好的,所以我确切地想出了如何将碎片添加到我的板上,并且效果很好。我的 GraySpace 内部类有一个可选的构造函数,它接受一个int
值,并从中确定在 GraySpace 面板上的颜色块。我测试了,它的工作原理。
My problem, however, is actually GETTING the pieces onto the checkerboard. The board must represent a "default" checker game, where all available pieces are on the board. So, three rows of red checkers, three rows of black checkers, with two empty rows separating them. Thus far, I have 4 separate for
loops to draw two rows at a time on the board... But it's not working properly. Any advice? The latest source code is above, replacing my old questions source code. Again, thank you for any advice!
然而,我的问题实际上是将棋子放在棋盘上。棋盘必须代表一个“默认”的棋盘游戏,棋盘上所有可用的棋子。所以,三排红色棋子,三排黑色棋子,中间有两个空行将它们隔开。到目前为止,我有 4 个单独的for
循环在板上一次绘制两行......但它无法正常工作。有什么建议吗?上面是最新的源代码,替换我的老问题源代码。再次感谢您的任何建议!
采纳答案by Starkey
Call getHeight
and getWidth
on the component you are in. Since paintComponent
is a member of your JPanel
class, you can just call getHeight
and getWidth
directly.
在你所在的组件上调用getHeight
and getWidth
。因为paintComponent
是你的JPanel
类的成员,你可以直接调用getHeight
and getWidth
。
I made a couple of other changes to your method.
我对你的方法做了一些其他的改变。
- Don't call
this.paintComponent
, call the base class (super
) - You need to set the color before you draw.
- I bet
fillOval
is what you want.
- 不调用
this.paintComponent
,调用基类(super
) - 您需要在绘制之前设置颜色。
- 我打赌
fillOval
这就是你想要的。
For example:
例如:
protected void paintComponent(Graphics g) {
int h = getHeight();
int w = getWidth();
super.paintComponent(g);
g.setColor(CHECKER_COLOR);
g.fillOval(w/2, h/2, w, h);
}
For extra credit, turn on antialiasing and make your checkers look great!
为了获得额外的荣誉,打开抗锯齿,让您的跳棋看起来很棒!
回答by Andrew Hubbs
One thing about your for loops just for future knowledge, when you define int i=0, that variable only exists within that loop, so you don't need to use a different variable a,b,c,d,e, etc in your 4 for loops you could simply use i,j,k 4 times.
关于 for 循环的一件事只是为了将来的知识,当您定义 int i=0 时,该变量仅存在于该循环中,因此您无需在其中使用不同的变量 a、b、c、d、e 等你的 4 个 for 循环你可以简单地使用 i,j,k 4 次。
Also, I think your loops are adding a lot more pieces than you want.
此外,我认为您的循环添加的部分比您想要的要多得多。
for (int a=0; a<2; a++) { //2 (
for (int i=0; i<4; i++) { // 4
add(new WhiteSpace()); // (1
add(new GraySpace(RED_PIECE)); // + 1)
} // +
for (int j=0; j<4; j++) { // 4
add(new GraySpace(RED_PIECE)); // (1
add(new WhiteSpace()); // + 1)
} // )
} //= 2 ( 4 * 2 + 4 * 2) = 32
In this one loop you are adding 32 squares. You do this 4 times. That is already twice the squares you need.
在这个循环中,您将添加 32 个方格。你这样做4次。这已经是你需要的平方的两倍了。
The very simplest solution is to remove the 4 outer loops. Then you would have what you want.
最简单的解决方案是移除 4 个外环。然后你就会得到你想要的。