I draw texts with Graphics.drawString but I want to draw Strings with rectangle background.
Use Graphics.fillRect or Graphics2D.fill before drawing the text.
Here's an example:
import java.awt.*;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
public class FrameTestBase extends JFrame {
public static void main(String args[]) {
FrameTestBase t = new FrameTestBase();
t.add(new JComponent() {
public void paintComponent(Graphics g) {
String str = "hello world!";
Color textColor = Color.WHITE;
Color bgColor = Color.BLACK;
int x = 80;
int y = 50;
FontMetrics fm = g.getFontMetrics();
Rectangle2D rect = fm.getStringBounds(str, g);
g.setColor(bgColor);
g.fillRect(x,
y - fm.getAscent(),
(int) rect.getWidth(),
(int) rect.getHeight());
g.setColor(textColor);
g.drawString(str, x, y);
}
});
t.setDefaultCloseOperation(EXIT_ON_CLOSE);
t.setSize(400, 200);
t.setVisible(true);
}
}
Suggestion:
Use a JLabel
Set its opaque property to true via setOpaque(true);
Set its foreground color via setForeground(myForegroundColor);
Then set its background color via setBackground(myBackgroundColor);
Related
I have finished working on a path finding visualizer recently. I was wondering if it was possible to use the graphics package for the colors to start off as white and then fade to their respective color like cyan or black. Right now I have it where the color just appears instantly and would think it would look nicer if the colors were able to fade from one another. Here is the code I have so far and a picture of the output
Path finding Visualizer
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int x = 0; x < cells; x++) { //coloring each node
for (int y = 0; y < cells; y++) {
switch (map[x][y].getType()) {
case 0: //start node
g.setColor(Color.GREEN);
break;
case 1: //end node
g.setColor(Color.RED);
break;
case 2: //wall node
g.setColor(Color.BLACK);
break;
case 3: //empty node
g.setColor(Color.WHITE);
break;
case 4: //visited nodes
g.setColor(Color.CYAN);
break;
case 5: //path
g.setColor(Color.YELLOW);
break;
}
g.fillRect(x * CSIZE, y * CSIZE, CSIZE, CSIZE);
g.setColor(Color.BLACK); //grid color
g.drawRect(x * CSIZE, y * CSIZE, CSIZE, CSIZE);
}
}
}
Here is one way. It uses a timer to periodically decrement the red component in the rgb color scheme.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ColorFadingDemo extends JPanel implements ActionListener {
Color color = new Color(255,0,0);
final static int height = 500;
final static int width = 500;
final static String title = "default title";
JFrame frame = new JFrame(title);
public static void main(String[] args) {
SwingUtilities.invokeLater(
() -> new ColorFadingDemo().start());
}
public void start() {
Timer timer = new Timer(0, this);
timer.setDelay(20);
timer.start();
}
public void actionPerformed(ActionEvent ae) {
int rgb = color.getRGB();
rgb -= 0x10000;
color = new Color(rgb);
repaint();
}
public ColorFadingDemo() {
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
frame.add(this);
setPreferredSize(
new Dimension(width, height));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(color);
g2d.fillRect(100,100,300,300);
g2d.dispose();
}
}
Easy:
int transparency = 0; // Transparency value;
int R = 255, G = 0, B = 0; //Enter your RGB values
Color c; // The color that you can then use in your paint method
Thread t = new Thread() {
public void run() {
while (transparency < 255) {
int transparency = 0;
c = new Color(R,G,B,transparency); // By creeting a custom color you can define the R, G, B and transparency values
transparency++;
try {
int fadeTime = 1000; // How long the fading process should go
Thread.sleep(255/fadeTime);
} catch (Exception e) {}
}
}
};
t.start(); // The thread will continue to run in the background until the transparency reaches 255
I was reading Core Java and encountered this code snippet:
package draw;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class DrawTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new DrawFrame();
frame.setTitle("DrawTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class DrawFrame extends JFrame
{
public DrawFrame()
{
add(new DrawComponent());
pack();
}
}
class DrawComponent extends JComponent
{
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
public void paintCompent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// draw a rectangle
double leftX = 100;
double topY = 100;
double width = 200;
double height = 150;
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
g2.draw(rect);
// draw the enclosed ellipse
Ellipse2D ellipse = new Ellipse2D.Double();
ellipse.setFrame(rect);
g2.draw(ellipse);
// draw a diagonal line
g2.draw(new Line2D.Double(leftX, topY, leftX + width, topY + height));
// draw a circle with the same center
double centerX = rect.getCenterX();
double centerY = rect.getCenterY();
double radius = 150;
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX + radius, centerY + radius);
g2.draw(circle);
}
public Dimension getPreferredSize()
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
I tried this code on Eclipse, it did run but, instead of rectangles, ellipse, diagonal lines and circle, there appeared nothing in the frame. I double-checked the code against the book, there was no typo. What is wrong?
There's a spelling mistake...
public void paintCompent(Graphics g) {
should be
public void paintComponent(Graphics g) {
This is why you should use the #Override annotation, as it will give you a compile time error when you try to override a method that doesn't exist within the parent hierarcy.
You should also be calling super.paintComponent(g); before performing any custom painting
I am trying to create a button which looks as shown below and continuously fades in and fades out .It looks like :-
Now i have done till the looks with gradient paint but what should i do to make the button text appear.Inspite of calling 'super(s)' it doesn't appear as i have painted it with GradientPaint.What should i do make the text appear over paint.My code is shown below :-
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Fader extends JFrame{
Fader()
{
super("A fading button");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setSize(400,400);
add(new CustomButton("Submit"));
setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable(){public void run(){new Fader();}});
}
}
class CustomButton extends JButton
{
public CustomButton(String s) {
super(s);
// TODO Auto-generated constructor stub
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g.create();
GradientPaint gp=new GradientPaint(0, 0, Color.RED, 200, 100, Color.YELLOW);
g2.setPaint(gp);
g2.fillRect(0, 0, getWidth(), getHeight());
}
public Dimension getPreferredSize()
{
return new Dimension(200,100);
}
}
Secondly,an advice to implement the fade in and out effect is also requested.
You can use this option, that paints a transparent color gradient on a component:
#Override
public void paintComponent(Graphics g){
super.paintComponent( g );
Graphics2D g2=(Graphics2D)g.create();
int h = getHeight();
int w = getWidth();
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, .5f));
g2.setPaint(new GradientPaint(0, 0, Color.yellow, 0, h, Color.red));
g2.fillRect(0, 0, w, h);
g2.dispose();
}
Other pretty good example with fading in (as requested). I used RadialGradientPaint. You can play with AlphaComposite
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f));
where 4f represent transparent level 40%
#Override
public void paintComponent(Graphics g){
super.paintComponent( g );
Graphics2D g2=(Graphics2D)g.create();
int h = getHeight();
int w = getWidth();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
Point2D center = new Point2D.Float(100, 50);
float radius = 150;
float[] dist = {0.0f, 1.0f};
Color[] colors = {Color.yellow, Color.red};
RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors);
g2.setPaint(p);
g2.fillRect(0, 0, w, h);
g2.dispose();
}
Finally we can play with alpha dynamically. Her is the full code. I created simple thread that change me alpha from 0 to 9 and vise versa. Here we go:
public class Fader extends JFrame{
private static final long serialVersionUID = 1L;
static JButton button;
public static float mTransparent = .0f;
Fader(){
super("A fading button");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setSize(400,400);
JButton button = new CustomButton("Submit");
add(button);
setVisible(true);
Blink blink = new Blink(this);
blink.start();
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable(){public void run(){new Fader();}});
}
public static float getTransparentLevel() {
return mTransparent;
}
public void setTransparentLevel(float newVal) {
mTransparent = newVal;
if(button != null){
button.repaint();
}
repaint();
}
}
class Blink extends Thread{
Fader fader;
public Blink(Fader fader) {
this.fader = fader;
}
#Override
public void run(){
while(true){
if(Fader.getTransparentLevel() == 0.0f){
//increase to 1f
for(int i=1; i<10; i++){
fader.setTransparentLevel((float)i/10);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
else if(Fader.getTransparentLevel() == 0.9f){
//increase to 1f
for(int i=10; i>=0; i--){
fader.setTransparentLevel((float)i/10);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class CustomButton extends JButton {
private static final long serialVersionUID = 1L;
public CustomButton(String s) {
super(s);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent( g );
Graphics2D g2=(Graphics2D)g.create();
int h = getHeight();
int w = getWidth();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Fader.getTransparentLevel()));
Point2D center = new Point2D.Float(100, 50);
float radius = 150;
float[] dist = {0.0f, 1.0f};
Color[] colors = {Color.yellow, Color.red};
RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors);
g2.setPaint(p);
g2.fillRect(0, 0, w, h);
g2.dispose();
}
public Dimension getPreferredSize(){
return new Dimension(200,100);
}
}
It blinks with sleep 300 ms from .0 to .9 of transparent and back from .9 to .0:
-->
Once you override the paintComponent() method, you are on your own with drawing the button. So, you will have to draw the text yourself. Something like this will help:
g2.setColor(Color.GREEN);
g2.drawString(getText(), 0, 10);
The above code must be added after the fillRect method. However, you will have to use FontMetrics in order to position the text according to the text alignment preferences.
To fadeIn and fadeOut you will need to implement your own Animation Sequencer that runs in a different thread, that will constantly vary the alpha value with a TimerTask. Once the value of alpha reaches 0, it should be incremented back to 100%.
Also check out the book by Romain Guy: Filthy Rich Java Clients
I need some help with this program I have to create for Uni. The problem is that the setColor and getColor methods do no work, and the line doesn't change color when I want it too.
What do I need to do to change the color of the line to red?
Cheers
import java.awt.Color;
import java.awt.Point;
import javax.swing.JPanel;
import java.awt.*;
public class Shape extends JPanel {
static Point startPoint = new Point(0, 0);
Point controlPoint = new Point(0, 0);
Color colour = Color.BLACK;
public Shape() {
this(startPoint);
}
public Shape(Point startPoint) {
// initialise variable startPoint
this.startPoint = startPoint;
// execute methods setColour and setControlPoint
setColor(colour);
setControlPoint(controlPoint);
// change startPoint
startPoint.x = 50;
startPoint.y = 50;
}
public void setColor(Color colour) {
this.colour = colour;
colour = Color.RED;
}
public Color getColor() {
return colour;
}
public void setControlPoint(Point controlPoint) {
controlPoint.x = 150;
controlPoint.y = 150;
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(colour);
g.drawLine(startPoint.x, startPoint.y, controlPoint.x, controlPoint.y);
}
}
You need to call repaint() after the color is set
public void setColor(Color colour) {
this.colour = colour;
colour = Color.RED;
// Repaint so the component uses the new color
repaint();
}
Or, you can get rid of the setColor() method.
Then you can use:
setForeground( colour );
to control the color of the line to be drawn.
The color of the Graphics object will be set to the foreground colour so you can also get rid of:
g.setColor( colour );
I am looking for the simplest way to draw some
text around an ellipse object on my app.
I need to create a feeling of "cuddling".
So far, I've used the Graphics2D class to print my drawings
on screen and my "canvas" is a BufferedImage.
The width and height of my ellipses are constant at 50,50 respectively.
Any suggestions?
Here's an example of curved text:
// slightly modified from the original:
// http://examples.oreilly.com/9781565924840/examples/RollingText.java
import javax.swing.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
public class RollingText extends JFrame {
RollingText() {
super("RollingText v1.0");
super.setSize(650, 350);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
String s = "What's our vector, Victor?";
Font font = new Font("Serif", Font.PLAIN, 24);
FontRenderContext frc = g2.getFontRenderContext();
g2.translate(40, 80);
GlyphVector gv = font.createGlyphVector(frc, s);
int length = gv.getNumGlyphs();
for (int i = 0; i < length; i++) {
Point2D p = gv.getGlyphPosition(i);
double theta = (double) i / (double) (length - 1) * Math.PI / 4;
AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());
at.rotate(theta);
Shape glyph = gv.getGlyphOutline(i);
Shape transformedGlyph = at.createTransformedShape(glyph);
g2.fill(transformedGlyph);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new RollingText().setVisible(true);
}
});
}
}
which produces: