我正在制作一个JavaSwing应用程序,遇到了一个问题。我想做一个有图标的按钮。要创建它,我首先创建一个重新缩放的图像图标:
studentIcon = new ImageIcon(new ImageIcon(
"D:\\Programming\\Java\\ELearningDesktop\\src\\com\\core\\student.png")
.getImage().getScaledInstance(64, 64, Image.SCALE_SMOOTH));
然后我做一个按钮并在上面设置图标:
JButton studentButton = new JButton();
studentButton.setIcon(studentIcon);
studentButton.setFocusable(false);
它工作得很好,但由于某些原因,每当我将鼠标悬停在按钮上时,按钮上的图标就会变成像素。在悬停之后,它永远不会变得平滑,除非我重新缩放jframe,这样它可能会调用 repaint()
在某个地方重新粉刷。
我使用下载的外观,但如果使用默认的外观,问题仍然存在。以同样的方式使用imageicon,但不重新缩放也没有帮助-仍会出现像素化。解决办法是什么?
课程起点
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—在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-一个使用gridbaglayout的covenence类
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;
}
}
谢谢
截图:
前两个按钮是平滑的
第二个悬停按钮变为像素化
第三个按钮在调整帧大小后再次变得平滑
2条答案
按热度按时间h6my8fg21#
它永远不会变得平滑,除非我重新缩放jframe,这样它可能会在某个地方调用repaint(),然后重新绘制它。
我想以上是与这个问题有关的。swing不支持透明背景。
swing希望组件是不透明的,在这种情况下,组件负责绘制不透明的背景。
或者,组件可以是非不透明的,在这种情况下,首先绘制父组件以确保绘制不透明的背景。
如果您有透明度,那么您需要使组件不透明,并覆盖paintcomponent方法和自己绘制背景。
基本代码是:
有关更多信息和可重用解决方案,请参见透明背景,这样就不必每次都使用自定义绘制。
mpgws1up2#
编辑:
看起来我的问题与windows缩放有关,正如javaswing给出的答案所示,所有图像都是像素化的。使用这个链接中的标记答案对我很有帮助。在这里:https://stackoverflow.com/a/50566705/12538636
暴力方法:
通过重新油漆按钮的面板,每次有一个按钮的变化,使它看起来光滑的所有时间。下面是代码片段:
唯一的小问题是,现在悬停和按钮对悬停的响应之间有一个很小的差距(稍微改变一个颜色来表示悬停)。