Hubert Wajda
Hubert Wajda

Reputation: 1

Why can't I change the JButton (disabled) text color?

I started programming Java. This is my first window application. I did a simple tic-tac-toe game and I want the "o" button font color to be a different color. But it doesn't work. I can change the background color, but not the fonts, why?

package moje;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.print.PrinterJob;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JTextField;

public class Kolko_i_krzyzyk extends JFrame implements ActionListener {
    
    static JTextField tekst;
    static JLayeredPane ekran = new JLayeredPane();
    static JButton button = new JButton();
    static int licznik=0;

    
    public Kolko_i_krzyzyk () {
        super("Kółko i krzyżyk");
        ekran = new JLayeredPane();
        setVisible(true);
        setSize(800, 800);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        
        //Siatka podzielona 3 na 3
        setLayout(new GridLayout(3,3));
        
        //Tworzenie 9 przycisków
        for(int i = 1; i<=9; i++) {
        JButton button = new JButton();
        add(button);
        button.addActionListener(this);
        }
    }

    public static void main(String[] args) {
        JFrame okno = new Kolko_i_krzyzyk();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    JButton  button = (JButton) e.getSource();
    if(licznik%2==0 ) {
        button.setText("x");
        button.setFont(new Font ("Arial", Font.BOLD, 90));
    }
    else {
        button.setText("O");
        button.setForeground(Color.RED);
        button.setFont(new Font ("Arial", Font.BOLD, 90));
    }
    button.setEnabled(false);
    licznik++;
    }
}
    

Upvotes: 0

Views: 883

Answers (1)

maloomeister
maloomeister

Reputation: 2486

The issue here is the default behavior when disabling the JButton via setEnabled(false). This will grey out the button and ignore any color formatting you did to the text (foreground).

There are several workarounds to modify this behavior (as seen in this similar question).

Here is a short demonstration (without the final game logic of course) , which changes the UI of the JButton via setUI().

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.plaf.metal.MetalButtonUI;

public class Test {

    private int counter = 0;

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> new Test().buildGui());
    }

    private void buildGui() {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.add(panel);
        panel.setLayout(new GridLayout(3, 3));

        for (int i = 1; i <= 9; i++) {
            JButton button = new JButton() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(150, 150);
                }
            };
            button.setFont(new Font("Arial", Font.BOLD, 90));
            panel.add(button);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (counter % 2 == 0) {
                        button.setText("X");
                        button.setUI(new MetalButtonUI() {
                            // override the disabled text color for the button UI
                            protected Color getDisabledTextColor() {
                                return Color.BLUE;
                            }
                        });
                    } else {
                        button.setText("O");
                        button.setUI(new MetalButtonUI() {
                            protected Color getDisabledTextColor() {
                                return Color.RED;
                            }
                        });
                    }
                    button.setEnabled(false);
                    counter++;
                }
            });
        }
        frame.pack();
        frame.setVisible(true);
    }

}

Result:

Result

Another (simpler) way to do it would be to build some ImageIcons for "X" and "O", then set these on the buttons via setIcon()/setDisabledIcon(). This would save you the trouble from modifying the button UI.

Upvotes: 5

Related Questions