1

So like the title says, I'm trying to set the background color of a panel within a frame so that they'd both have different colors. What I tried so far is using the setBackground method on each alone or at the same time and the result I got is always only one color showing, which is weird because the inner frame shouldn't be able to change the outer frame's settings, right?

code example:

public class frameStuff{

    private JFrame frame;
    private frame1 in_frame;

    @SuppressWarnings("serial")
    class frame1 extends JPanel  {
        frame1(){
            super();
        }

        public void paint(Graphics g){

        }
    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    frameStuff window = new frameStuff();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public frameStuff() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 500, 350);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
//      frame.getContentPane().setBackground(Color.GRAY);/*if this line wasn't a comment then everything would be grey instead of white as it's now.

        in_frame = new frame1();
        in_frame.setBounds(100, 100, 350, 220);
        in_frame.setBackground(Color.BLUE);
        in_frame.setVisible(true);//this doesn't seem to matter whatever the case
        frame.getContentPane().add(in_frame);

    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
NerdOnline
  • 153
  • 6
  • 5
    Remove `public void paint(Graphics g){ }` .. Don't override a working method only to have it do nothing! – Andrew Thompson Jan 26 '15 at 08:39
  • @Andrew Thompson That's the reason I want to have a costume JPanel class to begin with though, in the code I'm using I'm displaying a bunch of shapes on it. – NerdOnline Jan 26 '15 at 08:41
  • 1
    Note that `class frame1 extends JPanel {` is **not** a frame and should not be called that! – Andrew Thompson Jan 26 '15 at 08:41
  • @Andrew Thompson You're correct though, it seems like I'm missing out on something in the paint method then, because when it's removed the background thing is working properly, any idea what that might be? – NerdOnline Jan 26 '15 at 08:44
  • 4
    *"That's the reason I want to have a costume JPanel class to begin with though.."* If it is not necessary to display the problem, it is redundant. Otherwise, it is causing problems right now. Given this is a `JComponent` (a `JPanel` extends `JComponent`) it would **never** be correct to override `paint(..)` - instead override `paintComponent(..)` and immediately call `super.paintComponent(..);` – Andrew Thompson Jan 26 '15 at 08:45
  • *"..any idea what that might be?"* Overriding the `paint(..)` method to do nothing **breaks the paint chain.** With one 'link' in the chain broken, the entire GUI (within that component) will paint poorly or not at all. – Andrew Thompson Jan 26 '15 at 08:46
  • 1
    `frame.getContentPane().setLayout(null);` This comes up once or twice a day. (so *again*) Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Jan 26 '15 at 08:48
  • 1
    "it would never be correct to override paint(..) - instead override paintComponent(..) and immediately call super.paintComponent(..);" It seems like adding this one line "super.paint(g);" to the paint method solves the problem here, do you still suggest doing it as you mentioned? Is it faster this way? btw, you can post the reply to this as the answer and I'll accept it :p – NerdOnline Jan 26 '15 at 08:56

1 Answers1

4
class frame1 extends JPanel  {
    frame1(){
        super();
    }

    public void paint(Graphics g){
    }
}

Should be:

// Should be called a Panel (since it is one) and use correct case
class Panel1 extends JPanel  {
    Panel1(){
        super();
    }

    // The method to override for custom painting in ANY JComponent
    @Override // handy to check we got the method signature right
    public void paintComponent(Graphics g){
        // paints the background, borders etc.
        super.paintComponent(g);
        // all custom drawing AFTER this line..
    }
}

It seems like adding this one line super.paint(g); to the paint method solves the problem here, do you still suggest doing it as you mentioned?

Yes.

Is it faster this way?

Yes. If only for the fact that you still have to change the method in code and recompile/build the project into something that will render reliably, without strange artifacts. That may be painting correctly for you, now, but it is purely by chance.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433