Как да задам цвета на JButtons в масив в java?

Да предположим, че има масив от бутони с имена:
private JButton buttons[] = new JButton[9];
Как мога да задам цвета на всички бутони в този масив на син?

Това е целият ми код: Това е игра на Tic Tac Toe с използване на бутони.

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

public class TicTacToe implements ActionListener {
private JButton buttons[] = new JButton[9];
private JFrame window = new JFrame("Tic Tac Toe");
private boolean win = false;
private int count = 0;
private int Xwins = 0, Owins = 0;
private String letter = "";
private int[][] winCombinations = new int[][] {
        {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, //horizontal wins
        {0, 3, 6}, {1, 4, 7}, {2, 5, 8}, //vertical wins
        {0, 4, 8}, {2, 4, 6}                     //diagonal wins
};
String name1 = JOptionPane.showInputDialog("Please enter first player's name");
String name2 = JOptionPane.showInputDialog("Please enter second player's name");

public TicTacToe(){
    JOptionPane.showMessageDialog(null,"Remember Player 1 is X and Player 2 is O.");
    window.setSize(300,300);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setLayout(new GridLayout(3,3));
    window.setVisible(true);


      for(int i=0; i<=8; i++){
          buttons[i] = new JButton();
          window.add(buttons[i]);
          buttons[i].addActionListener(this);
          buttons[i].setBackground(Color.MAGENTA);
  }
      for (JButton button: buttons) {
           button.setBackground(Color.BLUE);
        }

}

public void actionPerformed(ActionEvent event) {
        count++;
        if(count % 2 == 0){
            letter = "O";

        }else{
            letter = "X";
        }
         JButton pressedButton = (JButton)event.getSource(); 
         pressedButton.setText(letter);
         pressedButton.setEnabled(false);
         pressedButton.setBackground(Color.WHITE);


    //Determine who won
    for(int i=0; i<=7; i++){
        if( buttons[winCombinations[i][0]].getText().equals(buttons[winCombinations[i][1]].getText()) && 
                buttons[winCombinations[i][1]].getText().equals(buttons[winCombinations[i][2]].getText()) && 
                buttons[winCombinations[i][0]].getText() != ""){
                win = true;
            }
        }
        if(win == true){
            if(letter == "X"){
                JOptionPane.showMessageDialog(null, name1 + " wins the game!");
            }else{
                JOptionPane.showMessageDialog(null, name2 + " wins the game!");
            }
            playAgain();
        }else if(count == 9 && win == false){
            JOptionPane.showMessageDialog(null, "The game is tied!");
            playAgain();
        }
    } 

public void playAgain(){
    if(letter == "X"){
        Xwins++;
    }else{
        Owins++;
    }
    JOptionPane.showMessageDialog(null, name1 + " has won this many times: " + Xwins);
    JOptionPane.showMessageDialog(null, name2 + " has won this many times: " + Owins);
    int response = JOptionPane.showConfirmDialog(null, "Would you like to play again?", "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

    if(response == JOptionPane.YES_OPTION){
        reset();
    }else{
        System.exit(0);
    }
}

  public void reset() {
      for(int i = 0; i<=8; i++) {
              buttons[i].setText("");
              buttons[i].setEnabled(true); 
      }
      win = false;
      count = 0;
  }  

public static void main(String[] args){
    TicTacToe play = new TicTacToe();
   }
}

person huntingGirl    schedule 02.01.2013    source източник
comment
За точно тази употреба бих поставил цветни икони в бутоните, отколкото да знам как да рисувам X или O или никакъв символ. :)   -  person Andrew Thompson    schedule 02.01.2013


Отговори (3)


Трябва да нулирате цвета на бутона до син в цикъла for на метода reset:

buttons[i].setBackground(Color.blue);

Ето как изглежда полученото приложение на моята машина и машина с Mac OSX. Бутоните стават бели, след като бъдат избрани:

въведете описание на изображението туквъведете описание на изображението тук

Ако използвате Mac OSX, може също да имате проблеми с външния вид на системата. Можете да промените това във вашия main метод по този начин:

public static void main(String[] args){
   try {
      // Set cross-platform Java L&F (also called "Metal")
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
      // alternatively, the following should load the default L&F for your system
      //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
   } catch (Exception e) {}

   TicTacToe play = new TicTacToe();
}
person 808sound    schedule 02.01.2013
comment
Хм, това е странно. Значи, когато прозорецът се появи за първи път, всички горни бутони са сиви? Променят ли цвета си, когато щракнете върху тях? - person 808sound; 02.01.2013
comment
Как изграждате проекта? Тоест, използвате ли Eclipse или компилирате от командния ред? Освен това каква версия на Java използвате? - person 808sound; 02.01.2013
comment
Използвам Eclipse. Как да разбера коя версия на Java използвам? - person huntingGirl; 02.01.2013
comment
В Eclipse можете да отидете в менюто Window и след това Preferences-›Java-›Installed JREs. Това трябва да покаже списък с JRE, като този по подразбиране е маркиран. - person 808sound; 02.01.2013
comment
Ъммм. Мисля, че е Java SE 7. - person huntingGirl; 02.01.2013
comment
Може да е нещо странно, като специфично за ОС ограничение. Хората са имали проблеми с цвета на бутоните на Mac OSX. Може да се наложи да промените външния вид и усещането, така че ще се опитам да актуализирам отговора си с това. - person 808sound; 02.01.2013
comment
@huntingGirl можеш ли да опиташ да промениш външния вид и усещането, както е показано по-горе, и да видиш дали това помага? - person 808sound; 02.01.2013
comment
Благодаря! Това проработи! Но можете ли да ми обясните какво точно е Look and Feel и какво UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); това ще реши ли проблема ми? - person huntingGirl; 02.01.2013
comment
Страхотно, радвам се, че работи! Look & Feel е функционалност на Java Swing, която позволява внедряване на различни изгледи/поведения за компонентите (бутони, менюта, текстови полета и т.н.). Например Metal L&F (който е междуплатформен и очевидно стандартен за Linux) има квадратен стил на бутоните с цветове на фона, докато L&F по подразбиране за Mac има кръгли бутони със сив фон. Повече информация можете да намерите на docs.oracle.com/javase/tutorial/ uiswing/lookandfeel/plaf.html - person 808sound; 02.01.2013
comment
Какви други видове външен вид и усещане мога да използвам? Просто съм любопитен.. Бихте ли ми показали как бих го кодирал? - person huntingGirl; 02.01.2013

Това всъщност е страничен ефект на JButton.

Фонът и съдържанието са две различни понятия. Въпреки че можете да промените цвета на фона, той може да не промени областта на съдържанието на бутона. Всъщност може да действа различно при различен вид и усещане.

Вместо това използвайте JLabel, много по-лесно е да се контролира...

въведете описание на изображението тук

public class TicTacToe implements ActionListener {

    private JLabel labels[] = new JLabel[9];
    private JFrame window = new JFrame("Tic Tac Toe");
    private boolean win = false;
    private int count = 0;
    private int Xwins = 0, Owins = 0;
    private String letter = "";
    private int[][] winCombinations = new int[][]{
        {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, //horizontal wins
        {0, 3, 6}, {1, 4, 7}, {2, 5, 8}, //vertical wins
        {0, 4, 8}, {2, 4, 6} //diagonal wins
    };
    String name1 = JOptionPane.showInputDialog("Please enter first player's name");
    String name2 = JOptionPane.showInputDialog("Please enter second player's name");

    public TicTacToe() {
        JOptionPane.showMessageDialog(null, "Remember Player 1 is X and Player 2 is O.");
        window.setSize(300, 300);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLayout(new GridLayout(3, 3));
        window.setVisible(true);

        MouseHandler handler = new MouseHandler();

        for (int i = 0; i <= 8; i++) {
            labels[i] = new JLabel();
            labels[i].setOpaque(true);
            labels[i].setBorder(new LineBorder(Color.LIGHT_GRAY));
            labels[i].setHorizontalAlignment(JLabel.CENTER);
            window.add(labels[i]);
            labels[i].addMouseListener(handler);
            labels[i].setBackground(Color.MAGENTA);
        }
//        for (JButton button : buttons) {
//            button.setBackground(Color.BLUE);
//        }

    }

    public void actionPerformed(ActionEvent event) {
    }

    public void playAgain() {
        if (letter == "X") {
            Xwins++;
        } else {
            Owins++;
        }
        JOptionPane.showMessageDialog(null, name1 + " has won this many times: " + Xwins);
        JOptionPane.showMessageDialog(null, name2 + " has won this many times: " + Owins);
        int response = JOptionPane.showConfirmDialog(null, "Would you like to play again?", "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

        if (response == JOptionPane.YES_OPTION) {
            reset();
        } else {
            System.exit(0);
        }
    }

    public void reset() {
        for (int i = 0; i <= 8; i++) {
            labels[i].setText("");
            labels[i].setEnabled(true);
        }
        win = false;
        count = 0;
    }

    public class MouseHandler extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent event) {
            count++;
            if (count % 2 == 0) {
                letter = "O";

            } else {
                letter = "X";
            }
            JLabel pressedLabel = (JLabel) event.getSource();
            pressedLabel.setText(letter);
            pressedLabel.setEnabled(false);
            pressedLabel.setBackground(Color.WHITE);


            //Determine who won
            for (int i = 0; i <= 7; i++) {
                if (labels[winCombinations[i][0]].getText().equals(labels[winCombinations[i][1]].getText())
                                && labels[winCombinations[i][1]].getText().equals(labels[winCombinations[i][2]].getText())
                                && labels[winCombinations[i][0]].getText() != "") {
                    win = true;
                }
            }
            if (win == true) {
                if (letter == "X") {
                    JOptionPane.showMessageDialog(null, name1 + " wins the game!");
                } else {
                    JOptionPane.showMessageDialog(null, name2 + " wins the game!");
                }
                playAgain();
            } else if (count == 9 && win == false) {
                JOptionPane.showMessageDialog(null, "The game is tied!");
                playAgain();
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                TicTacToe play = new TicTacToe();
            }
        });
    }
}

Единственият друг избор, който може да имате, е да създадете имплементация на бутона, който е в състояние само да рисува цвета на фона, това ще изисква да разширите от AbstractButton, но честно казано, това е много работа...

person MadProgrammer    schedule 02.01.2013

@808sound е на прав път - някои от стандартния външен вид и усещане (напр. Windows) правят странно/трудно/трудно променянето на цвета на бутоните.

В началото на вашата програма опитайте да зададете LAF чрез

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 

Повече подробности тук

person user949300    schedule 02.01.2013