1

JButton and JLabel disappears when adding custom background. I don't see any problems in my program, but maybe you guys find an solution! I think it's only a little thing I forgot, but I can't figure it out.

Here's the code:

GameWindow.java:

setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");

The background appears perfect, but not the JButton and JLabel!

Code to the StartImagePanel.java:

public class StartImagePanel extends JComponent{
    private Image image;
    public StartImagePanel(Image image) {
        this.image = image;
    }
    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null);
    }
}
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
joapet99
  • 143
  • 8
  • `setContentPane(new StartImagePanel(..` For better help sooner, post an [SSCCE](http://sscce.org/). For the image, just create one in code, as seen in [this answer](http://stackoverflow.com/questions/14979647/background-image-hides-all-gui-design-components/14980180#14980180). – Andrew Thompson Feb 21 '13 at 13:10
  • Any chance of seeing that SSCCE soon, or do you intend to waste more time forcing people to guess why the code is broken? – Andrew Thompson Feb 21 '13 at 13:38
  • Sorry, but I don't know what to do for making this an SSCCE – joapet99 Feb 21 '13 at 13:54
  • 2
    @joapet99 You do exactly what that link tells you to do. Keep removing unnecessary code until you are only left with the problematic, buggy code. Then post the simplified, buggy program so that others don't have waste so much time finding the bug. They did it anyways this time, but next time it'll help if you can help others do less work :) – wrongusername Feb 22 '13 at 01:01
  • @AndrewThompson Is the new edited version I have added better? – joapet99 Mar 01 '13 at 16:43
  • *"Is the new edited version .. better?"* The term 'better' is subjective, so I cannot (or at least will not) say. OTOH it is still *not an SSCCE.* – Andrew Thompson Mar 01 '13 at 16:47
  • What is the problem now?? – joapet99 Mar 01 '13 at 16:49

2 Answers2

2

Your button and label are added to your GameWindow frame while they should be added to its contentPane, setContentPane(new StartImagePanel(RollrackLogo)); instead. That's why they are not showing, they are added to the frame.

Make a variable of the StartImagePanel and add the button and label to it and they should show up.

StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);

...

out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");

Answer dispute

The claims in the first paragraph are plain wrong. Here is source that proves it.

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class AddToCustomContentPane {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                // the GUI as seen by the user (without frame)
                JPanel gui = new JPanel(new FlowLayout());
                gui.setBorder(new EmptyBorder(2, 3, 2, 3));
                gui.setBackground(Color.RED);

                JFrame f = new JFrame("Demo");
                f.setContentPane(gui);

                // Acid test.  Can we add buttons direct to the frame?
                f.add(new JButton("Button 1"));
                f.add(new JButton("Button 2"));

                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

Edit after the custom panel code was given

Here's a snippet that works to show both button and label on a black image background, I removed that was not needed (listeners).

public static void main(String[] v) {

class StartImagePanel extends JPanel {
  private Image image;
  public StartImagePanel(Image image) {
      this.image = image;
  }
  @Override
  protected void paintComponent(Graphics g) {
    g.drawImage(image, 0, 0, null);
  }
}

class GameWindow extends JFrame{
  public GameWindow() {
    BufferedImage RollrackLogo;
    RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
    final JButton JBRandom = new JButton();
    final JLabel JLWelcome = new JLabel();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    StartImagePanel panel = new StartImagePanel(RollrackLogo);
    setContentPane(panel);
    setExtendedState(MAXIMIZED_BOTH);
    setVisible(true);
    JLWelcome.setText("Welcome to Rollrack");
    panel.add(JLWelcome);
    JLWelcome.setVisible(true);
    JBRandom.setText("Random");
    panel.add(JBRandom);
    JBRandom.setVisible(true);
  }
}

GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}
Jonathan Drapeau
  • 2,610
  • 2
  • 26
  • 32
  • I tried it and it did nothing... I think! Do it have something to say if the background is not transparent? – joapet99 Feb 21 '13 at 13:32
  • 2
    See the edit after **Answer dispute** to see why I disagree with your technical points. Note this might be better taken up on a separate question, but in plain terms. You're wrong. Even after a custom content pane has been set, if we `add` components to the frame, they will end up in the custom content pane so long as it has an appropriate layout. That leads me to repeat to the OP.. (slightly louder this time) *For better help sooner, post an [SSCCE](http://sscce.org/).* – Andrew Thompson Feb 21 '13 at 13:37
  • Ohh. How do I create an SSCCE? – joapet99 Feb 21 '13 at 13:45
  • @AndrewThompson I agree with you that it's possible to add them to the frame directly but it does work to add them to the contentPanel instead. I disagree that I'm wrong, I gave a different solution. – Jonathan Drapeau Feb 21 '13 at 14:01
  • @AndrewThompson I haven't tried your solution, but I think setBackground only can set color not image – joapet99 Feb 21 '13 at 14:11
  • @joapet99 It works, I can easily make a button and label visible in a panel within a frame but to help you, we would need more informations, especially your `StartImagePanel` since it might not work to add them to your panel if the image is over the label and button. – Jonathan Drapeau Feb 21 '13 at 14:13
  • @JonathanDrapeau I have added the code to the StartImagePanel in the question – joapet99 Feb 21 '13 at 14:23
  • @joapet99 Have your `StartImagePanel extends JPanel` instead of `Component`. Also, take Andrew's suggestion to use layout, will help you in the long run. – Jonathan Drapeau Feb 21 '13 at 14:35
1

I rather use an instance of a JFrame, instead of extending it, as @Andrew Thompson suggested in another question.
However, if you're extending it, it might be a good practice to call super() in the constructor.

Additionally, we may need to know what is going on in your StartImagePanel.
It seems, to me, to be the problem.

  1. Ensure both your GameWindow and StartImagePanel extend properly their superclasses (call super();).
  2. Ensure your StartImagePanel has a proper Layout.
  3. Add your components before you set your frame visible. This also means you won't need JLWelcome.setVisible(true);.
  4. Ensure that your code is executed in the EDT (Event-Dispatch Thread).

Example:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class GameWindow extends JFrame{
    BufferedImage rollrackLogo;
    JButton jbRandom;
    JLabel jlWelcome;

    public GameWindow() {
        super();
        jbRandom = new JButton("Random");
        jlWelcome = new JLabel("Welcome to Rollrack, " +
                namewindow.name);

        rollrackLogo = new BufferedImage(400, 200,
                BufferedImage.TYPE_INT_RGB);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setContentPane(new StartImagePanel(rollrackLogo));

        // Add your components.
        add(jlWelcome);
        add(jbRandom);

        addKeyListener(new KeyListener() {
            @SuppressWarnings("static-access")
            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == e.VK_ESCAPE){
                    System.exit(7);
                }
            }

            @Override
            public void keyReleased(KeyEvent arg0) {}

            @Override
            public void keyTyped(KeyEvent arg0) {}
        });

        // Pack, or otherwise set fullscreen.
        pack();

        // Now, set frame visible.
        setVisible(true);
    }
}

Edit: Now that you've posted the code for your StartImagePanel, I see that you're extending JComponent. Follow my previous advice, (call super), set a Layout, and extend JPanel instead.

afsantos
  • 5,178
  • 4
  • 30
  • 54