2

I want to write a text on a circle. The intersection area of the text and circle must be a different color.

At first I thought to use area class, but I couldn't figure out how to convert a text to an area.

I still have no idea how to convert a text to a shape or something.

Here is the example picture:

http://i.hizliresim.com/wOW2oQ.png

void paintComponent(Graphics g){
Ellipse2D myEllipse = new Ellipse2D.Double(20,20,100,100);

//i have no idea how to create a text as a shape.
//if i was able to create a text as a shape,i would name it "myText"

a1.add(new Area(myEllipse));
a2.add(new Area(myText)); 

g2.setColor(Color.red);
g2.fill(myEllipse);

g2.setColor(Color.CYAN);
g2.fill(myText);

a1.intersect(a2);
g2.setColor(Color.BLACK);
g2.fill(a1);

}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
Murat
  • 72
  • 10

2 Answers2

4

The painting engine can handle this by itself. Take a look at the XOR-Mode for Graphics:

http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#setXORMode(java.awt.Color)

In your example, you have to set the XOR color to White before writing the text:

Graphics2D g2 = (Graphics2D) g;

g2.setColor(Color.white);
g2.fillRect(0, 0, getWidth(), getHeight());

g2.setColor(Color.BLUE);
g2.fill(myEllipse);

g2.setColor(Color.red);
g2.setXORMode(Color.white); // Set XOR mode to white
g2.drawString(myText, 70, 70);

It can be quite tricky to find the correct XOR color. But with regards to this question, you have to bitwise XOR the foreground of the graphics, the XOR-Color, and the color you're painting onto.

For the circle area we get:

Foreground = FF 00 00 (red)
XOR-Color  = FF FF FF (white)
Background = 00 00 FF (blue)
----------------------
Result     = 00 FF 00 (green)

and outside:

Foreground = FF 00 00 (red)
XOR-Color  = FF FF FF (white)
Background = FF FF FF (white)
----------------------
Result     = FF 00 00 (red)

Update:

To find the XOR / Foreground pair, you can do the following:

You have to combine the background and resulting color by XOR. We see that for both cases (in ellipse and outside), we have

Ellispe: 00 00 FF ^ 00 FF 00 = 00 FF FF
Outside: FF FF FF ^ FF 00 00 = 00 FF FF

So we can choose any XOR / Foreground pair that results in 00 FF FF by XOR. In the example, I used white and red, but black and cyan would yield the same result.

Community
  • 1
  • 1
king_nak
  • 11,313
  • 33
  • 58
3

It's fairly straightforward to draw a circle and draw text. Thanks to king_nak for the Graphics2D method to change the color of the text in the circle.

Simple Painting

Here's the code.

package com.ggl.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimplePainting implements Runnable {

    @Override
    public void run() {
        JFrame frame = new JFrame("Simple Painting");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        PaintPanel paintPanel = new PaintPanel();
        frame.add(paintPanel);

        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimplePainting());
    }

    class PaintPanel extends JPanel {

        private static final long serialVersionUID = 
                -5950526117015270963L;

        private Ellipse2D myEllipse = 
                new Ellipse2D.Double(20, 20, 100, 100);

        private String myText = "Testing, one, two, three";

        public PaintPanel() {
            this.setPreferredSize(new Dimension(400, 200));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setXORMode(Color.WHITE);

            g2d.setColor(Color.RED);
            g2d.fill(myEllipse);

            g2d.setColor(Color.CYAN);
            g2d.drawString(myText, 70, 70);

        }
    }

}
Community
  • 1
  • 1
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111