初学者 Graphics2D Java:重绘()
Beginner Graphics2D Java : repaint()
我试图在 Action 处理程序中更改我的红色圆圈的颜色,然后 repaint()
我无法弄清楚为什么它不起作用。
这里进口
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
我的 class 在这里:
public class CirclePanel extends JPanel implements ActionListener {
static JFrame f;
static JButton run1, run2, reset, quit;
static JPanel btnPanel;
static CirclePanel circlePanel;
static final int NUM = 5;
static Color c;
static Graphics2D g2;
static Graphics2D g3;
public CirclePanel(){
f = new JFrame();
f.setTitle("Dining Philosophers");
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.setSize(1000,1000);
f.setLayout(new BorderLayout());
btnPanel = new JPanel();
btnPanel.setPreferredSize(new Dimension(250, 100));
btnPanel.add(run1 = new JButton("Run 1"));
btnPanel.add(run2 = new JButton("Run 2"));
btnPanel.add(reset = new JButton("Reset"));
btnPanel.add(quit = new JButton("Quit"));
run1.setPreferredSize(new Dimension(180, 50));
run2.setPreferredSize(new Dimension(180, 50));
reset.setPreferredSize(new Dimension(180, 50));
quit.setPreferredSize(new Dimension(180, 50));
run1.addActionListener(this);
f.add(btnPanel, BorderLayout.SOUTH);
f.add(this, BorderLayout.CENTER);
f.setVisible(true);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g2 = (Graphics2D) g;
g3 = (Graphics2D) g;
g2.translate(470, 400);
c = Color.red;
for(int i = 0; i < NUM; ++i){
c = Color.red;
g2.setColor( c);
g2.fillOval(150, 0, 100, 100);
g3.setColor(Color.BLACK);
g3.fillOval(90, 0, 30, 30);
g2.rotate(2*Math.PI/ NUM);
}
}
如您所见,当我按下按钮 Run1 时,它确实进入了动作处理程序并执行了重绘方法,但没有任何变化。
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == run1) {
System.out.println("Entered Action Handler");
g2.setColor(Color.green);
repaint();
}
}
这是我的主要内容:
public static void main(String[] args) {
new CirclePanel();
}
}
Graphics 对象寿命不长,不稳定,您不应该以这种方式使用它们。不要设置 g2 或任何其他图形 字段 ,而是创建一个名为 Color circleColor = ...;
的颜色字段,然后更改 this。在 protected void paintComponent(Graphics g)
方法中,调用 g.setColor(circleColor);
,这应该有效。
删除这些字段,因为它们很危险:
// static Graphics2D g2;
// static Graphics2D g3;
此外,您的代码显示过度使用静态修饰符,我冒昧地建议您的 none 个字段应该是静态的,除了常量:
static final int NUM
repaint() 方法最终会调用面板的 paintComponent() 方法。 Swing会传入Graphics对象来进行绘画。
在绘画代码中,您总是将颜色硬编码为红色。不要这样做。
相反,您需要在面板中定义一个变量 class。比方说 "circleColor"(即 "circleColor" 替换您的 "c" 变量,因为变量名称应该更具描述性,而不仅仅是单个字符)。
然后在您的 ActionListener 代码中执行:
//g2.setColor(Color.green);
circleColor = Color.green;
你在 paintCompnent() 方法中这样做:
//c = Color.red;
g.setColor(circleColor);
另外:
static Graphics2D g2;
static Graphics2D g3;
不需要任何这些变量。您始终使用传递给绘画方法的 Graphics 对象。
阅读有关 Custom Painting 的 Swing 教程部分,了解更多信息以及有关如何构建代码的更好示例。例如,您不应该使用静态变量。
发生的事情是:
- 您正在更改动作侦听器中的
g2
颜色。
- 然后你调用
repaint();
所以 paintComponent(Graphics g)
被调用。
- 在
paintComponent(Graphics g)
方法中,您将 g2
颜色设置为 c
,以便覆盖您在动作侦听器中所做的更改。
这就是为什么圆圈最终没有改变颜色的原因。
您应该在构造函数中而不是在for
循环中设置c = Color.RED;
,然后您只需在动作侦听器c = Color.GREEN;
中更改c
的值即可。
此外,您在 for
循环中和循环之前都设置了 c = Color.RED;
,这是无用的。
编辑:
正如 @camickr
所建议的那样,您的代码结构也很糟糕。
- 您不需要
g2
和 g3
因为您可以绘制多个形状
使用相同的 Graphics g
对象。
- 在你的情况下,你甚至不需要在
paintComponent
方法之外调用 g
,因为你可以像我上面说的那样简单地更改 Color c
变量。
- 您也不需要所有这些
static
变量。只需将它们设为 private
,如果您需要从 class 外部访问它们,您应该创建一些 getters
和 setters
.
Here you'll find more on static variables and some examples.
Here you'll find more about getters, setters and encapsulation.
如何更改代码的示例:
public class CirclePanel extends JPanel implements ActionListener {
private JFrame f;
private JButton run1, run2, reset, quit;
private JPanel btnPanel;
private int NUM;
private Color c;
public CirclePanel(){
color1 = Color.red;
color2 = Color.black;
NUM = 5;
// Setup JFrame and stuff as you were doing.
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.translate(470, 400);
for(int i = 0; i < NUM; i++){
g.setColor(color1);
g.fillOval(150, 0, 100, 100);
g.setColor(color2);
g.fillOval(90, 0, 30, 30);
g.rotate(2*Math.PI/ NUM);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == run1) {
System.out.println("Entered Action Handler");
color1 = Color.green;
repaint();
}
}
// GETTERS and SETTERS if needed
}
我试图在 Action 处理程序中更改我的红色圆圈的颜色,然后 repaint()
我无法弄清楚为什么它不起作用。
这里进口
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
我的 class 在这里:
public class CirclePanel extends JPanel implements ActionListener {
static JFrame f;
static JButton run1, run2, reset, quit;
static JPanel btnPanel;
static CirclePanel circlePanel;
static final int NUM = 5;
static Color c;
static Graphics2D g2;
static Graphics2D g3;
public CirclePanel(){
f = new JFrame();
f.setTitle("Dining Philosophers");
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.setSize(1000,1000);
f.setLayout(new BorderLayout());
btnPanel = new JPanel();
btnPanel.setPreferredSize(new Dimension(250, 100));
btnPanel.add(run1 = new JButton("Run 1"));
btnPanel.add(run2 = new JButton("Run 2"));
btnPanel.add(reset = new JButton("Reset"));
btnPanel.add(quit = new JButton("Quit"));
run1.setPreferredSize(new Dimension(180, 50));
run2.setPreferredSize(new Dimension(180, 50));
reset.setPreferredSize(new Dimension(180, 50));
quit.setPreferredSize(new Dimension(180, 50));
run1.addActionListener(this);
f.add(btnPanel, BorderLayout.SOUTH);
f.add(this, BorderLayout.CENTER);
f.setVisible(true);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g2 = (Graphics2D) g;
g3 = (Graphics2D) g;
g2.translate(470, 400);
c = Color.red;
for(int i = 0; i < NUM; ++i){
c = Color.red;
g2.setColor( c);
g2.fillOval(150, 0, 100, 100);
g3.setColor(Color.BLACK);
g3.fillOval(90, 0, 30, 30);
g2.rotate(2*Math.PI/ NUM);
}
}
如您所见,当我按下按钮 Run1 时,它确实进入了动作处理程序并执行了重绘方法,但没有任何变化。
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == run1) {
System.out.println("Entered Action Handler");
g2.setColor(Color.green);
repaint();
}
}
这是我的主要内容:
public static void main(String[] args) {
new CirclePanel();
}
}
Graphics 对象寿命不长,不稳定,您不应该以这种方式使用它们。不要设置 g2 或任何其他图形 字段 ,而是创建一个名为 Color circleColor = ...;
的颜色字段,然后更改 this。在 protected void paintComponent(Graphics g)
方法中,调用 g.setColor(circleColor);
,这应该有效。
删除这些字段,因为它们很危险:
// static Graphics2D g2;
// static Graphics2D g3;
此外,您的代码显示过度使用静态修饰符,我冒昧地建议您的 none 个字段应该是静态的,除了常量:
static final int NUM
repaint() 方法最终会调用面板的 paintComponent() 方法。 Swing会传入Graphics对象来进行绘画。
在绘画代码中,您总是将颜色硬编码为红色。不要这样做。
相反,您需要在面板中定义一个变量 class。比方说 "circleColor"(即 "circleColor" 替换您的 "c" 变量,因为变量名称应该更具描述性,而不仅仅是单个字符)。
然后在您的 ActionListener 代码中执行:
//g2.setColor(Color.green);
circleColor = Color.green;
你在 paintCompnent() 方法中这样做:
//c = Color.red;
g.setColor(circleColor);
另外:
static Graphics2D g2;
static Graphics2D g3;
不需要任何这些变量。您始终使用传递给绘画方法的 Graphics 对象。
阅读有关 Custom Painting 的 Swing 教程部分,了解更多信息以及有关如何构建代码的更好示例。例如,您不应该使用静态变量。
发生的事情是:
- 您正在更改动作侦听器中的
g2
颜色。 - 然后你调用
repaint();
所以paintComponent(Graphics g)
被调用。 - 在
paintComponent(Graphics g)
方法中,您将g2
颜色设置为c
,以便覆盖您在动作侦听器中所做的更改。
这就是为什么圆圈最终没有改变颜色的原因。
您应该在构造函数中而不是在for
循环中设置c = Color.RED;
,然后您只需在动作侦听器c = Color.GREEN;
中更改c
的值即可。
此外,您在 for
循环中和循环之前都设置了 c = Color.RED;
,这是无用的。
编辑:
正如 @camickr
所建议的那样,您的代码结构也很糟糕。
- 您不需要
g2
和g3
因为您可以绘制多个形状 使用相同的Graphics g
对象。 - 在你的情况下,你甚至不需要在
paintComponent
方法之外调用g
,因为你可以像我上面说的那样简单地更改Color c
变量。 - 您也不需要所有这些
static
变量。只需将它们设为private
,如果您需要从 class 外部访问它们,您应该创建一些getters
和setters
.
Here you'll find more on static variables and some examples.
Here you'll find more about getters, setters and encapsulation.
如何更改代码的示例:
public class CirclePanel extends JPanel implements ActionListener {
private JFrame f;
private JButton run1, run2, reset, quit;
private JPanel btnPanel;
private int NUM;
private Color c;
public CirclePanel(){
color1 = Color.red;
color2 = Color.black;
NUM = 5;
// Setup JFrame and stuff as you were doing.
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.translate(470, 400);
for(int i = 0; i < NUM; i++){
g.setColor(color1);
g.fillOval(150, 0, 100, 100);
g.setColor(color2);
g.fillOval(90, 0, 30, 30);
g.rotate(2*Math.PI/ NUM);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == run1) {
System.out.println("Entered Action Handler");
color1 = Color.green;
repaint();
}
}
// GETTERS and SETTERS if needed
}