Вызов нелокальной переменной в ActionPerformed - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть случайным образом нарисованный круг 3 разными цветами (СИНИЙ, КРАСНЫЙ и ЗЕЛЕНЫЙ) и 3 кнопками с одинаковыми цветами (СИНИЙ, КРАСНЫЙ и ЗЕЛЕНЫЙ), и если круг КРАСНЫЙ и я нажимаю КРАСНУЮ кнопку, мне нужно показатьвверх в ярлыке вы выиграете, если вы выберете неправильный цвет вы теряете.Это очень просто, но я не могу вызвать в ActionPerformed переменную (то есть цвет, соответствующий цвету кнопки) из paintComponent.Прошу прощения за мой язык тоже.

Вот код с 2 классами:

PaintPanel.class

public class PaintPanel extends JPanel implements ActionListener {

int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
 JLabel label = new JLabel("Choose the right Color");
 JPanel subPanel = new JPanel();
private Color[] colors;

public PaintPanel() {

    setLayout(new BorderLayout());
    setPreferredSize(new Dimension(440, 440));
    add(label, BorderLayout.NORTH);
    b1.addActionListener(this);
    b2.addActionListener(this);
    b3.addActionListener(this);
    subPanel.add(b1);
    b1.setForeground(Color.BLUE);
    subPanel.add(b2);
    b2.setForeground(Color.RED);
    subPanel.add(b3);
    b3.setForeground(Color.GREEN);
    add(subPanel, BorderLayout.SOUTH);

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Color[] colors = new Color[3];

    colors[0] = Color.BLUE;
    colors[1] = Color.RED;
    colors[2] = Color.GREEN;

    Color c1 = colors[randInt(colors.length)];


    g.setColor(c1);
    /* this.colors.equals(c1); !!!! HERE I TRIED !!!*/
    g.fillOval(x, y, 30, 30);

}

private int randInt(int length) {
    // TODO Auto-generated method stub
    Random rand = new Random();
    int randomColor = rand.nextInt(length);
    return randomColor;
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
    }else {
        label.setText("You LOSE");
    } 
    if (e.getSource() == b2) {

    }
    if (e.getSource() == b3) {

    }
}
}

Еще один - DrawCircle.class -

public class DrawCircle extends JFrame {

private JPanel painted;

public DrawCircle() {
    painted = new PaintPanel();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLayout(new FlowLayout());
    setBounds(0, 0, 800, 540);
    add(painted);
    setVisible(true);
}

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

}

}

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Ваш массив цветов не должен создаваться в методе paintComponent ().Он должен быть объявлен как переменная экземпляра PaintPanel и должен быть создан в конструкторе PaintPanel.

Это возможно (вам не нужен отдельный класс; я добавил основной в PaintPanel):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class PaintPanel extends JPanel implements ActionListener {

   int             x        = 200, y = 250;
   private JButton b1       = new JButton("BLUE");
   private JButton b2       = new JButton("RED");
   private JButton b3       = new JButton("GREEN");
   JLabel          label    = new JLabel("Choose the right Color");
   JPanel          subPanel = new JPanel();
   private Color   circleColor;

   public PaintPanel() {

      setLayout(new BorderLayout());
      setPreferredSize(new Dimension(440, 440));
      add(label, BorderLayout.NORTH);
      b1.addActionListener(this);
      b2.addActionListener(this);
      b3.addActionListener(this);
      subPanel.add(b1);
      b1.setForeground(Color.BLUE);
      subPanel.add(b2);
      b2.setForeground(Color.RED);
      subPanel.add(b3);
      b3.setForeground(Color.GREEN);
      add(subPanel, BorderLayout.SOUTH);

      Random rand = new Random();
      int rc = rand.nextInt(3);
      switch (rc) {
      case 1:
         circleColor = Color.RED;
         break;
      case 2:
         circleColor = Color.GREEN;
         break;
      default:
         circleColor = Color.BLUE;
         break;
      }

   }

   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(circleColor);
      g.fillOval(x, y, 30, 30);

   }

   @Override
   public void actionPerformed(ActionEvent e) {
      JButton b = (JButton) e.getSource();
      if (b.getForeground().equals(circleColor)) {
         label.setText("You WIN");
      } else {
         label.setText("You LOSE");
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            // create the main frame
            JFrame frame = new JFrame();
            // create the component to display in the frame
            PaintPanel comp = new PaintPanel();
            frame.add(comp, BorderLayout.CENTER);

            frame.pack();
            frame.setVisible(true);
            frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
            frame.addWindowListener(new WindowAdapter() {
               @Override
               public void windowClosing(WindowEvent arg0) {
                  System.exit(0);
               }
            });
         }
      });

   }
}
0 голосов
/ 14 февраля 2019

Просто пара замечаний: вы не можете получить доступ к нестатическому методу из статического контекста.Рассмотрите возможность размещения вашего DrawCircle() метода в отдельном классе.Создайте экземпляр этого класса и вызовите DrawCircle() из этого экземпляра.

Что касается PaintPanel.class, обратите внимание, что paintComponent() вызывается очень часто, а не только при инициализации.Цвета, которые вы генерируете, должны быть сохранены в месте, доступном для actionPerformed().Подумайте о создании члена Color tmp в структуре вашего класса и укажите свой правильный ответ оттуда.Кроме того, вы, кажется, пропускаете звонок на UpdateUI().Этот код не идеален, но работает хорошо.Лично я бы нашел другой способ создания новых цветов, кроме переопределения paintComponent (), но если вам это нужно, этот пример может оказаться полезным.Комментарий ниже с улучшениями:

package com.company;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class PaintPanel extends JPanel implements ActionListener
{

    int x = 200, y = 250;
    private JButton b1 = new JButton("BLUE");
    private JButton b2 = new JButton("RED");
    private JButton b3 = new JButton("GREEN");
    JLabel label = new JLabel("Choose the right Color");
    JPanel subPanel = new JPanel();
    private Color[] colors;
    Color tmp = null;

    public PaintPanel()
    {

        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(440, 440));
        add(label, BorderLayout.NORTH);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        subPanel.add(b1);
        b1.setForeground(Color.BLUE);
        subPanel.add(b2);
        b2.setForeground(Color.RED);
        subPanel.add(b3);
        b3.setForeground(Color.GREEN);
        add(subPanel, BorderLayout.SOUTH);

    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        colors = new Color[3]; //Referencing Class member colors instead of local variable
        colors[0] = Color.BLUE;
        colors[1] = Color.RED;
        colors[2] = Color.GREEN;

        tmp = colors[randInt(colors.length)]; //Read into a class member instead of a local variable
        g.setColor(tmp);
        System.out.println("Paint Triggered. New Color is: " + tmp.toString()); //todo remove this debugging line
        g.fillOval(x, y, 30, 30);
    }

    private int randInt(int length)
    {
        // TODO Auto-generated method stub
        Random rand = new Random();
        int randomColor = rand.nextInt(length);
        return randomColor;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == b1) {
            if (Color.BLUE.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        } else if (e.getSource() == b2) {
            if (Color.RED.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        } else if (e.getSource() == b3) {
            if (Color.GREEN.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        }
        updateUI(); //<---------------IMPORTANT To Sync What you see with each button press.
    }
}
0 голосов
/ 14 февраля 2019

Я думаю, вы просто испортили свои скобки (и отступы).Используйте инструмент автоматического отступа или автоформатирования в IDE, он быстро найдет эти проблемы.

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
//  v Problem is this extra brace
    }else {
        label.setText("You LOSE");
    } 

Измените на

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
        else {
          label.setText("You LOSE");
        } 
    } else if( //...
...