Jmenuitem Imageicon Too Big

JMenuItem ImageIcon too big

If you don't want to scale the image in code (I presume that's what you mean in the question?), why not just make the source image that size to start with? The simplest solution is sometimes the best!

Also, getScaledInstance() is generally a bad idea. This explains why and gives better options for resizing the image. If you're using the image elsewhere, then it's worth reading up on that article and scaling it using a better technique (such as graphics.drawImage()). But if you're just using it in the menu, then resizing the source image is probably the best thing to do.

If you are going to resize:

BufferedImage image = ImageIO.read("img.jpg");
BufferedImage ret = new BufferedImage(32,32,BufferedImage.TYPE_RGB);
ret.getGraphics().drawImage(image,0,0,32,32,null);

Something like that should give you the image, you can then create your ImageIcon using ret.

How to fit Image size to JFrame Size?

First of all, I wouldn't be loading the image inside the paintComponent method, this method is call repeatedly (and some times in quick succession), you don't want to do anything that takes time to execute or consumes resources unnecessarily

Check out Java: maintaining aspect ratio of JPanel background image for suggestions on filling/fitting images to a given area

How to remove the empty icon gap from a JMenuItem (Java Swing)?

I tried to replicate this, and it turns out it is actually directly linked to the LookAndFeel, when it is changed to SystemLookAndFeel (I'm running Win10).
Seems like this is (or was) a bug - see https://bugs.openjdk.java.net/browse/JDK-8152981 (reference taken from this thread).
This seems like it is intentional and I didn't find a way to completely remove the icon-spacing.

Adding this to the JMenuItem helped though:

menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

This will change the component orientation, thus removing the space on the left side. Negative side-effect: it will move the space to the right side. Nonetheless, maybe this works out for you.

Another way I found, which I think only would work if you never use any Icons in your JMenuItem, is like this:

item.setMargin(new Insets(2, -20, 2, 2));

You may tweak these values according to your needs.
I don't know if these workarounds might have any side-effects, I just compiled what I found on the issue.

How can i re-size the width and height of a png file with custom defined value?

Works

  public JButton createButton(String name, String toolTip) {

// Create image
BufferedImage a = null;
try {
a = ImageIO.read((InputStream) P2P.class.getResourceAsStream("/image/menu/" + name + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
BufferedImage bi = new BufferedImage(70, 70, BufferedImage.TRANSLUCENT);

Graphics2D g = (Graphics2D) bi.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(a, 0, 0, 70, 70, null);
g.dispose();
// get the cursor for this button
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
ImageIcon iconRollover = new ImageIcon(bi);
ImageIcon iconDefault = new ImageIcon(bi);
ImageIcon iconPressed = new ImageIcon(bi);

// create the button
JButton button = new JButton();
//button.addActionListener(this);
button.setIgnoreRepaint(true);
button.setFocusable(false);
button.setToolTipText(toolTip);
button.setBorder(null);
button.setContentAreaFilled(false);
button.setCursor(cursor);
button.setIcon(iconDefault);
button.setRolloverIcon(iconRollover);
button.setPressedIcon(iconPressed);
return button;
}

Force JMenuItem size

One way to solve this, is to rescale the icon itself :

 ImageIcon i = new ImageIcon((getClass().getResource("new.png")));
Image image = i.getImage(); // transform it
Image newimg = image.getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
i = new ImageIcon(newimg); // transform it back

Then you set this new resized-icon to your JMenuItem :

*In fact you can just force the size of JMenuItem by declaring :

.setPreferredSize(new Dimension(..,..));

but the problem is that the icon won't be scaled, it will look like the following :

Sample Image

Here is the simple demo I wrote :

public class SwingMenuDemo {

private JFrame mainFrame;

public SwingMenuDemo() { prepareGUI(); }

public static void main(String[] args) {
SwingMenuDemo swingMenuDemo = new SwingMenuDemo();
swingMenuDemo.showMenuDemo();
}

private void prepareGUI() {
mainFrame = new JFrame("Java SWING Examples");
mainFrame.setSize(400, 400);
mainFrame.setVisible(true);
}

private void showMenuDemo() {
//create a menu bar
final JMenuBar menuBar = new JMenuBar();

//create menus
JMenu fileMenu = new JMenu("File");

//create menu items
JMenuItem test1 = new JMenuItem("test1");
JMenuItem test2 = new JMenuItem("test2");
JMenuItem test3 = new JMenuItem("test3");
JMenuItem test4 = new JMenuItem("test4");

ImageIcon i = new ImageIcon((getClass().getResource("new.png")));
Image image = i.getImage(); // transform it
Image newimg = image.getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
i = new ImageIcon(newimg); // transform it back

test4.setIcon(i);

fileMenu.add(test1);
fileMenu.add(test2);
fileMenu.add(test3);
fileMenu.add(test4);

menuBar.add(fileMenu);

//add menubar to the frame
mainFrame.setJMenuBar(menuBar);
mainFrame.setVisible(true);
}
}

The size of original icon :

Sample Image

The scaled icon on JMenuItem :

Sample Image

Double icons with JMenuItem setHorizontalTextPosition on Win

  • My envirment: Windows 10 64bit + JDK 1.8.0_72
  • I'm not sure if this is a bug... Now this bug seems fixed: JDK-8152981 Double icons with JMenuItem setHorizontalTextPosition on Win 10 - Java Bug System

Sample Image

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class WinMenuItemIconTest {
private static JMenuBar makeManuBar() {
JMenuItem menuItem0 = new JMenuItem("Command", createIcon());

JMenuItem menuItem1 = new JMenuItem("LEFT bug?", createIcon());
menuItem1.setHorizontalTextPosition(SwingConstants.LEFT);
//menuItem1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

JMenuItem menuItem2 = new JMenuItem("CENTER bug?", createIcon());
menuItem2.setHorizontalTextPosition(SwingConstants.CENTER);

JMenuItem menuItem3 = new JMenuItem("RIGHT_TO_LEFT", createIcon());
menuItem3.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

JMenu menu = new JMenu("Menu");
menu.add(menuItem0);
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);

JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
return menuBar;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
//NOTE: Bug happens with Windows L&F
String name = UIManager.getSystemLookAndFeelClassName();
try {
UIManager.setLookAndFeel(name);
} catch (Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(makeManuBar());
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
protected static ImageIcon createIcon() {
BufferedImage bi = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.setColor(Color.RED);
g.fillOval(0, 0, 25, 25);
g.dispose();
return new ImageIcon(bi);
}
}


Related Topics



Leave a reply



Submit