0

so I'm just learning Java GUI (JFrame, JPanel etc) and I ran into this issue where when I repaint my panel and then continue to add buttons to the same panel, the buttons sort of stutter and only half appear when I hover my mouse over the button.

I will split my code up into the different classes below so hopefully someone with more experience may be able to spot what the issue is.

import javax.swing.JFrame;

public class Main
{
   public static void main(String[] args)
   {
       new Test();
   }
}

Above is the first class

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

public class Test extends JFrame
{
    private menuPanel MENUPANEL;

    public Test()
    {
        super("My Game");
        setLayout(new BorderLayout());
        MENUPANEL = new menuPanel();
        add(MENUPANEL, BorderLayout.CENTER);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(660,360);
        setResizable(false);
        setVisible(true);
    }
}

Here is my class which creates the initial frame.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

public class menuPanel extends JPanel
{
    private JButton btn1, btn2, btn3;
    private JPanel menuPanel;
    private ImageIcon mypic;

    public menuPanel()
    {
        JButton btn1 = new JButton("START GAME");
        btn2 = new JButton("EXIT GAME");
        btn3 = new JButton("OPTIONS");

        setLayout(new FlowLayout());
        add(btn2);
        add(btn1);
        add(btn3);
    }

    @Override
    public void paint (Graphics g)
    {
        super.paintComponents(g);
        ImageIcon i = new ImageIcon("background.gif");
        i.paintIcon(this, g, 0,0);
    }
}

Finally here is my panel class.

Please excuse me if I've used any wrong terminology etc. I've been searching for a fix for this problem for a few hours now and only have a handful of hours experience with Java GUI.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • What are you trying to achieve? – PM 77-1 Feb 25 '19 at 19:26
  • Well, you've completely broken the paint chain (the chain of methods which make up the painting process). Instead of overriding `paint`, override `paintComponent`, instead of call `super.paintComponents` call `paintComponent`s super method instead – MadProgrammer Feb 25 '19 at 19:27
  • Instead of calling `JFrame#setSize`, call `JFrame#pack`, it will better honour the preferred size of it's content – MadProgrammer Feb 25 '19 at 19:28
  • Maybe you should also take a look at [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) and [Painting in AWT and Swing](https://www.oracle.com/technetwork/java/painting-140037.html) to get a better understanding of how the paint system actually works – MadProgrammer Feb 25 '19 at 19:30
  • You might also want to have a look at [How to set a background picture in JPanel](https://stackoverflow.com/questions/22162398/how-to-set-a-background-picture-in-jpanel/22162430#22162430) – MadProgrammer Feb 25 '19 at 19:31
  • @MadProgrammer Thank you so much, it worked perfectly! I will also change my code so it calls pack instead of setSize. Honestly I'm learning this from like 20 different youtube videos any chance you might have a link to where I can learn it properly? – Javed Hakim Feb 25 '19 at 19:32
  • Honestly, the best place to get started is the [Swing Tutorials](https://docs.oracle.com/javase/tutorial/uiswing/), but since you're just learning, I might suggest using JavaFX instead – MadProgrammer Feb 25 '19 at 21:13
  • @MadProgrammer I'll give JavaFX a shot, I do however have another issue. I'd like to reference my JFrame from my JPanel (for example right now I can't just do dispose(); to close the window when opening another) if you don't mind could you inform me on how to call/reference (sorry for bad terminology) my JFrame from my JPanel. – Javed Hakim Feb 26 '19 at 00:49
  • @JavedHakim Generally, you don't want. Usually you'd use a delegate pattern to allow the `JPanel` to inform some interested party that some kind of state has changed and they should take appropriate action. But, you could just use [`SwingUtilities.windowForComponent`](https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#windowForComponent-java.awt.Component-) – MadProgrammer Feb 26 '19 at 01:11
  • 1) A single blank line of white space in source code is all that is *ever* needed. Blank lines after `{` or before `}` are also typically redundant. 2) *`ImageIcon i = new ImageIcon("background.gif");`* should not be in the paint method. Instead declare `ImageIcon i;` as an attribute of the class, and load it during construction. – Andrew Thompson Feb 26 '19 at 02:41

0 Answers0