带有背景图像和 JPanel 的 JFrame
JFrame with Background Image and a JPanel
我有以下内容:
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 和按钮(如单人游戏等)的 MainMenu。我是否必须设置 Layout 或者是否可以不设置 Layout。我刚开始使用 GUI,正如您可以从代码中假设的那样。提前致谢...
Do I have to set a Layout or is it possible without one
作为一般经验法则,是的,您应该尽可能使用布局管理器,它会在长期 运行.
中为您节省大量工作
根据您的代码以及我认为您想要执行的操作,我建议您查看:
作为补充建议:
- 不要使用
null
布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件个体大小的因素太多,none 是您可以控制的。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正
- 永远不要引用
src
,程序导出后它将不存在。尽量避免使用绝对路径,因为不同的计算机会将您的程序放置在不同的位置(并非所有 OS 都有驱动器号的概念)。相反,在您的情况下,您应该使用 getClass().getResource("/Testumgebung/background/battleship_main.jpg")
- 作为一般规则,您应该在执行任何自定义绘画之前致电
super.paintComponent
。
- 为了让您的背景显示出来,添加到其中的所有组件都应设为透明 (
setOpaque(false)
),这样背景才能显示出来。
- 将您的 类 划分为职责范围。例如
Panel
应该只管理背景图像而不应该管理其他任何东西,这意味着将 Gui
添加到 Panel
作为一个单独的步骤而不是Panel
s初始化
作为概念示例...
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);
}
}
}
我有以下内容:
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 和按钮(如单人游戏等)的 MainMenu。我是否必须设置 Layout 或者是否可以不设置 Layout。我刚开始使用 GUI,正如您可以从代码中假设的那样。提前致谢...
Do I have to set a Layout or is it possible without one
作为一般经验法则,是的,您应该尽可能使用布局管理器,它会在长期 运行.
中为您节省大量工作根据您的代码以及我认为您想要执行的操作,我建议您查看:
作为补充建议:
- 不要使用
null
布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件个体大小的因素太多,none 是您可以控制的。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正 - 永远不要引用
src
,程序导出后它将不存在。尽量避免使用绝对路径,因为不同的计算机会将您的程序放置在不同的位置(并非所有 OS 都有驱动器号的概念)。相反,在您的情况下,您应该使用getClass().getResource("/Testumgebung/background/battleship_main.jpg")
- 作为一般规则,您应该在执行任何自定义绘画之前致电
super.paintComponent
。 - 为了让您的背景显示出来,添加到其中的所有组件都应设为透明 (
setOpaque(false)
),这样背景才能显示出来。 - 将您的 类 划分为职责范围。例如
Panel
应该只管理背景图像而不应该管理其他任何东西,这意味着将Gui
添加到Panel
作为一个单独的步骤而不是Panel
s初始化
作为概念示例...
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);
}
}
}