Java:不确定如何在单独的类中修改图形对象



所以我这个程序的目标是使用GUI制作一个基本的蚀刻草图。除了能够用鼠标绘制之外,我还需要添加一个按钮来更改任意四种颜色之间的线条颜色。由于我只是第一次学习这一点,因此在遇到问题之前,我已经更改了线条颜色:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Etch_A_Sketch implements MouseListener, MouseMotionListener
{
    JFrame window;
    Container content;
    int mouseX,mouseY,oldX,oldY;
    JButton colorButton;
    ActionListener bPress = new MyListener();
    public Etch_A_Sketch()
    {
        JFrame window = new JFrame("Classic Etch a Sketch");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        content = window.getContentPane();
        window.setSize(640,480);
        content.setLayout( new FlowLayout() );
        content.addMouseListener(this);
        content.addMouseMotionListener(this);           
        colorButton = new JButton("Click to switch color!");
        colorButton.setSize(175,50);
        colorButton.setVisible(true);
        colorButton.addActionListener(bPress);
        content.add(colorButton);
        window.setVisible(true);
    }

    public void mouseClicked( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
    }
    public void mousePressed( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        //repaint();
    }
    public void mouseReleased( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        //repaint();
    }
    public void mouseExited( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        //repaint();
    }
    public void mouseEntered( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        //repaint();
    }
    public void mouseDragged( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        if (oldX ==0 )
        {
            oldX=mouseX;
            oldY=mouseY;
            return;
        }

        Graphics g = content.getGraphics(); // use g to draw onto the pane
        g.drawLine( oldX,oldY, mouseX, mouseY );
        oldX = mouseX;
        oldY = mouseY;
        // repaint();
    }
    public void mouseMoved( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        //repaint();
    }
    class MyListener implements ActionListener
    {
        final Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE};
        int index = 0;
        public void actionPerformed(ActionEvent e)
        {   
            g.setColor(colors[index]);
            index = (index + 1) % colors.length;
        }
    }

    public static void main( String[] args)
    {
        new Etch_A_Sketch();
    }
}

我的问题是这个 - 我意识到MyListener类中对"g"的引用超出了范围,因为它是mouseDragged方法的一部分。当我的 JButton 被按下时,我将如何更改它?我已经尝试将 g 的声明移到方法之外,但它不起作用。任何帮助将不胜感激!

另外,可能值得注意的是,我有一个基本文件来启动这个项目,并且"//repaint((;"行已经分开了。不过,我不知道它们到底是什么意思...它与我的问题有关吗?

尝试将静态全局变量放在文件的顶部;

static Graphics g = null;

然后在public void mouseDragged( MouseEvent me)

Etch_A_Sketch.g = content.getGraphics(); // use g to draw onto the pane

然后在class MyListener中引用它

有趣的是,为了安全起见,我建议使用界面。在主类中声明一个,让类实现它,然后在你想要content.getGraphics();的值时触发事件<</p>

div class="ans> 你可以

做的是通过构造函数传递对图形对象的引用:

class MyListener implements ActionListener
{
    private final Graphics graphics;
    private final Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE};
    private int index = 0;
    public MyListener(Graphics graphics)
    {
        this.graphics = graphics;
    }
    public void actionPerformed(ActionEvent e)
    {   
        this.graphics.setColor(colors[index]);
        index = (index + 1) % colors.length;
    }
}

现在,在创建操作侦听器时,而不是这样做...

ActionListener bPress = new MyListener();
public Etch_A_Sketch()
{
    JFrame window = new JFrame("Classic Etch a Sketch");
    // ...
    // ...
    colorButton.addActionListener(bPress);
    content.add(colorButton);
    window.setVisible(true);
}

你可以这样做:

public Etch_A_Sketch()
{
    JFrame window = new JFrame("Classic Etch a Sketch");
    // ...
    // ...
    Graphics graphics = content.getGraphics();
    colorButton.addActionListener(new MyListener(graphics));
    content.add(colorButton);
    window.setVisible(true);
}

好的OOP设计是关于区分保持不变的内容和您预期将要扩展的内容。 你是蚀刻素描的铅笔将扩大很多(将添加不同的颜色,不同的厚度,生产盒子而不是涂鸦,也许是橡皮擦(。 您应该创建一个铅笔类。

public class Pencil {
    private Graphics backGroundGraphics;
    final Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE};
    private int colorIndex;

public Pencil(BufferedImage backGround) {
    backGroundGraphics = backGround.getGraphics();
    backGroundGraphics.setColor(Color.BLACK);
}
    public void changeColor() {
        colorIndex++;
        backGroundGraphics.setColor(colors[colorIndex % 4]);
    } 
    public void drawLine(int oldX, int oldY, int mouseX, int mouseY) {
         backGroundGraphics.drawLine(oldX,oldY, mouseX, mouseY);
    }
}

然后在您的 GUI 类中添加所有这些:

class  Etch_A_Sketch implements MouseListener, MouseMotionListener {
    ...
   private Pencil pencil;
   BufferedImage bf;
   ...
   ...
        public Etch_A_Sketch()
        {
        bf = new BufferedImage(640, 480, BufferedImage.TYPE_INT_ARGB);
        pencil = new Pencil(bf);
            ....
            ....
}
                           ....
public void mouseDragged( MouseEvent me)
    {
        mouseX = me.getX();
        mouseY = me.getY();
        if (oldX ==0 )
        {
            oldX=mouseX;
            oldY=mouseY;
            return;
        }
        pencil.drawLine(oldX, oldY, mouseX, mouseY);
        Graphics g2 = content.getGraphics();
        g2.drawImage(bf, 0, 0, content);
        oldX = mouseX;
        oldY = mouseY;
    }

                 ....
class MyListener implements ActionListener
{
    final Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE};
    int index = 0;
    public void actionPerformed(ActionEvent e)
    {   
        pencil.changeColor();
    }
}
现在

,您现在正在绘制缓冲图像。 然后,您将缓冲的图像绘制到内容窗格上。 这消除了我添加新铅笔类时出现的闪烁行为。 此方法称为"缓冲"。

一旦你得到了所有这些,你甚至可以练习一种叫做策略模式的设计模式。 这将允许您更改铅笔行为(而不是画线,也许画圆圈或其他东西(。 这个想法是g.drawLine代码不会在你的铅笔课中硬编码。

不要用getGraphics()来画画。

绘制

是通过使用自定义绘制代码重写面板的paintComponent(...)方法来完成的。

查看自定义绘画方法,

了解进行自定义绘画的几种不同方法的工作示例。这些示例演示如何绘制不同颜色的矩形。

最新更新