Change a JOptionPane's button text color

57 views Asked by At

I would like to change the button text color of one of the options of a JOptionPane dialog to be different from the default color in Java Swing. So far, I've found some answers on how to do this for the entire application, but no answers for how to do this for one specific button.

The way I'm displaying the dialog (documentation here):

JOptionPane.showOptionDialog(
    null, // parent
    "Body text", 
    "Title text", 
    JOptionPane.YES_NO_OPTION, 
    JOptionPane.WARNING_MESSAGE,
    null, // icon
    new String[]{"Continue", "Cancel"}, 
    "Cancel");

I would like the "Continue" button to have red text color instead, but want all other JOptionPane button text colors in my app to remain the same.

2

There are 2 answers

0
Jorn Rigter On BEST ANSWER

I figured it out - simply use HTML formatting to set the button text color:

JOptionPane.showOptionDialog(
    null, // parent
    "Body text", 
    "Title text", 
    JOptionPane.YES_NO_OPTION, 
    JOptionPane.WARNING_MESSAGE,
    null, // icon
    new String[]{"<html><font color=#ff0000>Continue</font></html>", "Cancel"}, 
    "Cancel");
4
MadProgrammer On

The JOptionPane is a vey flexible and curious class.

If you read the documentation for JOptionPane#showOptionDialog(Component, Object, String, int, int, Icon, Object[], Object) you will find that the parameter options states:

options - an array of objects indicating the possible choices the user can make; if the objects are components, they are rendered properly; non-String objects are rendered using their toString methods; if this parameter is null, the options are determined by the Look and Feel

(emphasis added by me)

This basically means you can pass your own configured JButtons via the options parameter and they will be "rendered properly".

Having said that, it will take some additional work to make work as "normal" (ie returning the index of the option that was selected).

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                showOptions();
            }
        });
    }

    protected JOptionPane getOptionPane(JComponent parent) {
        JOptionPane pane = null;
        if (!(parent instanceof JOptionPane)) {
            pane = getOptionPane((JComponent) parent.getParent());
        } else {
            pane = (JOptionPane) parent;
        }
        return pane;
    }

    public void showOptions() {
        final JButton okay = new JButton("Ok");
        okay.setForeground(Color.GREEN);
        okay.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane pane = getOptionPane((JComponent) e.getSource());
                pane.setValue(okay);
            }
        });
        final JButton cancel = new JButton("Cancel");
        cancel.setForeground(Color.RED);
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane pane = getOptionPane((JComponent) e.getSource());
                pane.setValue(cancel);
            }
        });

        int option = JOptionPane.showOptionDialog(
                null,
                "Happiness and Joy",
                "Get",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                new Object[]{okay, cancel},
                okay);
        System.out.println(option);
    }

}