单击jButton时如何更改单个椭圆的颜色?

时间:2014-08-04 00:16:30

标签: java swing jbutton mouselistener ellipse

我希望能够点击JButton并将我制作的下一个椭圆从其默认的蓝色更改为各自的颜色,红色或黑色。到目前为止,我能够改变我所有椭圆的颜色。

public class MainClient {

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainClient window = new MainClient();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public MainClient() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
    private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 800, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final SpriteField panel = new SpriteField();
    panel.setBounds(0, 110, 782, 331);
    panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            int tX = e.getX();
            int tY = e.getY();
            panel.CreateObjectAt(tX,tY);
        }
    });
    frame.getContentPane().setLayout(null);
    panel.setBackground(Color.LIGHT_GRAY);
    frame.getContentPane().add(panel);

    final JButton btnRed = new JButton("black");
    btnRed.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            panel.setColor(Color.BLACK);
        }
    });
    btnRed.setBounds(229, 500, 97, 25);
    frame.getContentPane().add(btnRed);

    JButton btnRed_1 = new JButton("red");
    btnRed_1.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            panel.setColor(Color.RED);
        }
    });
    btnRed_1.setBounds(342, 500, 97, 25);
    frame.getContentPane().add(btnRed_1);

}

}

我有一个SriteField类

public class SpriteField extends JPanel
{
    ArrayList<RoundSprite>mSprites = new ArrayList<RoundSprite>();

    private Color color = Color.BLUE;
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        AffineTransform tOldTransform = g2.getTransform();

        for(RoundSprite tOne:mSprites)
        {
            tOne.DrawSprite(g2, color);
        }
        g2.setTransform(tOldTransform);
    }
    public void CreateObjectAt(int tX, int tY)
    {
        //make sprite
        RoundSprite mLonely = new RoundSprite();
        //set position
        mLonely.SetPosition(tX, tY);
        //add to array
        mSprites.add(mLonely);
        repaint();
    }
    public void setColor(Color color)
    {
        this.color = color;
        repaint();
    }

}

我有一个RoundSprite类

public class RoundSprite 
{
int mX;
int mY;
private Color color;
void DrawSprite(Graphics2D g2, Color color)
{

    AffineTransform tOldTransform = g2.getTransform();
    g2.setColor(color);
    g2.translate(mX, mY); //got it out from the corner

    g2.draw(new Ellipse2D.Double(-15, -22, 30, 50));

    g2.setTransform(tOldTransform);

}
public void SetPosition(int tX, int tY) //g2.translate
{
    mX = tX;
    mY = tY;        
}

1 个答案:

答案 0 :(得分:1)

有三个核心问题......

为了panel_1 MouseListener更改panel内精灵的颜色,MouseListener需要引用panel

您可以在panel方法中将final声明为initialize,但我更愿意将panel private实例字段设为MainClient 1}}。

两个

为了改变颜色,SpriteField需要提供一种方式,利益相关方可以请求更改。

这需要SpriteField提供某种方法,感兴趣的各方可以在需要时调用,例如setColor方法......

public class SpriteField extends JPanel {

    private Color color = Color.BLACK;
    //...
    public void setColor(Color color) {
        this.color = color;
        repaint();
    }

然后panel_1 MouseListener现在可以引用SpriteField并调用可以产生更改的方法......

panel_1.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("Click");
        panel.setColor(Color.BLUE);
    }
});

你需要一些方法告诉精灵它应该是什么颜色......

这个取决于你想要实现的目标......

如果你想要绘制所有精灵相同的颜色,那么你需要一些方法告诉精灵他们应该使用哪种颜色,例如,你可以改变DrawSprite方法来接受{{1}参数...

Color

public class RoundSprite { //... void DrawSprite(Graphics2D g2, Color color) { SpriteField内,将颜色传递给精灵

paintComponent

现在,这将在场中绘制相同颜色的所有精灵,如果你想改变各个精灵的颜色,这会变得无比复杂......

让我们暂时不考虑选择精灵的问题......

基本上,您需要将相同的原则从两个应用到public class SpriteField extends JPanel { //... private Color color = Color.BLACK; @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; AffineTransform tOldTransform = g2.getTransform(); for (RoundSprite tOne : mSprites) { tOne.DrawSprite(g2, color); } g2.setTransform(tOldTransform); } 类。

您需要提供一种可以RoundSprite所需颜色的方法。您需要将此值存储在set/get类的实例字段中,并且在调用RoundSprite时,将DrawSprite应用于Color上下文。

这意味着Graphics不需要执行任何颜色管理,除了将更改请求从调用者传递到选定的sprite之外,因此它仍然需要SpriteField方法...

附注......

您可能希望阅读Code Conventions for the Java TM Programming Language,这样可以让人们更轻松地阅读您的代码并让您阅读其他代码

避免使用setColor布局,像素完美布局是现代ui设计中的一种幻觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来纠正

哦,你意识到已经有一个null类可能应该用JButton代替JPanel ....