1

我有一个我制作的程序选择工具。它会打开一个带有 17 个按钮的 JFrame,其中 15 个是可自定义的,它们从位于 C: 驱动器中的 .txt 文档中获取文本。当我单击分配按钮时,它会打开一个 JFileChooser 以在单击按钮时选择要打开的文件。然后选择要更改的按钮,然后键入要通过该按钮显示的文本。之后,程序会重写 .txt 文件并更新按钮。这是更新的代码:

public static void restart() {
    start.assignButtonActions();
    start.assignButtonText();
    start.paint(graphics);
}
public void assignButtonActions() {
    /**
     * assign button actions
     */
    for (int i = 0; i < buttonAction.length; i++) {
        buttonAction[i] = io.readSpecificFromHD("C:\\ButtonActions.txt", i
                + 1 + actionButton.length);
    }
}

public void assignButtonText() {
    for (int i = 0; i < actionButton.length; i++) {
        /**
         * set button text
         */
        actionButton[i].setText(io.readSpecificFromHD(
                "C:\\ButtonActions.txt", i + 1));
    }

}
public void paint(Graphics g) {
    g.drawImage(getImage("files/background.png"), 0, 0, FRAMEWIDTH,
            FRAMEHEIGHT, null);
    refresh();
}

public void refresh() {
    graphics.drawImage(getImage("files/background.png"), 0, 0, FRAMEWIDTH,
            FRAMEHEIGHT, null);
    for (int i = 0; i < actionButton.length; i++) {
        actionButton[i].repaint();
    }
    assignButton.repaint();
    helpButton.repaint();
}

这就是我相信这个问题所需的所有代码。问题是,restart()调用该方法后,背景就在那里,按钮周围有一个白色方块,方块内部是白色的。不是一个真正的大问题,但真的非常烦人而且非常不专业。起初我以为是在绘制背景后按钮正在调整大小,所以我做了它,以便每次调用时刷新运行两次。一点帮助都没有。

编辑:我解决了这个问题。我接受了气垫船的回答并修改了我学到的一点。我所要做的就是将restart()方法修改为:

public static void restart() {
    start.assignButtonActions();
    start.assignButtonText();
    start.repaint();
}

因为repaint();重绘了气垫船所说的整个组件。非常感谢大家!希望这有助于未来的问题。

4

1 回答 1

4

通过直接调用并尝试在 JComponent 的方法paint(...)之外使用 Graphics 对象,您似乎错误地处理了 Swing 图形。paintComponent(...)不要这样做,因为所有的 Swing 图形教程都会告诉你(如果你还没有学习过其中的一些,你很快就会想要这样做)。而是在一个 JComponent 的(比如 JPanel 的)内做所有的图形paintComponent(...),先调用 super 的方法,然后在 paintComponent 的方法参数中使用 JVM 提供的 Graphics 对象。

编辑
教程链接:

我认为您将不得不重新编写大部分图形代码。你应该做的改变:

  • 仅在 JPanel 或其他 JComponent 派生类中绘制,而不在 JFrame 或其他顶级窗口中绘制。
  • 绘制你的类的paintComponent(...)方法。
  • 在您的方法上方放置一个 @Override 注释,paintComponent(...)以确保您实际上覆盖了超级方法。
  • 将超级调用作为覆盖方法paintComponent(...)的第一行(通常) 。paintComponent(...)
  • 使用 JVM 传递给此方法的 Graphics 对象。
  • 不要使用通过调用getGraphics()组件获得的 Graphics 对象(极少数例外)。
  • 不要给你的类一个 Graphics 字段并尝试在其中存储 Graphics 对象。JVM 提供的 Graphics 对象不会持久存在,并且会很快变为 null 或不可用。
  • 不要自己打电话paint(...)paintComponent(...)直接打电话(除了极少数例外——而且你当前的代码不属于例外之一,相信我)。
  • 您可能不需要调用repaint()您的 JButton
于 2012-08-08T21:16:49.337 回答