package Main;
import javax.swing.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.io.File;
import java.io.IOException;
public class Background {
public static void main(String[] args) {
//Window Name
JFrame F = new JFrame("Xiao's World");
//Background Image
try{
F.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("src/Main/sky.jpg")))));
}catch(IOException e)
{
//Case if image is not available
System.out.println("Image doesn't exist.");
}
//Frame setup and rules
F.setResizable(false);
F.pack();
F.setSize(800, 600);
F.setVisible(true);
}
}
You see I can easily display a background no problem but I want a picture to be displayed on top of this background along with a few others is there a way to make a method to easily display multiply images on top of each other?
I'm trying to create a scene but it's kind of difficult because most tutorials are background imaging and not scene making. Also if you could help me so I can set up a stream of music to go alone with it that would be great, I have the images and the files I just need a code to help me set it up. I'm not that good with methods so explanations are appreciated.
Create a custom component, using something like JPanel
Override it's paintComponent method.
Use a List to maintain the z-ordering of the images and paint them to the component using Graphics#drawImage
See Painting in AWT and Swing and Performing Custom Painting for more details
You will also want to take a look at 2D Graphics to get a good understanding of how you can interact with the Graphics context.
While Swing is double buffered by default, it uses a passive rendering engine, this means that updates to the UI are done at it's discretion.
Eventually, you will want to take control of the rendering process so you can update the UI when you want it to be updated, to do this, you will need to look into BufferingStrategy. You find out more by looking at BufferStrategy and BufferCapabilities and BufferStrategy JavaDocs
Using...
The following code can produce...
This just generates a random point where 0-1000 trees can be added to the scene...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test{
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage sky, mountains, tree;
private List<Point> treePoints;
public TestPane() {
try {
sky = ImageIO.read(getClass().getResource("/Sky.png"));
mountains = ImageIO.read(getClass().getResource("/Mountians.png"));
tree = ImageIO.read(getClass().getResource("/Tree.png"));
} catch (IOException e) {
e.printStackTrace();
}
treePoints = new ArrayList<>(25);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.anchor = gbc.SOUTH;
JSlider slider = new JSlider(0, 1000);
slider.setValue(0);
add(slider, gbc);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
int count = slider.getValue();
if (count == 0) {
treePoints.clear();
} else if (count < treePoints.size()) {
treePoints = treePoints.subList(0, count - 1);
} else {
Rectangle skyBounds = getSkyBounds();
int y = (skyBounds.y + skyBounds.height) - tree.getHeight();
while (treePoints.size() < count) {
int x = skyBounds.x + (int)Math.round((Math.random() * (skyBounds.width + tree.getWidth()))) - tree.getWidth();
treePoints.add(new Point(x, y));
}
}
repaint();
}
});
}
protected Rectangle getSkyBounds() {
int x = (getWidth() - sky.getWidth()) / 2;
int y = (getHeight() - sky.getHeight()) / 2;
return new Rectangle(x, y, sky.getWidth(), sky.getHeight());
}
#Override
public Dimension getPreferredSize() {
return sky == null ? new Dimension(200, 200) : new Dimension(sky.getWidth(), sky.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Rectangle skyBounds = getSkyBounds();
g2d.drawImage(sky, skyBounds.x, skyBounds.y, this);
g2d.drawImage(mountains,
skyBounds.x,
skyBounds.y + skyBounds.height - (mountains.getHeight()),
this);
for (Point p : treePoints) {
g2d.drawImage(tree, p.x, p.y, this);
}
g2d.dispose();
}
}
}
Related
I tried using, "label.setBounds(100,100,250,250)" and "label.setLocation(100,100)" but the image does not move from the top and center of the JLabel.
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Machine extends JPanel
{
public Machine()
{
ImageIcon imageIcon = new ImageIcon("res/robot.png");
JLabel label = new JLabel(imageIcon);
add(label);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new Machine());
frame.setVisible(true);
frame.setSize(new Dimension(1080, 720));
}
}
What are you trying to do?
The default layout of a JPanel is a FlowLayout with center alignment and the label is displayed at its preferred size. So the label is displayed in the center.
You have a couple of options:
Change the alignment of the FlowLayout to be either LEFT or RIGHT
Don't add the label to the panel. Just add it directly to the frame which uses a BorderLayout.
Then you can do something like:
label.setHorizontalAlignment(JLabel.LEFT);
label.setVerticalAlignment(JLabel.CENTER);
Edit:
was just trying to get the image to be in the middle of the frame
Then post your actual requirement when you ask a question. We don't know what "can I change the location" means to you.
So you would either use the BorderLayout and adjust the horizontal/vertical alignment as already demonstrated.
Or, you could set the layout manager of the frame to be a GridBagLayout and then add the label directly to the frame and use:
frame.add(label, new GridBagConstraints());
Now the label will move dynamically as the frame is resized.
If you want to place an image in a certain location, perhaps best is to draw it directly in your JPanel in a paintComponent method override, using one of Graphics drawImage(...) methods, one that allows placement of the image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/f/f2/Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Version 2: MouseListener / MouseMotionListener so that the image can be moved
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/thumb/f/f2/"
+ "Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
MyMouse mouse = new MyMouse();
addMouseListener(mouse);
addMouseMotionListener(mouse);
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
private class MyMouse extends MouseAdapter {
private Point offset;
#Override
public void mousePressed(MouseEvent e) {
// check if left mouse button pushed
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get bounds of the image and see if mouse press within bounds
Rectangle r = new Rectangle(x, y, img.getWidth(), img.getHeight());
if (r.contains(e.getPoint())) {
// set the offset of the mouse from the left upper
// edge of the image
offset = new Point(e.getX() - x, e.getY() - y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
offset = null;
}
private void moveImg(MouseEvent e) {
x = e.getX() - offset.x;
y = e.getY() - offset.y;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
I have a GUI, and the main panels have transparent backgrounds, so
one can see the background image through them. The problem is, clicking on a
button on one of this panels, on Mac OS, where buttons have round borders, their backgrounds turn in a not-transparent color. How could I avoid this?
Here an image:
Simply make the button transparent using setOpaque(false). Never use a alpha color for a background color, Swing only deals with opaque or not opaque components, it does not know how to deal with alpha based colors.
If you use an alpha based background color, Swing does not know that 1- it's suppose to prepare the Graphics context correctly before painting the component and 2- that the components below the component will also need to be updated when the component changes.
Using alpha background colors will generate random and annoying paint artifacts as the complexity of the UI increases and the changes begin to occur (the UI is updated)
See Painting in AWT and Swing and Performing Custom Painting for more details
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage background;
public TestPane() {
JButton btn = new JButton("I'm a transparent button");
btn.setOpaque(false);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btn, gbc);
add(new JButton("I'm not a transparent button"), gbc);
try {
background = ImageIO.read(new File("C:\\hold\\thumbnails\\issue522.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g2d.drawImage(background, x, y, this);
g2d.dispose();
}
}
}
}
If you want to paint an translucent background, you will need to override the components paintComponent method and paint it yourself, making sure that the component is marked as transparent (not opaque) first
I have a class "Map" which extends JPanel. I add it to a class that extends a JFrame.
public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = Math.abs(startX - endX);
int height= Math.abs(startY - endY);
g.setColor(Color.RED);
g.fillRect(startX, startY, width, height);
}
My class "Map" also contains a label with an image in it. If the image is smalled than the window, when I draw a rectangle it is seen.
In short, it is under the label.
paintComponent is the "bottom" of the paint chain, so anything painted here will appear below everything else.
A better solution might be to add the Map panel to the label (setting the JLabel's layout manager appropriately).
Or, create a "base" panel, set it's layout manager to use a OverlayLayout manager and add the JLabel and Map panel to it.
This will, of course, all depend on what it is you want to achieve...
Updated with "Panel on Label" example
Basically, this takes a JLabel, sets an icon (as the background image), set it's layout as BorderLayout and then adds a JPanel on to it.
Remember, JPanel is opaque by default, so you need to make it transparent ;)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class OverlayLabel {
public static void main(String[] args) {
new OverlayLabel();
}
public OverlayLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
background.setLayout(new BorderLayout());
background.add(new TestPane());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(background);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
int x = (getWidth() - 20) / 2;
int y = (getHeight() - 20) / 2;
g2d.setColor(Color.RED);
g2d.fillRect(x, y, 20, 20);
g2d.dispose();
}
}
}
Updated with example of OverlayLayout
OverlayLayout basically uses the components x/y alignment to make determinations about how best it should place the individual components
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class OverlayLabel {
public static void main(String[] args) {
new OverlayLabel();
}
public OverlayLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
background.setAlignmentX(0.5f);
background.setAlignmentY(0.5f);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new OverlayLayout(frame.getContentPane()));
frame.add(new TestPane());
frame.add(background);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
int x = (getWidth() - 20) / 2;
int y = (getHeight() - 20) / 2;
g2d.setColor(Color.RED);
g2d.fillRect(x, y, 20, 20);
g2d.dispose();
}
}
}
And finally, if none of that is working for you, you could use JLayeredPane as the base, which will allow you to determine the z-order of each component...
See How to use layered panes for more details...
I have the following code:
import javax.swing.JWindow;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
public class sutff extends JWindow
{
//Get transparent image that will be use as splash screen image.
Image bi=Toolkit.getDefaultToolkit().getImage("window.png");
ImageIcon ii=new ImageIcon(bi);
public sutff()
{
try
{
setSize(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(null);
show();
//Thread.sleep(10000);
//dispose();
//JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
//Paint transparent image onto JWindow
public void paint(Graphics g)
{
g.drawImage(bi,0,0,this);
}
public static void main(String[]args)
{
sutff tss=new sutff();
}
}
The purpose is to create a window that is translucent and resembles Windows Aero-style glass. I have the following transparent png that I am using:
http://i.imgur.com/5UNGbsr.png
The problem is that since its transparent, its suppose to show the things behind the window, right? That's what it does when first executed, except whatever window is behind this "transparent window" when it first starts up, the program somehow creates an "image" of that and permanently attaches it with the window. So even if I minimize the windows behind this "transparent window," the image of the first background window remains.
Here is a screenshot:
When I took this screen shot, I had already minimized the command prompt and the IDE which can be seen in the background, yet it still remains in the background of the window.
What am I doing wrong?
Don't override the paint() method of a top level container, especially when you don't invoke super.paint(). This will cause painting problems. If you ever do need to do custom painting then you should override the paintComponent() method of JPanel (or JComponent) and then add the panel to the window/frame. Read the Swing tutorial on Custom Painting. This advice is given daily, I don't know why people still try to override paint()???
However this is only one of your problems. The better solution is to add your image to a JLabel and then add the label to the window. You will also need to make the window background transparent:
import javax.swing.*;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.Image;
import java.awt.Toolkit;
public class Stuff extends JWindow
{
//Get transparent image that will be use as splash screen image.
Image bi=Toolkit.getDefaultToolkit().getImage("transparent.png");
ImageIcon ii=new ImageIcon(bi);
public Stuff()
{
try
{
setBackground( new Color(0, 0, 0, 0) );
setSize(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(null);
JLabel label = new JLabel(ii);
add(label);
show();
//Thread.sleep(10000);
//dispose();
//JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
/*
//Paint transparent image onto JWindow
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(bi,0,0,this);
}
*/
public static void main(String[]args)
{
Stuff tss=new Stuff();
}
}
The problem is, you window is actually transparent. Java still thinks that the Window opaque and therefore won't update the graphics in such away as to show what's actually behind.
Creating a transparent window is relatively simple in Java since Java 1.6.10 (I think)
The following is a very simple example, using a semi transparent paint effect that will allow what ever falls below the window to continue to be painted correctly.
import com.sun.awt.AWTUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransaprentBlur {
public static void main(String[] args) {
new TransaprentBlur();
}
public TransaprentBlur() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
// Java 6...
// AWTUtilities.setWindowOpaque(frame, true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.exit(0);
}
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Shape shape = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(225, 225, 225, 128));
g2d.fill(shape);
g2d.setColor(Color.GRAY);
g2d.draw(shape);
g2d.dispose();
}
}
}
Update with image example
Screen shoots showing windows been moved behind the window...
Basically, all you need to do, is place you image rendering code with in the paintComponent method of TestPane
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransaprentBlur {
public static void main(String[] args) {
new TransaprentBlur();
}
public TransaprentBlur() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
// Java 6...
// AWTUtilities.setWindowOpaque(frame, true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage image;
public TestPane() {
try {
image = ImageIO.read(getClass().getResource("/5UNGbsr.png"));
} catch (IOException ex) {
}
setOpaque(false);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.exit(0);
}
}
});
}
#Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - image.getWidth()) / 2;
int y = (getHeight() - image.getHeight()) / 2;
g2d.drawImage(image, x, y, this);
g2d.dispose();
}
}
}
}
Okay so I have a vertical string but when it contains I's or L's they are offset from the rest of the string because of how they are typographically written they are in a sense left justified in the box they are drawn in unlike the rest are drawn centered. I am wondering how to make those letters fall into line with the others. Also of importance is that these are individual drawstring calls. I tried using AffineTransform but it mashes all the letters together. this is the code i use to loop through the string and write each character.
for(int i =0; i<team.length();i++)
{
gg.drawString(Character.toString(team.charAt(i)), 100, ypos-fm.getDescent());
ypos+=40;
}
The string im using is BOLIVAR if you'd like to test it. Thanks in advance!
You could try centering the text around the character width
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestVerticalTexr {
public static void main(String[] args) {
new TestVerticalTexr();
}
public TestVerticalTexr() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
String team = "BOLIVAR";
FontMetrics fm = g2d.getFontMetrics();
int ypos = fm.getHeight();
for (int i = 0; i < team.length(); i++) {
int x = 100 - (fm.charWidth(team.charAt(i)) / 2);
g2d.drawString(Character.toString(team.charAt(i)), x, ypos);
ypos += fm.getHeight();
}
g2d.dispose();
}
}
}
You could consider using a Text Icon. It is a little more sophisticated in the painting of the text.