带有背景图像和 JPanel 的 JFrame [英] JFrame with Background Image and a JPanel

查看:37
本文介绍了带有背景图像和 JPanel 的 JFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下:

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

}
}

我只想要一个带有 BackgroundImage 和 Singleplayer 等按钮的 MainMenu.我是否必须设置 Layout 或者是否可以不设置.我刚开始使用 GUI,您可能可以从代码中假设.提前谢谢...

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:

作为补充建议:

  • 不要使用 null 布局,像素完美的布局是现代 ui 设计中的一种错觉.影响组件单个尺寸的因素太多,您无法控制.Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正
  • 永远不要引用src,一旦程序导出,它就不会存在了.尽量避免使用绝对路径,因为不同的计算机会将您的程序放置在不同的位置(并且并非所有操作系统都有驱动器号的概念).相反,在您的情况下,您应该使用类似 getClass().getResource("/Testumgebung/background/battleship_main.jpg")
  • 作为一般规则,您应该在执行任何自定义绘画之前调用 super.paintComponent.
  • 为了让您的背景显示出来,添加到其中的所有组件都应该是透明的 (setOpaque(false)),这样背景才能显示出来.
  • 将您的课程划分为责任区域.例如 Panel 应该只管理背景图像而不应该管理其他任何东西,这意味着将 Gui 添加到 Panel作为一个单独的步骤,而不是 Panels 初始化的一部分
  • 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 Panels 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);
        }

    }

}

这篇关于带有背景图像和 JPanel 的 JFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆