在自定义 JButton 中覆盖 paintComponent() 方法

Overriding paintComponent() Method within a custom JButton

所以我的最终目标是将 JButton 的设计从基本的蓝色按钮更改为我想要的任何东西,比如圆形。 所以我创建了一个名为 "Button" 的 class 并使其扩展 JButton

public class Button extends JButton {

public Button(String text) {
    super(text);
    this.setContentAreaFilled(false);
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    System.out.println("hello");

    //Paint Stuff Will Happen Here
}

@Override
public Dimension getPreferredSize() {
    return (new Dimension(120, 120));
}

}

我的第一个目标只是确保调用了 paintComponent 方法,所以我输入了一条调试消息。该调试消息从未显示过。 基本上永远不会调用 paintComponent() 方法,即使我手动为我的 JFrame 调用 "repaint" 方法。 尽管没有调用该方法,但常规按钮仍然显示在我的 JFrame 上,这让我很困惑。

这是我的 JPanel 代码

public class Scene extends JPanel {

public Scene() {
    //Initialize Listeners
    Button button = new Button("Hello");
    button.setBounds(400, 400, 50, 25);

    this.setLayout(null);
    this.add(button);
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    //Paint Stuff Below
    for (int xI = 0; xI < Sprite.allSprites.size(); xI++) {
        Sprite sprite = Sprite.allSprites.get(xI);

        if (sprite.isVisible) {
            g2.drawImage(sprite.image, sprite.rawLocation.x.intValue(), sprite.rawLocation.y.intValue(), null);
        }
    }

    g2.dispose();
}

}

基本上,在我的 JPanel 中,我重写了 paintComponent 方法,以便将我的各种精灵绘制到屏幕上,这工作得很好,可能与问题无关。

最后,这是我的 JFrame 代码

public class GameWindow extends JFrame {

private Scene currentScene;
public void initialize(Scene scene) {
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(Settings.DEFAULT_WINDOW_SIZE);
    this.setResizable(false);
    this.setLocation(this.getLocationToCenterScreen());

    this.setScene(scene);
}

//Gets the center of the screen with the given window
public Point getLocationToCenterScreen() {
    return new Point(Settings.SCREEN_CENTER.x - (this.getSize().width / 2), Settings.SCREEN_CENTER.y - (this.getSize().height / 2));
}

public void setScene(Scene scene) {
    this.currentScene = scene;
    this.setContentPane(scene);
}

public Scene getCurrentScene() {
    return currentScene;
}

}

据我所知,这段代码并没有什么特别之处。 我已经设置了内容窗格。 我确保每个 paintComponent() 方法还包括 super.paintComponent(g)。 出于测试目的,我已将 LayoutManager 设置为 null。 我已经设置了按钮的边界。

如我所说,按钮确实显示在屏幕上。但调试消息从未显示。 此外,屏幕上显示的按钮看起来很像 10 年前真正古老的 Windows 按钮。全是灰色的,带有黑色边框。 只有在我使用扩展 JButton 的 class 时才会显示这个旧按钮。

无论如何,谢谢大家!我希望我能克服这个奇怪的问题。

首先,正如其他一些人所说,不要命名您的 class "Button";它属于 Swing 的前身 AWT(高级窗口工具包),最好的情况下可能会混淆编译器,最坏的情况下会让你出错 "Button"。

这应该可以解决 paintComponent() 问题,但此外,如果您只是想改变按钮的感觉,那么您就过度编程了。

JButton.

有两种方法可以做到这一点

第一个也是最简单的(对于图像)是 AbstractButton.setIcon(Icon defaultIcon) An Icon is a type of image, loadable from a BufferedImage with ImageIcon(Image image) 并且可以用相同的方式进行操作。这可能就是您所需要的。

我想到的另一种范围更广泛的方法是更改​​应用程序的 Look and Feel。我们大多数人的系统都有几个可用的,包括默认 Java 外观和平台外观。我建议尽早设置它;因为它完全是通过静态方法完成的,对于小项目,你甚至可以在任何东西初始化之前将它放入 main 方法中。

如果这不能解决您的问题,请告诉我,祝您在接下来的项目中一切顺利!