我试图在Action处理程序中更改我的Red Cirlces的颜色,然后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;
我的课在这里:
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按钮时,它确实进入了动作处理程序并执行了repaint方法,但是没有任何变化。
@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();
}
}
答案 0 :(得分:2)
Graphics对象不是长期存在的,不稳定的,并且您不应该以这种方式使用它们。代替设置g2或任何其他图形 field ,创建一个名为Color circleColor = ...;
的Color域,然后更改 this 。在protected void paintComponent(Graphics g)
方法中,调用g.setColor(circleColor);
,这应该可以工作。
删除这些字段,因为它们很危险:
// static Graphics2D g2;
// static Graphics2D g3;
另外,您的代码显示了对static修饰符的过度使用,我敢建议您,除了常量之外,所有字段都不应该是静态的:
static final int NUM
答案 1 :(得分:1)
repaint()方法最终将调用面板的paintComponent()方法。 Swing将传递要在绘画中使用的Graphics对象。
在绘画代码中,您始终将颜色硬编码为红色。不要这样做。
相反,您需要在面板类中定义一个变量。可以说“ 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教程中的部分,以获取更多信息以及有关如何构建代码的更好示例。例如,您不应该使用静态变量。
答案 2 :(得分:-2)
正在发生的事情:
g2
颜色。repaint();
,这样就叫paintComponent(Graphics g)
。paintComponent(Graphics g)
方法中,您将g2
的颜色设置为c
,因此,您将覆盖在操作侦听器中所做的更改。这就是为什么圆圈最后没有变色的原因。
您应该在构造函数中而不是在c = Color.RED;
循环中设置for
,然后才可以在动作侦听器c
中更改c = Color.GREEN;
的值。
此外,您同时在c = Color.RED;
循环中和之前都设置了for
。
编辑:
根据{{1}}的建议,您的代码结构也很糟糕。
@camickr
和g2
,因为您可以绘制多个形状
使用相同的g3
对象。Graphics g
方法之外调用g
,因为您可以像上面所说的那样简单地更改paintComponent
变量。Color c
变量。只需将它们设置为static
,如果您需要从课程之外访问它们,则应创建一些private
和getters
。 Here you'll find more on static variables and some examples.
Here you'll find more about getters, setters and encapsulation.
如何更改代码的示例:
setters