PulsePanda
PulsePanda

Reputation: 1856

Why is my background Glitching after repainting?

I have a program selection tool that i made. it opens a JFrame with 17 buttons, 15 of which are customizable, and they get their text from a .txt document located in the C: drive. when i click the assign button, it opens a JFileChooser to select a file to open when the button is clicked. You then select a button to change, and then type the text you want displayed by the button. After that the program rewrites the .txt file and updates the buttons. here is the code for updating:

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();
}

Thats all the code that is required for this question i believe. The problem is, after the method restart() is called, the background is there, with a white square around the buttons, with it being white inside the square. not really a major problem, but really incredibly annoying and pretty unprofessional. At first i thought it was that the buttons were resizing after the background is painted, so i made it so that the refresh runs twice each time its called. didnt help one bit.

EDIT: I fixed the problem. I took hovercraft's answer and modified what i learned a little bit. all i had to do was modify the restart() method to:

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

because the repaint(); repaint the whole component which was what hovercraft said. Thank you a ton everyone! hope this helps future questions.

Upvotes: 1

Views: 174

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

You appear to be handling your Swing graphics incorrectly by calling paint(...) directly and trying to use a Graphics object outside of a JComponent's paintComponent(...) method. Don't do this, as all the Swing graphics tutorials will tell you (if you've not gone through some of them yet, you will want to do this soon). Instead do all graphics within a JComponent's (such as a JPanel's) paintComponent(...), call the super's method first, and use the Graphics object provided by the JVM in the paintComponent's method parameter.

Edit
Tutorial links:

I'm thinking that you'll have to re-write most of your graphics code. Changes you should make:

  • Draw only in a JPanel or other JComponent-derived class, not in a JFrame or other top-level window.
  • Draw in your class's paintComponent(...) method.
  • Place an @Override annotation just above your paintComponent(...) method to be sure that you are in fact overriding the super method.
  • Call the super's paintComponent(...) as the first line (usually) of your paintComponent(...) override method.
  • Use the Graphics object passed into this method by the JVM.
  • Do not use a Graphics object obtained by calling getGraphics() on a component (with rare exceptions).
  • Do not give your class a Graphics field and try to store the Graphics object in it. The Graphics objects given by the JVM do not persist and will quickly become null or non-usable.
  • Do not call paint(...) or paintComponent(...) directly yourself (with rare exceptions -- and your current code does not qualify as one of the exceptions, trust me).
  • You will likely not need to call repaint() on your JButtons

Upvotes: 4

Related Questions