转载请注明出处:http://blog.csdn.net/jiratao/article/details/38600571
背景:
正在学习Java中,要用Swing来做一个窗口,想做一个带有背景图的窗体,结果两天了还没解决
尝试:
尝试了以下方案:
1. 通过设置layeredPane
2. 通过继承自JPanel实现了自定义的ImagePanel类,重写paintComponent方法进行绘制
以上两种方案均能实现背景图,But!!!
第1种方案,无论我往ContentPane上还是LayerdPane上放任何组件,均看不见~~白瞎~
第2种方案,可以往自己的Panel对象上放组件,但是全部变形,位置变走样了,见下图
可以看到我的label选中了,在右边,但是实际显示的位置却在左边。
原因:
后来调试的时候发现第2种方案出现走样的原因:
因为我的背景图比较大,所以我是做了缩放处理的,当我去除缩放绘制的代码时,组件就正常了,但是这和我的需求不一样,我必须要能缩放背景图,但是不能影响添加的组件啊。
最终解决方案:
想来想去,我只能想到先放一个Panel做背景图,再覆盖一层透明的Panel来添加组件了。
可是Swing怎么能做到Panel的覆盖呢?没有哪种布局管理器能满足我的需求啊。。
后来一想,我好笨啊,,我的Frame的布局设置为绝对布局,然后不就可以弄两个覆盖Panel了嘛!!
想到就做,弄了两个Panel,一个bgPanel,是自定义ImagePanel的对象,用来绘制背景图,一个mainPanel,用来容纳组件,用绝对布局设置其位置。
注意这里:要把bgPanel放到mainPanel之后添加才能看到mainPanel,很奇怪这里的顺序
当然,绝对布局不能随窗体大小改变,所以这里我们需要处理componentResized事件,在其中:
bgPanel.setSize(frame.getContentPane().getWidth(), frame.getContentPane().getHeight());
MainPanel.setSize(frame.getContentPane().getWidth(), frame.getContentPane().getHeight());
这样,窗体变化时,我们的多层Panel也能跟随变化了。
终于解决这几天困扰了我很久的问题~~~太辛苦了。
附上关键部分代码:
MImagePanel类
public class MImagePanel extends JPanel {
private static final long serialVersionUID = 3602544785116642939L;
private ImageIcon imageIcon = null;
public MImagePanel(URL imgUrl) {
super();
imageIcon = new ImageIcon(imgUrl);
}
@Override
protected void paintComponent(Graphics g) {
// TODO 自动生成的方法存根
super.paintComponent(g);
if (imageIcon != null) {
float width = this.getWidth();
float height = this.getHeight();
int iconWidth = imageIcon.getIconWidth();
int iconHeight = imageIcon.getIconHeight();
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.scale(width / iconWidth, height / iconHeight);
g2d.drawImage(imageIcon.getImage(), 0, 0, null);
}
}
}
public class JLoginWindow {
private JFrame frame;
private JTextField textField;
private JPasswordField passwordField;
private MImagePanel bgPanel;
private JPanel MainPanel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JLoginWindow window = new JLoginWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JLoginWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
bgPanel.setSize(frame.getContentPane().getWidth(), frame.getContentPane().getHeight());
MainPanel.setSize(frame.getContentPane().getWidth(), frame.getContentPane().getHeight());
}
});
frame.setTitle("\u9910\u996E\u7BA1\u7406\u7CFB\u7EDF");
frame.setBounds(0, 0, 600, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MainPanel = new JPanel();
MainPanel.setLocation(0, 0);
MainPanel.setOpaque(false); // 设置Panel透明
frame.getContentPane().add(MainPanel);
MainPanel.setBorder(new LineBorder(Color.RED, 3));
MainPanel.setLayout(new BoxLayout(MainPanel, BoxLayout.X_AXIS));
MainPanel.setSize(584, 361);
MainPanel.add(Box.createHorizontalGlue());
JPanel panelLogin = new JPanel();
panelLogin.setOpaque(false);
MainPanel.add(panelLogin);
panelLogin.setLayout(new GridLayout(3, 0, 0, 0));
JPanel panelBlank = new JPanel();
panelLogin.add(panelBlank);
panelBlank.setOpaque(false);
JPanel panelNamePwd = new JPanel();
panelLogin.add(panelNamePwd);
panelNamePwd.setOpaque(false);
panelNamePwd.setLayout(new GridLayout(5, 2, 0, 0));
JLabel label_2 = new JLabel("");
panelNamePwd.add(label_2);
JLabel label_3 = new JLabel("");
panelNamePwd.add(label_3);
JLabel label = new JLabel("\u7528\u6237\u540D");
panelNamePwd.add(label);
textField = new JTextField();
panelNamePwd.add(textField);
textField.setColumns(10);
JLabel label_1 = new JLabel("\u5BC6\u7801");
panelNamePwd.add(label_1);
passwordField = new JPasswordField();
panelNamePwd.add(passwordField);
JPanel panelBtns = new JPanel();
panelLogin.add(panelBtns);
panelBtns.setOpaque(false);
panelBtns.setLayout(new BoxLayout(panelBtns, BoxLayout.X_AXIS));
JButton btnLogin = new JButton("\u767B\u5F55");
panelBtns.add(btnLogin);
JButton btnReset = new JButton("\u91CD\u7F6E");
panelBtns.add(btnReset);
/**
* 创建带背景图片的Panel
* ps. 要把背景Panel放到主Panel下才能看到主Panel,比较奇怪
*/
frame.getContentPane().setLayout(null);
bgPanel = new MImagePanel(
JLoginWindow.class.getResource("/img/pic3.jpg"));
bgPanel.setBounds(0, 0, 584, 361);
frame.getContentPane().add(bgPanel);
}
}
转载请注明出处:http://blog.csdn.net/jiratao/article/details/38600571