简体   繁体   中英

JFrame with Background Image and a JPanel

I have the following:

public class Frame {

public static void main(String[] args) {

    JFrame frame = new JFrame("Frame Demo");

    Panel panel = new Panel();        

    frame.add(panel);        

    frame.setBounds(250,100,800,500);
    frame.setVisible(true);
}
}

public class Panel extends JPanel {

JButton singlePlayerButton;
JButton multiPlayerButton;

BufferedImage image;

Gui gui;


public Panel() {
    gui = new Gui();
    add(gui);

    try {
        image = ImageIO.read(new File("C:\\Users\\void\\workspace\\BattleShips\\src\\Testumgebung\\background\\battleship_main.jpg"));

    } catch (IOException e) {
        e.getMessage();
        e.printStackTrace();
    }

}

public void paintComponent(Graphics g) {
    g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
}


JLabel text;
JPanel mainMenuPanel;


private class Gui extends JPanel {

    public Gui() {

    setVisible(true);
    setSize(500, 300);
    setLayout(null);

    mainMenuPanel = new JPanel();

    mainMenuPanel.setLayout(null);
    mainMenuPanel.setBackground(Color.BLUE);
    mainMenuPanel.setBounds(150, 10, 200, 230);
    add(mainMenuPanel);
    mainMenuPanel.setVisible(true);


    singlePlayerButton = new JButton("Single Player");
    singlePlayerButton.setBounds(100,50 , 150, 40);

    singlePlayerButton.setVisible(true);

    mainMenuPanel.add(singlePlayerButton);

    multiPlayerButton = new JButton("Multi Player");
    multiPlayerButton.setBounds(100, 100, 150, 40);

    multiPlayerButton.setVisible(true);
    mainMenuPanel.add(multiPlayerButton);

    repaint();
}

}
}

I just want a MainMenu with a BackgroundImage and buttons like Singleplayer etc. Do I have to set a Layout or is it possible without one. I just started with GUI, as you can probably assume from the code. Thanks in advance...

Do I have to set a Layout or is it possible without one

As a general rule of thumb, yes, you should make use of a layout manager where ever it's possible, it will save you a lot of work in the long run.

Based on you code and what I presume you want to do, I would suggest having a look at:

As additional advice:

  • Don't use null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
  • Don't reference src ever, it will no exist once the program is exported. Try and avoid absolute paths as well, as different computers will place your program in different locations (and not all OS's have a concept of drive letters). Instead, in your case, you should be using something like getClass().getResource("/Testumgebung/background/battleship_main.jpg")
  • You should be calling super.paintComponent before performing any custom painting as a general rule.
  • In order for your background to show up, all components which are added to it should be made transparent ( setOpaque(false) ) so the background can show through.
  • Separate your classes into areas of responsibility. For example Panel should do nothing but manage the background image and should not be managing anything else, this would mean having the Gui added to the Panel as a separate step and not part of the Panel s initialisation

As a conceptual example...

是自由的

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Frame {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Panel background = new Panel();

                JFrame frame = new JFrame("Testing");
                frame.setContentPane(background);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Gui());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class Panel extends JPanel {

        BufferedImage image;

        public Panel() {
            setLayout(new BorderLayout());
            try {
                image = ImageIO.read(getClass().getResource("/Testumgebung/background/battleship_main.png"));
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }

    }

    public static class Gui extends JPanel {

        private MainMenuPane mainMenuPane;
        private CardLayout cardLayout;

        public Gui() {

            setOpaque(false);

            setVisible(true);
            cardLayout = new CardLayout();
            setLayout(cardLayout);

            mainMenuPane = new MainMenuPane();
            // Other views

            add(mainMenuPane, "MainMenu");

            cardLayout.show(this, "MainMenu");

        }

    }

    public static class MainMenuPane extends JPanel {

        JButton singlePlayerButton;
        JButton multiPlayerButton;

        JLabel text;

        public MainMenuPane() {

            setLayout(new GridBagLayout());
            setOpaque(false);
            setBackground(Color.BLUE);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.ipadx = 20;
            gbc.ipady = 20;

            singlePlayerButton = new JButton("Single Player");

            add(singlePlayerButton, gbc);

            multiPlayerButton = new JButton("Multi Player");

            add(multiPlayerButton, gbc);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // This is faking transparency, so the background color
            // will be see through
            Graphics2D g2d = (Graphics2D) g.create();
            Composite old = g2d.getComposite();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.setComposite(old);
        }

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM