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

查看:129
本文介绍了具有背景图片和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,或者是否可以不设置一个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:

  • Laying Out Components Within a Container
  • How to Use GridBagLayout
  • How to Use CardLayout

作为其他建议:

  • 不要使用null布局,像素完美布局是现代ui设计中的一种幻觉.有太多因素会影响组件的单个大小,您无法控制. Swing旨在与布局管理者为核心一起工作,舍弃这些问题不会导致任何问题,而您将花费越来越多的时间进行纠正
  • 从不引用src,一旦导出程序,该引用将不存在.尽量避免使用绝对路径,因为不同的计算机会将您的程序放置在不同的位置(并非所有操作系统都具有驱动器号的概念).相反,在您的情况下,您应该使用类似getClass().getResource("/Testumgebung/background/battleship_main.jpg")
  • 的名称
  • 作为一般规则,您应该在执行任何自定义绘画之前调用super.paintComponent.
  • 为了显示背景,应将添加到背景中的所有组件透明化(setOpaque(false)),以便背景可以显示出来.
  • 将您的课程分为责任领域.例如,Panel除了管理背景图像外什么都不要做,这不意味着要管理其他任何事情,这意味着将Gui作为单独的步骤添加到Panel中,而不是Panel初始化的一部分
  • 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天全站免登陆