Java 单击按钮时如何更改单个椭圆的颜色?

Java 单击按钮时如何更改单个椭圆的颜色?,java,swing,jbutton,mouselistener,ellipse,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

我希望能够单击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);

}
}

我有一门斯里特菲尔德的课

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

有三个核心问题

一个 为了使
面板\u 1
鼠标侦听器
更改
面板
中精灵的颜色,
鼠标侦听器
需要参考
面板

您可以在
initialize
方法中将
面板
声明为
final
,但我更喜欢将
面板
设置为
MainClient
私有
实例字段

两个 要更改颜色,
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
方法以接受
color
参数

public class RoundSprite {
    //...
    void DrawSprite(Graphics2D g2, Color color) {
并在
SpriteField
paintComponent
中,将颜色传递给sprite

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);
    }
现在,这会将场中的所有精灵绘制为相同的颜色,如果您想更改单个精灵的颜色,这将变得非常复杂

让我们暂时撇开选择精灵的问题

基本上,您需要将相同的原则从点Two应用到
RoundSprite

您需要提供一种方法来设置/获取所需的颜色。您需要将此值存储在
RoundSprite
类的实例字段中,并且在调用
DrawSprite
时,将该
Color
应用于
图形
上下文

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

public class SpriteField extends JPanel {

    private Color color = Color.BLACK;
    //...
    public void setColor(Color color) {
        this.color = color;
        repaint();
    }
旁注。。。 您可能希望有一个通读版本,这将使人们更容易阅读您的代码,您也更容易阅读其他代码


避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局管理器一起工作,丢弃这些布局管理器将导致无止境的问题,您将花费越来越多的时间来纠正这些问题


哦,你意识到已经有了一个
JButton
类,可能应该用它来代替
JPanel
MouseListener
…?

避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局管理器一起工作,丢弃它们将导致无止境的问题,您将花费越来越多的时间试图纠正这些问题并感谢您的帮助。这是我的第一篇文章,所以我试着尽我所能编写我的代码。我换成了Jbutton,一切都解决了。我确定我需要更改每个椭圆的颜色,因为稍后我将需要调整和旋转每个椭圆以及撤消每个椭圆。然后您需要定义一种方法,通过该方法可以选择单个精灵,可能通过
SpriteField
上的
MouseListener
来循环查看
mSprites
列表,并确定鼠标是否“击中”了任何精灵。。。