首页 文章

初学者Graphics2D Java:repaint()

提问于
浏览
-1

我试图在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;

我的 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();
    }

}

3 回答

  • 2

    Graphics对象不是长寿命,不稳定,您不应该以这种方式使用它们 . 而不是设置g2或任何其他图形字段,创建一个颜色字段,比如称为 Color circleColor = ...; ,并更改它 . 在 protected void paintComponent(Graphics g) 方法中,调用 g.setColor(circleColor); ,这应该有效 .

    删除这些字段是危险的:

    // static Graphics2D g2;
    // static Graphics2D g3;
    

    此外,您的代码显示了静态修饰符的严重过度使用,我冒昧地建议您的所有字段都不应该是静态的,除了常量:

    static final int NUM
    
  • 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

    发生的事情是:

    • 您正在更改动作侦听器中的 g2 颜色 .

    • 然后你调用 repaint(); ,所以 paintComponent(Graphics g) 被调用 .

    • paintComponent(Graphics g) 方法中,您将 g2 颜色设置为 c ,因此您将覆盖在动作侦听器中所做的更改 .

    这就是为什么圈子最终没有改变颜色的原因 .

    您应该在构造函数中而不是在 for 循环中设置 c = Color.RED; ,然后您只需在动作侦听器 c = Color.GREEN; 中更改 c 的值 .

    你也在 for 循环中和之前设置了 c = Color.RED; ,这是无用的 .

    EDIT:
    正如 @camickr 所建议的那样,您的代码结构也很糟糕 .

    • 您不需要 g2g3 ,因为您可以使用相同的 Graphics g 对象绘制多个形状 .

    • 在你的情况下你甚至不需要在 paintComponent 方法之外调用 g ,因为你可以简单地改变 Color c 变量,如上所述 .

    • 您也不需要所有这些 static 变量 . 只要让它们 private ,如果你需要从课外访问它们,你应该创建一些 getterssetters .

    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
    }
    

相关问题