Java Graphics2D transparent background - java

I have a Graphics2D object and I want to set up the background of the object. It has a setBackground method, which has a Color parameter. This way I can set the color of the background.
My question is: how can I set the transparency of the background of the object? Can I somehow tell it to be completely transparent? Can I somehow tell it to be completely opaque? Can I somehow tell it to have 0.8 transparency/opacity? How can I set these values?
I have seen that there are int predefined values called TRANSLUCENT and OPAQUE, but I am not sure how can I use them.
Maybe the correct usage is to call the constructor of Color with an int parameter?

You can construct a Color object by specifying a transparency. For example the following code constructs a RED color with 50% transparency
Color c=new Color(1f,0f,0f,.5f );

You can call the constructor of Color in the following way:
Color c = new Color(r,g,b,a);
where a is the alpha (transparency) value.
As with all Java classes, you can find this information in the official API: http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html
It's a really good resource and can spare you waiting for an answer on here.

You may try this if you are using a JPanel :
jPanel1.setOpaque(false);

jPanel1.setBackground(new Color(0,0,0,200));
/*This will put a transparent black color on a panel, the important part of the code is: .setBackground(new Color(0,0,0,200));*/

Java is actually pretty good at this stuff, you can achieve transparency and much more. Here's some code for a simple transparent window I copied from oracle:
package misc;
import java.awt.*;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class TranslucentWindowDemo extends JFrame {
public TranslucentWindowDemo() {
super("TranslucentWindow");
setLayout(new GridBagLayout());
setSize(300,200);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add a sample button.
add(new JButton("I am a Button"));
}
public static void main(String[] args) {
// Determine if the GraphicsDevice supports translucency.
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
//If translucent windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) {
System.err.println(
"Translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
// Create the GUI on the event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TranslucentWindowDemo tw = new TranslucentWindowDemo();
// Set the window to 55% opaque (45% translucent).
tw.setOpacity(0.55f);
// Display the window.
tw.setVisible(true);
}
});
}
}
Look here for more information.

If what you want is to give a transparent effect use the Color properties to 4 variables:
this.setBackground (new Color (0,0,0, .5f));
this gives the background the RGB color of the first three parameters (*new Color (** 0,0,0, **. 5f)*) and the fourth is used to determine the percentage of opacity (opaque )
If you want the background not to be displayed, use the value null
this.setBackground (null);
Many use setOpaque (false); but that takes away the padding not the background.

Use the constructor of the color like this:
Color color = new Color(152,251,152, 50);
The value 50 is for the transparency.

Related

Problems with the alpha parameter when setting a background color for JTextFields

I am writing a chat program and I was trying to make it more interesting by adding a background image to the main JPanel (the one on which everything is built). When I try to change the transparency of a JTextField or JTextArea 50% using the code
MainPanel = new JPanel(){
#Override
public void paintComponent(Graphics g) {
ImageIcon im = new ImageIcon("background.jpg");
Image i = im.getImage();
g.drawImage(i,0,0,this.getSize().width,this.getSize().height,this);
}
};
...
outputWindow.setBackground(new Color(0,0,0,128));
where 'outputWindow' is a JTextArea added to 'MainPanel', I get a lot of garble once I display some text in the area.
Screenshot of the problem
I typed in "hi" and "hello world" in that order, which you can see at the top of the output screen, but is there any way to get rid of the extra garble?
For each Swing component which is partially transparent, be sure you call setOpaque(false);
https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/

Why does the JTable not show the Jtable heading even when added to JScrollPane?

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.TableColumn;
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.awt.Checkbox;
import java.awt.Paint;
import java.awt.Toolkit;
import java.awt.event.*;
public class Main extends JPanel {
static Object [][] Services = {{"Google.exe","Chickeaen.exe","Crp.exe"}};
static String [] ColNames = {"Processes:","Crolly:","Haler:"};
static JFrame Fram = new JFrame();
static JTextField CBox = new JTextField();
static JTable Tabs = new JTable(Services,ColNames);
JScrollPane ScrollArea = new JScrollPane();
static JButton ExitB = new JButton();
Dimension ScreenSize = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
Border BlackLineB = BorderFactory.createLineBorder(new Color(50,50,50));
public Main() {
Fram.setTitle("Jared Console");
Fram.setUndecorated(true);
Fram.setVisible(true);
Fram.setDefaultCloseOperation(Fram.EXIT_ON_CLOSE);
Fram.setResizable(false);
Fram.setSize((int)Math.round(ScreenSize.getWidth()*0.45),(int)Math.round(ScreenSize.getHeight()*0.33));
Fram.setBackground(new Color(0,0,0,150));
Fram.add(this);
CBox.setSize((int)Math.round(Fram.getWidth()*0.80),(int)Math.round(Fram.getHeight()*0.25));
CBox.setBackground(new Color(255,255,255));
CBox.setBorder(BorderFactory.createCompoundBorder(BlackLineB,BorderFactory.createEmptyBorder(0,20,0,0)));
CBox.setLocation((int)Math.round(Fram.getWidth()*0.1),(int)Math.round(Fram.getHeight()*0.70));
CBox.setFont(new Font("Arial",Font.BOLD,20));
CBox.setVisible(true);
ScrollArea.setSize((int)Math.round(Fram.getWidth()*0.80),(int)Math.round(Fram.getHeight()*0.50));
ScrollArea.setLocation((int)Math.round(Fram.getWidth()*0.10),(int)Math.round(Fram.getHeight()*0.10));
ScrollArea.setBorder(BlackLineB);
ScrollArea.setLayout(null);
ScrollArea.setVisible(true);
Tabs.setSize((int)Math.round(Fram.getWidth()*0.995),(int)Math.round(Fram.getHeight()*0.995));
Tabs.setLocation((int)Math.round(Fram.getWidth()*0.003),(int)Math.round(Fram.getHeight()*0.005));
Tabs.setFillsViewportHeight(true);
Tabs.setBackground(new Color(255,255,255));
this.add(CBox);
this.add(Tabs);
this.add(ExitB);
ScrollArea.add(Tabs);
this.add(ScrollArea);
this.setBorder(BorderFactory.createLineBorder(new Color(50,50,50),5));
this.setLayout(null);
this.setBackground(new Color(0,0,0));
this.setVisible(true);
}
public void paintComponent(Graphics Gla) {
Paint Plat = new GradientPaint(0f, 0f, new Color(0, 40, 0, 0), 0.0f, Fram.getHeight(), new Color(0, 0, 0, 150), true); //Made 200 equal to Fram Background Alpha.
Graphics2D Quo = (Graphics2D)Gla;
Quo.setPaint(Plat);
Quo.fillRect(0, 0, Fram.getWidth(), Fram.getHeight());
}
public static void main(String[] args) {
Main CScreen = new Main();
GraphicsEnvironment GE = GraphicsEnvironment.getLocalGraphicsEnvironment(); // Have to study lines 57,58 and 59
GraphicsDevice GD = GE.getDefaultScreenDevice();
boolean CheckTransL = GD.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!CheckTransL) {
System.out.println("PERPIXEL TRANSLUCENT NOT SUPPORTED - LOL UPDATESCRUB!");
System.exit(0);
};
}
}
Why does the JTable not show the Jtable heading even when added to JScrollPane?
Also the Console shows a error message at first then quickly goes away and launches the program? So yea I'd like to know what's wrong with this and also can you can note me of some bad habits in this program such as the way it's being typed.
Problems
null layout. Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify. See Laying Out Components Within a Container for more details
Over use of static. static is not your friend and you should avoid using it. It is not a cross object communication mechanism and over use like this will burn you
You don't actually wrap the JTable in JScrollPane
Breaking the paint chain by not calling super.paintComponent, this is going to produce a series of wonderful paint artifacts. See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
All interactions, creations and modifications to the UI should be done from within the context of the Event Dispatching Event, to reduce the risk of potential race conditions, dead locks and rendering artifacts. See Initial Threads for more details
Toolkit.getDefaultToolkit().getScreenSize() is a bad indicator for the viewable space of a screen, it does not take into account OS specific elements, like the dock or task bar, which could have your application appearing under them (and I really, really, REALLY hate it when that happens). Use appropriate layout managers and pack to pack the window around the content. You can then use JFrame#setLocationRelativeTo and pass it null and it will center the frame in the screen
JScrollPane issue...
The simply solution would be to use JScrollPane's constructor to pass it the reference of the JTable...
static JTable Tabs = new JTable(Services,ColNames);
JScrollPane ScrollArea = new JScrollPane(Tabs);
But, then you do this later in your code...
this.add(Tabs);
This will remove the table from the scroll pane to add it to you panel, as a component can only have a single parent.
Another option would be to specifiy the scroll pane's viewport's view component...
this.add(CBox);
//this.add(Tabs);
this.add(ExitB);
//ScrollArea.add(Tabs);
ScrollArea.setViewportView(Tabs);
this.add(ScrollArea);
You should never add components directly to a scroll pane (or it's underlying viewport), they have their own internal layout management functionality going on. Instead, you need to supply the component as the "view" to the JViewport
Take a look at How to Use Scroll Panes for more details.
First of all you should add a JTable to the ViewPort of the a JScrollPane in order to JTableHeader could be visible.
After that you should not add your JTable to both the JScrollPane and also the underlying container. You should:
add the JTable to the ViewPort of the JScrollPane.
add the JScrollPane to the underlying container.
and remove the line that add the JTable to the container explicitly.
Good Luck.

Window Size is smaller than it should be

Alright so I've got this JFrame with a screen on it. I've set the size to 800 by 800. However the window is created smaller than that. It's not a problem with the taskbar because it's not fullsize.
package sharph;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main extends JFrame {
public static String Title = "Game 1";
public static Dimension screenSize = new Dimension(800,800);
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle(Title);
frame.setSize(screenSize);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
Screen screen = new Screen();
screen.setSize(screenSize);
frame.add(screen);
frame.setVisible(true);
}
}
In the screen class the paint method draws a box around where the border should be:
//Draw border
g.setColor(Color.RED);
g.drawRect(1, 1, 799, 799);
When I run it, the window is smaller than the box and the bottom and right sides are cut off.
Note the second picture I manually re-sized to show the border difference.
I realize that I have drawn the box 1 pixel smaller on each side, but the difference is much more than 2 pixels.
This happens because the content needs to squeezed into the size of the frame minus its borders.
Checkout this question and this question for a more detailed explanation
The layout manager is also overriding the size property you set on the Screen component. In either case, you should be overriding the getPreferredSize method of the Screen class
Also, you shouldn't be relying on magic numbers or assumptions about the actual size of the component, but should, instead, be using getWidth and getHeight instead (I know, it's just for demonstration purposes)
Instead of "screen.setSize(screenSize);" type "screen.setPreferredSize(screenSize);" and then after you type "frame.setVisible(true);" type "frame.pack()". You can also remove "frame.setSize(screenSize);" if you want to.

Nimbus look-and-feel changes color of JButtons

I have a JButton with an icon on it.
I want the background color of the JButton to be the same as the icon.
The following code works fine in the standard look-and-feel :
button.setBackground(new Color(212,208,199));
But when I change my look-and-feel to Nimbus, then the background color of the JButton is much lighter.
The JButton still changes its background color when I change the color in button.setBackground(), but I have no idea to what color I need in Nimbus to get the same color as the background color of the JButton.
Of course I could try to find the color by sight by trying all values, but there should be a simpler way.
I also tried changing the background color via the following code, but with the same result :
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
defaults.put("Button.background",new Color(212,208,199));
How can I change the background color of my JButton in Nimbus, so that it merges with the background color of the containing icon ?
Below are some pictures of the button with default LaF, nimbus LaF (same code), and nimbus LaF (red color) :
Default LaF, using button.setBackground(new Color(212,208,199)) :
Nimbus LaF, using button.setBackground(new Color(212,208,199)) :
Nimbus LaF, using button.setBackground(Color.red) :
please why Table.background use Button.background instead
for more keys to see Nimbus Default
more about Background for JButton in Nimbus
maybe??? (no idea from your descriptions), maybe there no reason to change Background, have to look at JButtons API
methods
JButton.setBorderPainted(false);
JButton.setBorder(null);
JButton.setFocusable(false);
JButton.setMargin(new Insets(0, 0, 0, 0));
JButton.setContentAreaFilled(false);
JButton.setIcon(someIcon);
JButton.setRolloverIcon(someIcon);
JButton.setPressedIcon(someIcon);
JButton.setDisabledIcon(someIcon);
Use an image with no transparency and the 'background' will be whatever color is in the BG of the image.
The icons are jpg files (with no transparency) but only fill a part of the whole button..
See this question for tips on how to get buttons that are the exact size of the icon. The image below is formed from 4 buttons and 5 labels with the icons cut from a single image.
..the text below the icon would still show the button background color..
Oh right. Text as well.
In that case, the best strategy is to create an image with a transparent BG from the existing image, then use it in whatever button (with whatever GB color) it comes.
To do that, get a PNG of the image (PNG is not lossy like JPG), and use a dedicated image editor to save it with a transparent BG. But if we are forced to do it at run-time, consider using something like this:
This image actually demonstrates the lossy nature of JPG. We have to go more & more 'distant' from the base BG color to try and pick up all pixels that are outside the original icon. Even at its loosest interpretation of similar color, I still see some spots I would prefer removed.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
class ImageBackgroundCleaner {
public static BufferedImage clearImageBackground(BufferedImage solidBG, int distance) {
int w = solidBG.getWidth();
int h = solidBG.getHeight();
BufferedImage transparentBG = new BufferedImage(
w,
h,
BufferedImage.TYPE_INT_ARGB);
int c = solidBG.getRGB(0, 0);
for (int xx=0; xx<w; xx++) {
for(int yy=0; yy<h; yy++) {
int s = solidBG.getRGB(xx, yy);
if (getColorDistance(s,c)>=distance) {
transparentBG.setRGB(xx, yy, s);
}
}
}
return transparentBG;
}
public static int getColorDistance(int color1, int color2) {
Color c1 = new Color(color1);
Color c2 = new Color(color2);
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
return Math.abs(r1-r2) + Math.abs(g1-g2) + Math.abs(b1-b2);
}
public static void main(String[] args) throws Exception {
URL url = new URL("http://i.stack.imgur.com/Yzfbk.png");
BufferedImage bi = ImageIO.read(url);
final BufferedImage img = bi.getSubimage(39, 21, 40, 40);
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new GridLayout(3,0,5,5));
gui.setBackground(Color.RED);
JLabel original = new JLabel(new ImageIcon(img));
gui.add(original);
int start = 12;
int inc = 3;
for (int ii=start; ii<start+(8*inc); ii+=inc) {
gui.add(new JLabel(new ImageIcon(clearImageBackground(img, ii))));
}
JOptionPane.showMessageDialog(null, gui);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
The question still ponders me, as I would like to know why nimbus changes the outcome of setBackground() ... I assume nimbus applies some kind of color mask, which slightly changes the colors slightly?
But : in my project the buttons are all in a separate JPanel, and the Jpanels which require the nimbus LaF don't have any buttons, so I solved the problem by using the default LaF for the buttons JPanel, and only use the nimbus LaF in the JPanels where I need it.
Sorry, that I didn't think of this before (I somehow assumed the LaF had to apply to the whole project).
So problem solved, but still curious to an answer about the nimbus color handling ....
// you can always try this, it worked for me
button.setContentAreaFilled(false);
button.setOpaque(true);

drawing boxes in java

I have wrote a program that simulates memory allocation with first fit and best fit algorithms .
Now I want to associate my program with a drawing of set of boxes representing available memory segments
Before Allocation
After Allocation
So it just redraws but resizes one box and colors it ... What is the easiest way to do so ?
I have a set of boxes with different sizes that will be drawn dynamically according to input when the user does some action one of the boxes will be resized and recolored and so on.
I think this is best approached using graphics.
Instantiate a BufferedImage of a size to fit all boxes.
Get a Graphics instance by calling either of getGraphics() or createGraphics().
For each memory block:
Call Graphics.setColor(Color) according to allocation status, then..
Graphics.fillRect(int,int,int,int) or fillPolygon(Polygon) to draw the memory block.
If needed, use an AffineTransform to scale the sizes. This would require a Graphics2D object to draw on.
Use JPanel add JLabels like 0verbose but the layout to go with in my opinion is BoxLayout or GridBagLayout.
With FlowLayout you would have to make sure the size of the container is of a proper width to place one component under another, as by default it places components in a row.
From Java tutorial about FlowLayout "The FlowLayout class puts components in a row, sized at their preferred size. If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows."
Use a JPanel as container with vertical FlowLayout BoxLayout, and add to it a JLabel for each memory block.
If the memory blocks can be rendered all the same size, a JComponent (or even easier a JProgressBar) could be used to represent each memory block. Those could then be put into a GridLayout or BoxLayout to organize the placement. E.G.
MemoryAllocation.java
import java.awt.*;
import javax.swing.*;
import java.util.Random;
class MemoryAllocation {
public static JProgressBar getMemoryBlock(int full) {
JProgressBar progressBar = new JProgressBar(
SwingConstants.VERTICAL, 0, 100);
progressBar.setValue(full);
progressBar.setPreferredSize(new Dimension(30,20));
return progressBar;
}
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
JPanel memoryView = new JPanel(new GridLayout(0,10,1,1));
Random random = new Random();
for (int ii=0; ii<200; ii++) {
int amount = 100;
if (random.nextInt(5)==4) {
amount = 100-random.nextInt(75);
}
memoryView.add( getMemoryBlock(amount) );
}
JOptionPane.showMessageDialog(null, memoryView);
}
});
}
}
Screen Shot

Categories

Resources