JTree set transparency of Icon - java

I want to give a visual indication that a node has been transferred to clipboard with a "Cut" action. One intuitive look used by at least one proprietary OS is to make this the same image, but slightly transparent.
I'd quite like to know whether it is in fact possible somehow to use the icons used by the Windoze OS (W7)... but I'd be more intrigued if it were possible to interfere in some way (in the renderer) with the Icon, by somehow messing with the Graphics object used by Icon.paintIcon() ... just for a given node, obviously. I'm not clear where an Icon goes hunting for the Graphics object it uses when it is painted ... any enlightenment would be most welcome.
later
Many thanks to MadProgrammer. Spotted this possibility as a way of extracting obfuscated visuals with a view to their manipulation: https://home.java.net/node/674913 ... it works. Putting code here in case of broken link...
public class IconTest {
public static void main(String[] args) {
Icon leafIcon = UIManager.getIcon("Tree.leafIcon");
// ... ("Tree.closedIcon") ("Tree.openIcon")
BufferedImage img1 = new BufferedImage(leafIcon.getIconWidth(),
leafIcon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = img1.createGraphics();
g.drawImage(((ImageIcon) leafIcon).getImage(), 0, 0, null);
g.dispose();
try {
ImageIO.write(img1, "PNG", new File("leafIcon.png"));
} catch (IOException e) {
System.out.println("Error writing to file leafIcon" + ", e = " + e);
System.exit(0);
}
}
}
Then use MadProgrammer's technique to alter the image in any way one likes: change transparency, colour, etc. Great stuff.

I'd quite like to know whether it is in fact possible somehow to use the icons used by the Windoze OS (W7)
FileSystemView#getSystemIcon will give you the OS's icon representation of a given File, for example...
Icon icon = FileSystemView.getFileSystemView().getSystemIcon(new File("ThatImportantDoc.docx"));
I want to give a visual indication that a node has been transferred to clipboard with a "Cut" action. One intuitive look used by at least one proprietary OS is to make this the same image, but slightly transparent.
You need to paint the previous Icon to BufferedImage, which has had a AlphaComposite applied to it, for example
BufferedImage img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
You then need to wrap the resulting BufferedImage in a ImageIcon, which allows you to pass the image as a Icon to the rest of the API.
JPanel panel = new JPanel();
panel.add(new JLabel(icon));
panel.add(new JLabel(new ImageIcon(img)));
JOptionPane.showMessageDialog(null, panel, "Icon", JOptionPane.PLAIN_MESSAGE);
To get this to finally work, you will need to provide a TreeCellRenderer capable of supporting your functionality. Have a look at How to Use Trees for more details

Just one tweak enabling me to do what I mainly wanted to do: get the UI images "from the source code".
public class IconTest {
public static void main(String[] args) {
// OS folder icon
// Icon icon = FileSystemView.getFileSystemView().getSystemIcon(new File("."));
// proprietary word processor
// Icon icon = FileSystemView.getFileSystemView().getSystemIcon(new File("Doc1.docx"));
// taken from PNG file
// Icon icon = new ImageIcon( "openIcon.png" );
// taken directly from the Java images held somewhere (?) in the code
Icon icon = UIManager.getIcon("Tree.leafIcon");
// Icon icon = UIManager.getIcon("Tree.openIcon");
// ... ("Tree.closedIcon") ("Tree.openIcon")
BufferedImage img = new BufferedImage( icon.getIconWidth(),
icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setComposite(AlphaComposite.SrcOver.derive( 0.5f));
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
JPanel panel = new JPanel();
panel.add(new JLabel(icon));
panel.add(new JLabel(new ImageIcon(img)));
JOptionPane.showMessageDialog(null, panel, "Icon", JOptionPane.PLAIN_MESSAGE);
}
}

Related

Get a specific version of the icon of a file in Java

I was looking at this question and I was looking at the first answer.
So I tried to use this code:
public static Image getIcon(String fileName) throws Exception {
File file = new File(fileName);
FileSystemView view = FileSystemView.getFileSystemView();
Icon icon = view.getSystemIcon(file);
ImageIcon imageIcon = (ImageIcon) icon;
Image image = imageIcon.getImage();
return image;
}
Which does return an Image (or throws an Error) but the Image has terribly low resolution.
I am assuming that this is because the 16x16 Image is returned.
Is there any way to state which Image I want to be returned?
Java offers you two possibilities to retrieve file icons.
You already know the first one:
Icon icon = FileSystemView.getFileSystemView().getSystemIcon(new File(FILENAME));
that gives you a 16x16 pixel result.
The other one using ShellFolder
Icon icon = new ImageIcon(ShellFolder.getShellFolder(new File(FILENAME)).getIcon(true));
will retrieve you the larger one (32x32) depending on the boolean flag getLargeIcon in the getIcon method.
I'm sorry for you but more is (at the moment) not possible with the java default libraries. Interest exists as you can read in this JDK bugreport.
But nothing has been done so far.
If you really want to have larger versions you will need to retrieve them with the OS depending native calls or store them manually as local application ressources.
Note: If you have problems accessing ShellFolder you should read this question.
I used this method:
protected ImageIcon getImageIcon() {
File f = new File((iconPath!=null)?iconPath:"");
if (!f.isFile() || !f.canRead()) {
iconPath = Constants.getDefaultPreviewIconPath();
}
ImageIcon icon = new ImageIcon(iconPath, titolo);
return new ImageIcon(Utils.getScaledImage(
icon.getImage(),
Constants.getICON_WIDTH(),
Constants.getICON_HEIGTH()));
}
where getScaledImage is:
public static Image getScaledImage(Image srcImg, int w, int h) {
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}

Creating bufferedimage only saves the Panel background and not the stuff drawn on it

I have a JPanel object called drawPanel. I draw various things like rectangles on it and when I try to create a bufferedimage and save it as following, it only saves a blank image with just the background color and not the rectangles drawn onto the frame.
BufferedImage image = createImage(drawPanel);
File outputfile = new File("MyImage.jpg");
try {
ImageIO.write(image, "jpg", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
public BufferedImage createImage(JPanel panel) {
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.print(g);
return bi;
}
Kindly help me fix this problem.
This Graphics2D g2 = (Graphics2D) drawPanel.getGraphics(); is your problem. Calling print, printAll or paint will wipe clean anything that was painted to the component using getGraphics.
The short answer is, never use it. The long answer is, create a custom component, that extends from something like JPanel and override it's paintComponent method and perform ALL your custom painting within in it, when it's called.
See Painting in AWT and Swing and Performing Custom Painting for more details
A little hackery with Robot
Simply replace your method createImage with my one. :-)
public BufferedImage createImage(JPanel panel) {
//Get top-left coordinate of drawPanel w.r.t screen
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, panel);
//Get the region with wiht and heighht of panel and
// starting coordinates of p.x and p.y
Rectangle region = panel.getBounds();
region.x = p.x;
region.y = p.y;
//Get screen capture over the area of region
BufferedImage bi = null;
try {
bi = new Robot().createScreenCapture( region );
} catch (AWTException ex) {
Logger.getLogger(MyPaintBrush.class.getName()).log(Level.SEVERE, null, ex);
}
return bi;
}
(Credit to this dude)

System tray text instead of icon

How can I display text in the system tray instead of an icon?
I want to display a percentage for example.
final TrayIcon trayIcon = new TrayIcon(createImage("image.png", "tray icon"));
The code above is to set an icon, but how can I set text such as 100% to display in the system tray? This is specifically on OSX.
You can draw the text onto an image, this does the job although you are still using an image. I don't think there is an other way to do it.
BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
g2d.drawString("100%", x, y);
g2d.dispose();
trayIcon.setImage(image);

Rotating Cursor or Cursor image Java

Okay. So I'm trying to rotate the cursor image or the cursor itself depending on it's position. I have tried using
Graphics2D g2d = (Graphics2D)g;
AffineTransform old = g2d.getTransform();
g2d.rotate(Math.toRadians(degrees));
Toolkit toolkit = Toolkit.getDefaultToolkit(); //Get the default toolkit
Image image = toolkit.getImage("pictures/skills/skill" +InfoReader.SkillData("CastImage") +".png"); //Load an image for the cursor
Cursor cursor = toolkit.createCustomCursor(image, new Point(0, 0), "Cursor");
setCursor(cursor);
g2d.setTransform(old);
So I was thinking that this should rotate the image, but g2d.rotate() doesen't seem to have any effect on cursor? I'm not 100% sure if it has affect on the image itself. Atleast the cursor image is what I want it to be though.
EDIT: Here's an example video :) (In my case, I just want to rotate it around a certain point which stays on the same spot all the time). https://www.youtube.com/watch?v=TQ71QXa-B-s
While searching and asking around for the solution of a similar problem I've found your question and also the answer to it. This is the code I use in my program and it works. Note that this method was designed to be called only once and calling it constantly might require optimization. Also I've learned AffineTransform today and might have made some mistakes(even though code works).
Basically I rotate an image, create a new image from it and set the new image as the cursor.
My "cursor.png" is in the data folder.
private void rotateCursor(double rotation) {
// Get the default toolkit
Toolkit toolkit = Toolkit.getDefaultToolkit();
// Load an image for the cursor
BufferedImage image = null;
try {
image = ImageIO.read(this.getClass().getResource("/data/cursor.png"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
AffineTransform at = new AffineTransform();
// affineTransform applies the added transformations in the reverse order
// 3. translate it back to the center of the picture
at.translate(image.getWidth() / 2, image.getWidth() / 2);
at.rotate(rotation);//2- adds rotation to at (they are not degrees)
//1- translate the object so that you rotate it around the center
at.translate(-image.getWidth() / 2, -image.getHeight() / 2);
BufferedImage rotated = null; // creates new image that will be the transformed image
// makes this: at + image= rotated
AffineTransformOp affineTransformOp = new AffineTransformOp(at,
AffineTransformOp.TYPE_BILINEAR);
image2 = affineTransformOp.filter(image, rotated);
// Create the hotSpot for the cursor
Point hotSpot = new Point(10, 0); // click position of the cursor(ex: + shape's is middle)
Cursor cursor = toolkit.createCustomCursor(rotated, hotSpot, "cursor");
// Use the custom cursor
this.setCursor(cursor);
}
You can use window.getMousePosition().x; and window.getMousePosition().y; for getting mouse position if you are using a mouseListener.
You need to call rotateCursor() method with the correct double. How to calculate the correct double is something I can't help you with.
I hope it helps.
I've learned these from these sources:
storing transformed BufferedImage in Java
http://www.codebeach.com/2008/02/using-custom-cursors-in-java.html
Rotating BufferedImage instances
http://stumpygames.wordpress.com/2012/07/22/particles-tutorial-foundation/ (this tutorial also has a mouse listener)
It seems a bit confusing to me, what are you trying to rotate?
Lets imagine you have a BufferedImage object, you may get a Graphics2D object from it, and by operationg over it, you may get what you want.
java.awt.image.BufferedImage buffImage = null;
try {
java.io.InputStream imageStream =
MyClass.class.getResourceAsStream( "pictures/skills/skill" +InfoReader.SkillData("CastImage") +".png" );
//MyClass is anyclass that you use as relative path...
//use ClassLoader.getSystemClassLoader().getResourceAsStream( ... )
//for a absolute path
buffImage = javax.imageio.ImageIO.read( imageStream );
}
catch ( java.io.IOException | IllegalArgumentException ex ) {
//It may throw IllegalArgumentException if imageStream is null.
}
Graphics2D g2d = buffImage.createGraphics();
try {
AffineTransform old = g2d.getTransform();
g2d.rotate(Math.toRadians(degrees));
g2d.setTransform(old);
}finally {
g2d.dispose();
}
Toolkit toolkit = Toolkit.getDefaultToolkit(); //Get the default toolkit
Cursor cursor = toolkit.createCustomCursor(image, new Point(0, 0), "Cursor");
setCursor(cursor);
Now, if you intend to rotate it while you use it, I'm not sure how, but I hope I have helped a bit.
EDIT: Try to see this link, it might help you: https://www.google.com/#q=java+rotate+Cursor
EDIT 2: I see now what you want exaclty, I don't know how to help you, but try to see the link I gave you (yes it is from google). Even if you don't find much, it might help you in your quest.

Creating image of a panel just creates a panel image rather then the stuff present on the panel

I am writing a code to make an image file of a chart appearing on a panel. For that purpose I create the buffered image of that and then use ImageIO.write(). It works but it only displays the panel(grey coloured panel) but does not show the chart present on that panel. What to do in this case?? Here is my code
com.objectplanet.chart.NonFlickerPanel p =
new com.objectplanet.chart.NonFlickerPanel(new BorderLayout());
p.add("Center", chart); // this statements adds the chart in the center of the panel
ChartPanel.add("Center", p);
ChartPanel.setSize(500, 200);
ChartPanel.show();
int w = ChartPanel.getWidth();
int h = ChartPanel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
ChartPanel.paint(g);
ChartPanel.printAll(g);
File f = new File("D:\\image.png");
try {
// png is an image format (like gif or jpg)
ImageIO.write(bi, "png", f);
} catch (IOException ex) {
ex.printStackTrace();
}
Well i solved the problem .Anyone facing the same problem ,here is the solution
Use paintall function rather than just paint function

Categories