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 :
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 :
The scaled icon on JMenuItem
:
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
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
How to Match String Within Parentheses (Nested) in Java
Differencebetween Jvm, Jdk, Jre & Openjdk
How to Calculate the Intersection of Two Sets
Printing All Variables Value from a Class
How to Compare Two Java Objects
In Java, What Are the Advantages of Streams Over Loops
Why Won't This Generic Java Code Compile
How Does Java "Week Year" Really Work
When Would You Use a Weakhashmap or a Weakreference
Easy, Simple to Use Lru Cache in Java
Jre 1.7 - Java Version - Returns: Java/Lang/Noclassdeffounderror: Java/Lang/Object
Does Java Evaluate Remaining Conditions After Boolean Result Is Known
How to Create a Linked List Data Structure in Java
Best Way to Represent a Fraction in Java
Java Equivalent to C# Extension Methods
Why Java Polymorphism Not Work in My Example
How to Handle Very Large Numbers in Java Without Using Java.Math.Biginteger