Swing带背景图的窗体

转载请注明出处:http://blog.csdn.net/jiratao/article/details/38600571


背景:

正在学习Java中,要用Swing来做一个窗口,想做一个带有背景图的窗体,结果两天了还没解决


尝试:

尝试了以下方案:
1. 通过设置layeredPane
2. 通过继承自JPanel实现了自定义的ImagePanel类,重写paintComponent方法进行绘制
以上两种方案均能实现背景图,But!!!
第1种方案,无论我往ContentPane上还是LayerdPane上放任何组件,均看不见~~白瞎~
第2种方案,可以往自己的Panel对象上放组件,但是全部变形,位置变走样了,见下图
Swing带背景图的窗体_第1张图片
可以看到我的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

你可能感兴趣的:(Java)