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

2 回答 2

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);
}
于 2013-02-21T13:14:49.433 回答
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.

于 2013-02-21T14:40:58.923 回答