1

I have a JCheckbox,this is in a JPanel, that is supposed to show an image in the JPanel, when you select it. The problem is this: as you can see in the screenshot, the text of the JCheckbox is difficult to read because of the image.

screenshot

I was thinking if there was some way to contrast the text to the image, so that the color of the text is the opposite of the image.

I know that there're other ways to fix it, like setting the JCheckbox outside the image, but I'd have to change design of my program and structure code.

For example, here's how I want it to look:

look.

This is all the code that the JCheckBox currently has, it is something simple:

        final JCheckBox INFO_IMG = new JCheckBox("Ver img");

        INFO_IMG.setFont(new Font("Dialog", 0, 12));
        INFO_IMG.setBounds(-2, 2, 78, 13);
        INFO_IMG.setOpaque(false);
        INFO_IMG.setFocusable(false);
        INFO_IMG.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(final ItemEvent ie) {
                if (1 == ie.getStateChange()) {
                    INFO_IMG.setText("Ver info");
                    IMG.setVisible(true);
/*                  INFO_IMG.setForegound(ROBOT.getPixelColor(
                    (int)INFO_IMG.getLocationOnScreen.getX() + 12 
                    ,(int) INFO_IMG.getLocationOnScreen().getY() + 10)); 

                   This is another way that I had thought of,
                   although it does not work well,would also have to get 
                   the opposite color from the one return.
*/
              } else { 
                    INFO_IMG.setText("Ver img");
                    IMG.setVisible(false);
                }
            }
        });
        add(INFO_IMG);
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Have you tried the `UIManager` property [`"CheckBox.foreground"`](https://stackoverflow.com/search?q=%5Bswing%5D+%22CheckBox.foreground%22)? If this is not a duplicate, please [edit] your question to include a [mre] that shows your revised approach. – trashgod Nov 01 '21 at 17:21
  • Alternatively, XOR the text on the image and `setText("")`. – trashgod Nov 01 '21 at 17:27
  • Hello, I did not know that property, could you explain in more detail, please, and thank you. oh sorry now I add more info. – Ignacio Inzerilli Nov 01 '21 at 18:00
  • I certainly hadn't thought of that alternative, I'll use it as a last resort – Ignacio Inzerilli Nov 01 '21 at 18:01
  • Here are more examples using [`UIManager.put`](https://stackoverflow.com/search?tab=votes&q=%5bswing%5d%20UIManager.put). – trashgod Nov 01 '21 at 18:03
  • I'm confused. For a `JCheckBox`, you can set the foreground and background colors so they contrast. If you want something like the white/black image you posted, you'll have to create a BufferedImage and set the image to the `JCheckBox`. – Gilbert Le Blanc Nov 01 '21 at 18:31
  • What do not you understand? Sorry if it is not well explained, I will make some corrections, I think that doing what you say is somewhat complicated for what I want, anyway where can I see more information about that. No, not only black / white, it can any other color, it depends on the color of the image, the image can be chosen by the user. – Ignacio Inzerilli Nov 01 '21 at 18:49
  • I share @GilbertLeBlanc's doubts. I sense that you don't want the white/black image; I'm guessing that you want to ensure that the text is legible over _any_ background. With some adjustment, I'd recommend this [approach](https://stackoverflow.com/a/2658663/230513). I urge you to continue experimenting. In your revised [mre], access posted images via `URL`, as shown [here](http://stackoverflow.com/a/10862262/230513); use synthetic images as shown [here](http://stackoverflow.com/a/15982915/230513); or use `UIManager` icons, as shown [here](http://stackoverflow.com/a/12228640/230513). – trashgod Nov 01 '21 at 22:36
  • To enhance contrast, first paint a neutral background for the text; you can get its boundary like [this](https://stackoverflow.com/a/8282330/230513). – trashgod Nov 01 '21 at 22:46
  • trashgod, If I thought about it, if I can not otherwise, I will surely do it like this. Thanks for your answer. Now I will try what was recommended to me, then I will comment on how it worked for me.. – Ignacio Inzerilli Nov 11 '21 at 18:48

1 Answers1

0

Well, I have found this way to do it, but unfortunately it only works for black and white, can you think of other ways?


Public Color contrast(Image image) {
    BufferedImage buffered = toBufferedImage(image);
        
    int black = 0, white = 0;
        
    for (int x = 0; x < buffered.getWidth(); x++) {
        for (int y = 0; y < buffered.getHeight(); y++) {
            if(buffered.getRGB(x, y) == Color.BLACK.getRGB()) {
                black++;
            }else {
                white++;
            }
        }
    }
        
    System.out.println("Blanco: " + white + ", Negro: " + black);
    
    return (white > black) ? Color.BLACK : Color.WHITE;
}

private BufferedImage toBufferedImage(Image image) {
    int width = image.getWidth(null);
    int height = image.getHeight(null);
    int argb = BufferedImage.TYPE_BYTE_BINARY;
        
    BufferedImage buffered = new BufferedImage(width, height, argb);
        
    Graphics2D g2 = buffered.createGraphics();
    g2.drawImage(image, 0, 0, null);
    g2.dispose(); 
        
    // JOptionPane.showMessageDialog(null, new ImageIcon(buffered));

    return buffered;
}