Setting the size of a customized cursor in java - java

I have customized a cursor on a label component called ageLabel using the following code
ageLabel.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(new javax.swing.ImageIcon(getClass().getResource("/images/image1.jpg")).getImage(),new Point(5,5),"custom cursor"));
It works fine anyway but what I want to do is increase the size of the customized cursor. I have tried changing the point to (10,10) but the cursor size wouldn't change. I also tried changing the dimensions of the image that I used ,it still wouldn't change. I have searched through the internet but to no avail. Is It possible to resize the cursor in anyway? If it is how do I do that?
Thanks in advance for all helps.

Java's Image class has a built in function for scaling.
Documentation: https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html#getScaledInstance(int,%20int,%20int)
My approach to the problem:
Split the line up into many to make it look a bit nicer (not necessary).
Add an extra method call to scale the image up.
Potential Solution:
URL imageResource = getClass().getResource("/images/image1.jpg");
ImageIcon imageIcon = new ImageIcon(imageResource);
Image image = imageIcon.getImage();
// This is the important line that scales the image up!
Image scaledImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);
Toolkit toolkit = Toolkit.getDefaultToolkit();
Cursor cursor = toolkit.createCustomCursor(scaledImage, new Point(5, 5), "Custom Cursor");
ageLabel.setCursor(cursor);
Afterthoughts:
Remember to replace newWidth and newHeight with the values you want.
After you get it working, I'd even go further and extract some of this code into methods.
You might need to tweak your imports a bit if it isn't compiling.
I haven't tried running this code so I don't know if it works.

Related

Make image as tall as text

I have a Button with text and an ImageView as icon. The image might be of any resolution. Currently, the button will adapt its size to fit the image, e.g. if the image is 400x400, the button will be huge and the text will be tiny next to it.
What I want though, is the image to fit into the button. It should always be as tall as the text is.
ImageView img = new ImageView(image);
button = new Button("Some text", img);
button.setStyle("-fx-background-radius: 6em;");
Wouldn't have thought the solution to this is so easy:
img.setPreserveRatio(true);
img.setFitHeight(button.getFont().getSize());
does the trick for me. JavaFX is weirdly unintuitive sometimes. If the font size may change (e.g. via CSS styling), use a binding instead:
img.fitHeightProperty().bind(Bindings.createDoubleBinding(() -> button.getFont().getSize(), button.fontProperty()));
You can set your image height via
image_view.getLayoutParams().height = YOURHEIGHT
as discussed here.
I would suggest setting your text size to an appropriate value and use the above command to scale the image to the same height.
Test around whether you can size the image with em, otherwise use cm/inch.
If there a problems with image distortion when setting height, refer to this thread.

Codename One - Unwanted padding/spacing in ScaleImageLabel

New to Codename One, moving over from Android "native" java development.
I'm trying to create a SideMenu design that loosely resembles the Material side menu, as seen in just about every Google app (e.g. Play Store). Starting with a header image, I can't seem to get rid of some padding on the top and bottom:
The white bars on the top and bottom are unwanted. Current code:
public void start() {
if (current != null) {
current.show();
return;
}
home = new Home();
// SideMenu header BG image
Image headerImage = theme.getImage("bg_navdrawer_header.png");
ScaleImageLabel sideMenuHeaderBg = new ScaleImageLabel(headerImage);
sideMenuHeaderBg.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
// SideMenu header app title
Label sideMenuHeaderLabel = new Label("Title");
sideMenuHeaderLabel.setUIID("SideMenuHeaderTitle");
Container sideMenuHeader = new Container();
sideMenuHeader.add(LayeredLayout.encloseIn(sideMenuHeaderBg, FlowLayout.encloseBottom(sideMenuHeaderLabel)));
home.getToolbar().addComponentToSideMenu(sideMenuHeader);
home.show();
}
The white bars disappear if I use BACKGROUND_IMAGE_SCALED_FILL, but then it doesn't keep aspect ratio - it stretches to fill those two white spaces. (EDIT: It does keep aspect ratio, but it clips the longer dimension). I've tried setting the UIID to "Container" to... everything, makes no difference.
Any ideas?
UPDATE:
For some reason, calling setWidth on the ScaledImageView immediately after setting the background type solved it. Doesn't matter what the width is, any number at all and the "letterboxing" is gone and the height is as it should be.
ScaleImageLabel sideMenuHeaderBg = new ScaleImageLabel(headerImage);
sideMenuHeaderBg.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
sideMenuHeaderBg.setWidth(0);
Going to leave this open in case somebody has a better solution or can at least explain why this is the case, or exactly what is happening since my solution is more of a hack than an actual answer.
BACKGROUND_IMAGE_SCALED_FILL should keep aspect ratio. It resizes the image to "fill" the space's shorter dimension. The longer dimension is clipped.
BACKGROUND_IMAGE_SCALED will stretch to fill the space, but won't keep aspect ratio.
BACKGROUND_IMAGE_SCALED_FIT will also keep aspect ratio. It resizes the image to "fill" the space's longer dimension. The shorter dimension is "letterboxed", as you see in your screenshot.

ImageView doesn't stretch image properly

So I have no clue why this is happening. I am using Universal Image Loader to load these images. It seems like the last line of pixels is being streched for some weird reason. I want the image to just stretch out evenly. (I don't care that it will look weird. The images below are for demo purposes.)
Also, don't mind the first and last image. I purposely blurred that out because it had someone's face on it.
This is how I set up my Universal Image Loader:
//setup Image Loader for loading cruise line logos
displayImageOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)//show this image when image is loading
.showImageForEmptyUri(R.drawable.ic_launcher)//show this image incase image doesn't exist
.showImageOnFail(R.drawable.ic_launcher)//show this image if fetching image from URL didn't work
.cacheInMemory(true)//cache image in RAM
.cacheOnDisc(true)//cache image in device for later use
.considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(5))//super subtle rounded corners on images
.build();
This is caused by the way RoundedBitmapDisplayer draws the bitmap.
If you look at the source, you'll see that it uses a RoundedDrawable, which uses canvas.drawRoundRect() to draw a rounded rectangle of the desired size of the Drawable, using the downloaded image as the texture via a BitmapShader. BitmapShader does not support scaling (only clamping and tile modes). Try using a SimpleBitmapDisplayer instead which uses the normal ImageView.setImageBitmap() way of displaying the image.
If you need rounded corners, you'll have to find a different way to implement that, for example by scaling the Bitmap to the desired size first. Another option is to call Canvas.saveLayer() before delegating to BitmapDrawable for the scaling, and then applying the rounded corner masking effect using PorterDuff.Mode.DST_IN. Either way you'll end up writing a bit more low-level code, but you should be able to encapsulate everything nicely in a custom BitmapDisplayer.

java.awt.Image getWidth and getHeight methods not working well?

I'm trying to display images which happen to be instances of the Image class (http://docs.oracle.com/javase/7/docs/api/java/awt/Image.html).
I need to have it a BufferedImage and I found a piece of code that works well for that purpose (using Graphics).
However to create the BufferedImage I need to know the width and height of the image. The Image class does have getWidth and getHeight methods but they don't seem to work properly all the time. Using debug I found out that sometimes, the width and height were set to -1. I also found out that actually calling getWidth and getHeight methods "updates" the width and height value, so the height and width have correct values after then. So I added a fake "image.getWidth(null)" before calling getWidth and getHeight "for real" and got the right values.
That works fine when I do it in debug mode and step by step, BUT it doesn't work well anymore when I run it normally. I added a "Thread.sleep(5);" after the "fake" getWidth call and it made it work.
This behaviour is quite weird and maybe someone would have an explanation and/or a way to make it work without that sleep trick ?
Edit:
this is how the image is loaded :
URL url = "path/to/img";
Image img = Toolkit.getDefaultToolkit().getImage(url);
I have let's say read-only access to this code, this is why I'd like to start from there to get my BufferedImage.
What I added to this is
image.getWidth(null); // "Fake" call to force the image to update his width&height
try {
Thread.sleep(5);
} catch...
if(image.getWidth(null) != -1 && image.getHeight(null) != -1) {
BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics bg = bi.getGraphics();
bg.drawImage(image, 0, 0 null);
bg.dispose();
}
If I remove the sleep it seems that getWidth "doesn't have time" to complete and I still have width/height = -1 for some images.
Some methods used to compute the dimensions is probably asynchrone.
I understand that the ImageIO.read() is a simpler and more effective method but I'd still like to find a workaround to get this work :)
If it's not possible I'll find another way it's no big deal actually.
Maybe the image isn't fully loaded yet. Try adding a MediaTracker, add the image to the tracker and wait for the image to be fully loaded (using waitForAll or waitForID).
A crude but effective way to wait for an image to fully load is to construct an ImageIcon with it. The constructor doesn't return until the image is fully loaded. I.e.,
new javax.swing.ImageIcon(image); // force image to load

What is the appropriate way to scale the cursor in Java?

I have a piece of code that scales a JPanel in the paintComponent() method as follows:
g2d.translate(this.getWidth()/2, this.getHeight()/2);
g2d.scale(scale, scale);
g2d.translate(-this.getWidth()/2, -this.getHeight()/2);
I expected this to scale the cursor of the JPanel as well, however it does not. I tried creating a custom cursor with a larger image, but it automatically re-sizes it to 32x32. Is there a system-independent way of resizing a cursor to match the scale of my JPanel?
As far as I know, you may 'suggest' differently sized cursor images, but the operating system always has the final say. See http://docs.oracle.com/javase/7/docs/api/java/awt/Toolkit.html#getBestCursorSize(int, int)

Categories