JFrame与背景图像和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和像Singleplayer等的按钮。我是否必须设置一个布局,或者没有一个布局。 我刚开始使用GUI,你可以从代码中假设。 提前致谢…

我是否必须设置布局,或者没有布局

作为一般的经验法则,是的,您应该尽可能使用布局管理器,从长远来看,它将为您节省大量的工作。

基于你的代码和我想你想做的事情,我建议你看看:

  • 在容器中布置组件
  • 如何使用GridBagLayout
  • 如何使用CardLayout

作为补充建议:

  • 不要使用null布局,像素完美布局是现代ui设计中的错觉。 影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来纠正
  • 不要引用src ,一旦导出程序就不存在。 尝试并避免使用绝对路径,因为不同的计算机会将您的程序放在不同的位置(并非所有操作系统都有驱动器号的概念)。 相反,在你的情况下,你应该使用类似getClass().getResource("/Testumgebung/background/battleship_main.jpg")东西getClass().getResource("/Testumgebung/background/battleship_main.jpg")
  • 作为一般规则,您应该在执行任何自定义绘制之前调用super.paintComponent
  • 为了显示您的背景,添加到其中的所有组件都应该是透明的( setOpaque(false) ),以便后台可以显示。
  • 将您的class级分成责任范围。 例如, Panel除了管理背景图像之外什么都不做,不应该管理任何其他内容,这意味着将Gui作为单独的步骤添加到Panel ,而不是Panel初始化的一部分

作为一个概念的例子……

是自由的

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