所以我的这个程序的目标是使用GUI制作一个基本的Etch-A-Sketch。除了能够使用鼠标绘图之外,我还需要添加一个按钮来更改任何四种颜色之间的线条颜色。因为我刚刚第一次学习这个,所以在遇到问题之前,我已经改变了线条颜色:
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();”线已经分开了。我不确切地知道他们的意思,但是......这与我的问题有关吗?
答案 0 :(得分:0)
尝试将静态全局变量放在文件的顶部;
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();
答案 1 :(得分:0)
您可以做的是通过构造函数传递对图形对象的引用:
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时,而不是这样做......
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);
}
答案 2 :(得分:0)
良好的OOP设计是将保持不变的内容与您预期扩展的内容分开。你是etcha sketch的铅笔会扩大很多(将添加不同的颜色,不同的厚度,生产盒子而不是涂鸦,也许是橡皮擦)。你应该创建一个Pencil类。
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();
}
}
现在,您正在绘制缓冲图像。然后,您将该缓冲的图像绘制到contentPane上。这消除了我添加新铅笔类时出现的闪烁行为。这种方法称为“缓冲”。
一旦掌握了所有这些,您甚至可以练习一种名为策略模式的设计模式。这将允许您更改铅笔行为(而不是画线,可能画圆圈或其他东西)。这个想法是g.drawLine代码不会在你的铅笔类中进行硬编码。
答案 3 :(得分:-1)
请勿使用getGraphics()
进行绘画。
通过使用自定义绘画代码覆盖面板的paintComponent(...)
方法来完成绘画。
查看Custom Painting Approaches了解自定义绘画的几种不同方法的工作示例。这些示例向您展示了如何绘制不同颜色的矩形。