I'm making a Java Swing app and I came across a problem. I want to make a button with an icon on it. To make it, I first make a rescaled ImageIcon:
studentIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\student.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
Then I make a button and set the icon on it:
JButton studentButton = new JButton();
studentButton.setIcon(studentIcon);
studentButton.setFocusable(false);
It works fine, but for some reason the icon on button becomes pixelated every time I hover mouse onto it. After hovering it never becomes smooth unless I rescale the JFrame, so that it probably calls repaint()
somewhere and it repaints it.
I use a downloaded look-and-feel but the problem remains if I use the default look-and-feel. Using ImageIcon the same way, but without rescaling does not help - pixilation still appears. What could be the solution?
Starting point of the program
public class Starter {
public static void main(String[] args) {
FlatLightLaf.install();
EventQueue.invokeLater(()->{
AuthFrame frame = new AuthFrame();
frame.setVisible(true);
});
}
}
AuthFrame
public class AuthFrame extends JFrame {
private JPanel mainPanel;
private LoginPanel loginPanel;
private ImageIcon studentIcon;
private ImageIcon teacherIcon;
public AuthFrame() {
setLayout(new GridBagLayout());
ImageIcon imageIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\tileBackground.jpg")
.getImage().getScaledInstance(321, 333, Image.SCALE_SMOOTH));
mainPanel = new BackgroundPanel(imageIcon.getImage(), BackgroundPanel.TILED,
0f, 0.5f);
add(mainPanel, new GBC(0, 0).setFill(BOTH).setWeights(1, 1));
mainPanel.setLayout(new GridBagLayout());
studentIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\student.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
teacherIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\teacher.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
loginPanel = new LoginPanel();
mainPanel.add(loginPanel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setExtendedState(Frame.MAXIMIZED_BOTH);
}
LoginPanel - a private inner class that is used in the AuthFrame
private class LoginPanel extends JPanel {
private JTextField usernameField;
private JPasswordField passwordField;
private JLabel errorLabel;
private JButton studentButton;
private JButton teacherButton;
private JLabel titleLabel;
private boolean forStudent = true;
public LoginPanel() {
setLayout(new GridBagLayout());
setBackground(new Color(255, 255, 255, 181));
studentButton = new JButton();
studentButton.setIcon(studentIcon);
studentButton.setFocusable(false);
//add(studentButton, new GBC(0, 0).setAnchor(GBC.WEST).setInsets(10));
teacherButton = new JButton(teacherIcon);
teacherButton.setFocusable(false);
add(teacherButton, new GBC(0, 0).setAnchor(GBC.WEST).setInsets(10));
titleLabel = new JLabel("<html>Signing in as <b>student</b></html>");
Utils.deriveFontForTo(titleLabel, 24f);
add(titleLabel, new GBC(1, 0).setAnchor(GBC.EAST).setInsets(10));
titleLabel.setVerticalAlignment(JLabel.BOTTOM);
JLabel usernameLabel = new JLabel("Username");
Utils.deriveFontForTo(usernameLabel, 24f);
add(usernameLabel, new GBC(0, 1).setAnchor(GBC.WEST).setInsets(10));
usernameLabel.setHorizontalAlignment(LEFT);
JLabel passwordLabel = new JLabel("Password");
Utils.deriveFontForTo(passwordLabel, 24f);
add(passwordLabel, new GBC(0, 2).setAnchor(GBC.WEST).setInsets(10));
usernameField = new JTextField(15);
Utils.deriveFontForTo(usernameField, 24f);
add(usernameField, new GBC(1, 1).setInsets(10));
passwordField = new JPasswordField(15);
Utils.deriveFontForTo(passwordField, 24f);
add(passwordField, new GBC(1, 2).setInsets(10));
errorLabel = new JLabel();
Utils.deriveFontForTo(errorLabel, 16f);
errorLabel.setForeground(Color.RED);
add(errorLabel, new GBC(1, 3).setAnchor(GBC.WEST).setInsets(2));
errorLabel.setHorizontalAlignment(LEFT);
JButton loginButton = new JButton("Log in");
loginButton.setFocusable(false);
Utils.deriveFontForTo(loginButton, 24f);
add(loginButton, new GBC(1, 4, 1, 1)
.setFill(GridBagConstraints.HORIZONTAL).setInsets(10));
JButton registerButton = new JButton("Sign Up");
loginButton.setFocusable(false);
Utils.deriveFontForTo(registerButton, 24f);
add(registerButton, new GBC(1, 5, 1, 1)
.setInsets(10));
}
}
GBC - a covenience class to use GridBagLayout
package com.core.helpers.graphics;
import java.awt.*;
public class GBC extends GridBagConstraints {
public GBC(int gridX, int gridY){
super.gridx = gridX;
super.gridy = gridY;
}
public GBC(int gridX, int gridY, int gridWidth, int gridHeight){
super.gridx = gridX;
super.gridy = gridY;
super.gridwidth = gridWidth;
super.gridheight = gridHeight;
}
public GBC setAnchor(int anchor){
super.anchor = anchor;
return this;
}
public GBC setWeights(double weightX, double weightY){
super.weightx = weightX;
super.weighty = weightY;
return this;
}
public GBC setFill(int fill){
super.fill = fill;
return this;
}
public GBC setInsets(int k){
this.insets = new Insets(k,k,k,k);
return this;
}
}
Thanks
Screenshots:
first - two buttons are smooth