Java GUI实现的问题

时间:2011-02-09 21:13:19

标签: java user-interface

我目前正在尝试运行的代码存在问题 - 我正在尝试制作3个按钮,将它们放在GUI上,然后将第一个按钮的颜色更改为橙​​色,并将该颜色旁边的按钮设置为变成白色和绿色。此后的每次点击都会导致颜色向右移动一个按钮。到目前为止,我的代码如下所示,它正在跳过某些地方的颜色,并且根本不像我预期的那样表现。有人可以提供一些帮助/指导吗?

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class ButtonJava extends JButton implements ActionListener  {
  private int currentColor=-1;
  private int clicks=0;
  private static final Color[] COLORS = {
    Color.ORANGE,
    Color.WHITE,
    Color.GREEN };
  private static ButtonJava[] buttons;

  public ButtonJava( ){
    setBackground( Color.YELLOW );
    setText( "Pick ME" );
    this.addActionListener( this );
  }

  public static void main(String[] args) {
    JFrame frame = new JFrame ("JFrame");
    JPanel panel = new JPanel( );
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
    buttons = new ButtonJava[3];
    for(int i = 0;i<buttons.length ; i++){
      buttons[i] = new ButtonJava(); 
      panel.add(buttons[i]);
    }
    frame.getContentPane( ).add( panel );
    frame.setSize( 500, 500);
    frame.setVisible( true );
  }

  private void updateButton() {
     clicks++;
    changeColors();
//    setText( );
  }

private void changeColors( ) {
  for (int i=buttons.length-1;i>=0;i--){
    buttons[i].currentColor = nextColor(currentColor);
    buttons[i].setBackground(COLORS[buttons[i].currentColor]);
    buttons[i].setText(("# of clicks = " + buttons[i].getClicks() ) );
  }
}

private Integer getClicks() {
 return clicks;
}

private int nextColor( int curCol ) {
  final int colLen = COLORS.length;
  curCol--;
  curCol = (colLen + curCol % colLen) % colLen;
  return curCol;
}

private void firstClick( ActionEvent event ) {
  int curCol = 0;
  for (int i=buttons.length-1;i>=0;i--){
    if ( buttons[i] == event.getSource() ) {
      buttons[i].currentColor = curCol;
      curCol++;
      currentColor++;
    }
  }}

  @Override
  public void actionPerformed( ActionEvent event ) {
    if ( -1 == currentColor ) {
      firstClick( event );
    }
    updateButton( );   
  }


}

非常感谢您的帮助:)

3 个答案:

答案 0 :(得分:3)

您发布的代码存在一些问题,但它们通常归结为清楚什么是类的成员(静态)以及实例的成员。

对于初学者,buttons数组仅存在于main方法中,changeColors()无法访问。同样,由于changeColors()是一个实例方法,因此需要在数组中的按钮上直接调用setBackground()。如上所述,您将为一个按钮设置3次颜色。

此外,changeColors()中的逻辑未正确旋转currentColor索引。您需要增加计数器并确保包装颜色数组的长度。如果阵列大小相同,则需要确保有额外的添加以使颜色循环。

private static void changeColors( ) {
  for (int i=0;i<buttons.length;i++){
    buttons[i].setBackground(COLORS[currentColor]);
    currentColor = nextColor(currentColor);
  }
  if (buttons.length == COLORS.length) {
    currentColor = nextColor(currentColor);
  }
}

private static int nextColor(int currentColor) {
  return (currentColor+1)% COLORS.length;
}

修改新代码:

我不确定你为什么重新写nextColor(),就像我发布的那样。但总的来说,我觉得你遇到了问题,因为你的代码没有很好地分配你想要实现的任务。您有与特定按钮实例相关的代码以及与控制混合在一起的所有按钮相关的代码。

通过以下实现,单击按钮的次数问题在按钮类中显然是自包含的。然后按下每个按钮也会调用拥有面板中的一个方法。此方法知道有多少按钮和第一个按钮的颜色。每个后续按钮将包含列表中的下一个颜色,必要时包装。

public class RotateButtons extends JPanel {
  private static final Color[] COLORS = { Color.ORANGE, Color.WHITE, Color.GREEN };
  private static final int BUTTON_COUNT = 3;
  private JButton[] _buttons;
  private int _currentColor = 0;

  public static void main(String[] args)
  {
    JFrame frame = new JFrame("JFrame");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new RotateButtons());
    frame.setSize(500, 500);
    frame.setVisible(true);
  }

  public RotateButtons()
  {
    _buttons = new JButton[BUTTON_COUNT];
    for (int i = 0; i < _buttons.length; i++) {
      _buttons[i] = new CountButton();
      add(_buttons[i]);
    }
  }

  private void rotateButtons()
  {
    for (JButton button : _buttons) {
      button.setBackground(COLORS[_currentColor]);
      _currentColor = nextColor(_currentColor);
    }
    if (_buttons.length == COLORS.length) {
      _currentColor = nextColor(_currentColor);
    }
  }

  private int nextColor(int currentColor)
  {
    return (currentColor + 1) % COLORS.length;
  }

  private class CountButton extends JButton {
    private int _count = 0;

    public CountButton()
    {
      setBackground(Color.YELLOW);
      setText("Pick ME");
      addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0)
        {
          _count++;
          setText("# of clicks = " + _count);
          rotateButtons();
        }
      });
    }
  }
}

第二次编辑:

仅显示第一次点击时将_currentColor转移所需金额的更改。

public class RotateButtons extends JPanel {
  ...
  private boolean _firstClick = true;
  ...
  private void rotateButtons(CountButton source)
  {
    if (_firstClick) {
      _firstClick = false;
      boolean foundSource = false;
      for (int i = 0; i < _buttons.length; i++) {
        if (foundSource) {
          _currentColor = nextColor(_currentColor);
        } else {
          foundSource = _buttons[i] == source;
        }
      }
    }
    ...
  }

  private class CountButton extends JButton {
    ...

    public CountButton()
    {
      ...
      addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0)
        {
          ...
          rotateButtons(CountButton.this);
        }
      });
    }
  }

答案 1 :(得分:1)

我注意到的一件事是您使用currentColor分配颜色,但currentColor初始化为 0 且唯一操纵是currentColor %= 2,不会改变它。

答案 2 :(得分:1)

如果我理解您想要实现的目标,我想将currentColor %= 2更改为++currentColor,将setBackground(COLORS[currentColor]);更改为buttons[i].setBackground(COLORS[(i + currentColor) % 3]);。这样,每次点击一个按钮时,你的颜色应该在你的按钮周围循环。

编辑:可能还需要在changeColors内调用main来初始化您的按钮颜色。并且,正如@unholysampler所指出的,您的数组buttonsmain的本地数组,并且应该(例如)重构为静态成员变量,并且changeColors成为静态方法。