如何将两个扩展的JPanel类加载到一个JFrame?

时间:2014-01-08 04:07:04

标签: java image swing jpanel paint

我要用Java制作游戏,我的游戏会有一个菜单。菜单有一个背景和2个JLabel个对象。我把它们放在单独的类上,传递给一个JFrame。我的问题是,我在一个框架上加载了其中两个,但其中一个总是被另一个框架隐藏。

这是代码:

JFrame类

@SuppressWarnings("serial")
public class Sistem extends JFrame{
private final int lebar=954;
private final int tinggi=540;
private Image bg;
File gbr=new File("res/a.jpg");

public Sistem(){
    this.setTitle("Unknown man Unkown power");
    this.setSize(new Dimension(lebar,tinggi));
    this.setFocusable(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.setContentPane(new Ngrep());
    //this.setContentPane(new Menu());


    this.setVisible(true);
    //loadfont();
    //loadbg();

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            new Sistem();
        }
    });
}

}

背景课程

@SuppressWarnings("serial")
public class Ngrep extends JPanel{
private int l=954;
private int t=540;
private BufferedImage bg;
File gbr=new File("res/a.jpg");

public Ngrep(){
    loadbg();

}

private void loadbg() {
    // TODO Auto-generated method stub
    try {
        bg=ImageIO.read(gbr);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public void paint(Graphics g) {
    // TODO Auto-generated method stub
    super.paint(g);
    g.drawImage(bg, 0, 0, l, t, null);
}

}

菜单类

@SuppressWarnings("serial")
public class Menu extends JPanel implements Runnable,KeyListener{
private int l=954;
private int t=540;
JLabel menu1=new JLabel("MULAI BARU");
JLabel menu2=new JLabel("KELUARRR");
private File fo=new File("res/Mawns.ttf");
JLayeredPane p=new JLayeredPane();

public Menu(){
    loadfont();

    this.add(menu1);
    this.add(menu2);
}


public void loadfont(){
    try {
        FileInputStream fi=new FileInputStream(fo);
        Font f=Font.createFont(Font.TRUETYPE_FONT, fi).deriveFont(Font.TRUETYPE_FONT, 30);
        GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();

        ge.registerFont(f);

        menu1.setFont(f);
        menu2.setFont(f);

    } catch (Exception ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
    }
    p.setLayout(new GridLayout(2, 3));

    menu1.setBounds(0, 0, getWidth(), getHeight());
    menu2.setBounds(0, 0+menu1.getHeight(), getWidth(), getHeight());

    p.add(menu1, 2);
    p.add(menu2, 2);
}


}

我想要的是菜单在背景前面,但仍然可以看到背景。以及如何安排我创建的JLabel以屏幕为中心。

如何实现所需的布局?

3 个答案:

答案 0 :(得分:3)

public class Ngrep extends JPanel{

请注意,由于Ngrep JPanel,您可以直接向其添加组件,从而使Menu类成为冗余。

在此SSCCE中看到的东西。

Sistem preview

请注意,我最终进行了如此多的更改,因此无法明确记录大部分内容。仔细查看代码,根据原始代码进行检查,检查Java Docs,如果有任何不明白的变化,请问我。

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.URL;
import javax.imageio.ImageIO;

@SuppressWarnings("serial")
public class Sistem extends JFrame {

    public Sistem() {
        this.setTitle("Unknown man Unkown power");
        this.setFocusable(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setContentPane(new Ngrep());
        this.setResizable(false);
        this.pack();

        this.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Sistem();
            }
        });
    }
}

@SuppressWarnings("serial")
class Ngrep extends JPanel {

    private int l = 375;
    private int t = 150;
    private BufferedImage bg;
    JLabel menu1 = new JLabel("MULAI BARU");
    JLabel menu2 = new JLabel("KELUARRR");

    public Ngrep() {
        this.add(menu1);
        this.add(menu2);

        try {
            Font f = new Font(Font.MONOSPACED, Font.ITALIC, 30);
            menu1.setFont(f);
            menu1.setForeground(Color.RED);
            menu2.setFont(f);
            menu2.setForeground(Color.RED);
            URL url = new URL("http://i.stack.imgur.com/OVOg3.jpg");
            bg = ImageIO.read(url);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        setLayout(new GridLayout(2, 3));

        add(menu1);
        add(menu2);
    }

    public Dimension getPreferredSize() {
        return new Dimension(l, t);
    }

    /*
     * For a JComponent, override paintComponent rather than paint
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // a JPanel IS AN ImageObserver
        g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
    }
}

答案 1 :(得分:2)

首先使用JFrame#add代替JFrame#setContentPane,除非您打算向该(内容)窗格添加更多组件。

默认情况下,JFrame会为BorderLayout使用LayoutManager。您需要将其更改为您喜欢使用的内容或将每个组件添加到BorderLayout

中的适当位置

有关详细信息,请参阅Laying Out Components Within a Container

答案 2 :(得分:0)

解决了,因为我发现我使用paint()而不是paintComponent()。 像这样:

@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.drawImage(bg, 0, 0, l, t, this);
}

到此:

@Override
public void paintComponent(Graphics g) {
// TODO Auto-generated method stub
super.paintComponents(g);

g.drawImage(bg, 0, 0, l, t, this);
}