制作绘画程序,以前的位置颜色变化

时间:2014-02-24 01:58:33

标签: java swing graphics jframe mouse

我正在制作一个小的绘画程序,左边基本上有按钮,表示颜色,无论你点击和拖动,它都会使用图形绘制一个圆圈。我知道,根本没有效率,我可以使用笔画和东西,但我还在学习,但还没有达到目的,所以我用我所知道的测试它。一切似乎都在起作用,只有一个小问题。我可以单击,拖动,然后绘制一条线。但是当我改变颜色并绘制其他东西时,绘制的第一个圆是前一个颜色。我尝试了很多东西,但似乎无法修复它。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;


public class painting extends JFrame{

ArrayList<Integer> mouseLocXList = new ArrayList<Integer>();
ArrayList<Integer> mouseLocYList = new ArrayList<Integer>();
ArrayList<Color> colors = new ArrayList<Color>();
Color colorChosen = Color.black;

String[] colorsSideBarButtonString = {"Red", "Blue", "Green", "Orange", "Pink"};
Color[] colorsSideBar = {Color.red, Color.blue, Color.green, Color.orange ,  
    Color.pink};                          
JButton[] buttons = new JButton[colorsSideBarButtonString.length];


public painting(){
    setSize(1200,700);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setBackground(Color.WHITE);
    setLayout(null);
    setFocusable(true);

    addMouseMotionListener(new handler());

    colors.add(Color.black);

    for(int x = 0; x < colorsSideBarButtonString.length; x++){
        buttons[x] = new JButton(colorsSideBarButtonString[x]);
        buttons[x].setBounds(2,(x*50)+30,70,46);
        add(buttons[x]);
        buttons[x].addActionListener(new buttonListener());
    }

    setVisible(true);
}

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

public void paint(Graphics g){
    super.paint(g);

    g.setColor(Color.black);
    g.drawLine(72, 0, 72, 900);
    g.drawLine(1150, 0, 1150, 900);
    g.drawString("Colors", 17, 45);

    for(int i = 0; i < mouseLocXList.size(); i++){
        g.setColor(colors.get(i));
        g.fillOval(mouseLocXList.get(i),mouseLocYList.get(i),30,30);
    }

}

public class handler implements MouseMotionListener{

    public void mouseDragged(MouseEvent e) {
        mouseLocXList.add(e.getX());
        mouseLocYList.add(e.getY());
        colors.add(colorChosen);
        repaint();
    }
    public void mouseMoved(MouseEvent e) {          
    }

}

public class buttonListener implements ActionListener{

    public void actionPerformed(ActionEvent e) {
        for(int c = 0; c < buttons.length; c++)
            if(e.getSource() == buttons[c]){
                colorChosen = colorsSideBar[c];
        }
    }

}


}

对不起,这些节目有点长,我看不到哪里可以缩短它,一切似乎都是必要的。基本上每次单击并拖动鼠标时,其位置都存储在一个数组中,然后在图形中以for循环绘制。单击颜色,并将其添加到其自己的数组中,并在拖动时对鼠标位置进行每次更新,将当前颜色添加到colors数组中,以便在for循环中可以重新绘制颜色。我认为解决问题的最佳方法是运行它。

再一次,我知道这可能是你见过的最糟糕的书面程序之一。我理解,但我只是测试并试图看看我能做到这一点有多先进。

1 个答案:

答案 0 :(得分:2)

绘画是破坏性的,也就是说,每次调用paint时,它都会清除/删除之前绘制的内容。

这非常重要,因为Graphics上下文由绘制周期中绘制的所有组件共享,这意味着,当它到达您时,它可能已经在其上绘制了一些东西。

你需要做两件事。

首先,您需要创建一些可绘制的内容,即某种提供简单paintdraw方法的对象,您可以将Graphics上下文传递给它。这个对象应该知道它的绘画和颜色是什么

其次,您需要将这些“可绘制”对象中的每一个添加到创建它们的List中。这将允许您遍历List并在需要时重新绘制它们。

你应该避免覆盖paint这样的顶级容器JFrame,除了它们不是双缓冲并且在更新时会产生闪烁的事实,你最终可能会在边界下绘画框架的装饰(0x0实际上是窗口/框架的左上角,而不是框架标题栏下的可视区域)。

相反,请使用JPanel并覆盖它的paintComponent方法

请查看Performing Custom PaintingPainting in AWT and Swing了解详情

<强>更新...

您的颜色列表与您的鼠标点不同步,因为您确实...

colors.add(Color.black);

在构造函数中。这意味着第一个圆圈将以黑色绘制,而下一个圆圈将以所选颜色绘制。当您更改颜色时,它仍然不同步