这几天在写五子棋的java程序,当我写完了界面(有棋盘,有按钮)以及编写了基本程序及AI后,我发现自己对于这个界面不是很满意。如图:
界面是橘色的背景,用drawline画的棋盘,画出来的黑白子,以及上方的按钮,很明显,这里采用了一个边框布局。这不是我想要的最终效果。
首先解决背景的问题,大概有两种方法解决这个问题:1、获取一张照片把它放在最底层的容器,然后把它上方的容器设置为透明。2、在paint方法(画面重绘)中画上我想要的背景图。
我最初采用了方法二,这个方法的好处是很方便,两条语句可以解决问题。
ImageIcon img = new ImageIcon("C:\\Users\\mayifan\\Desktop\\timg.jpg");
g.drawImage(img.getImage(), 0, 0, 1000, 750, null);
ImageIcon img1 = new ImageIcon("C:\\Users\\mayifan\\Desktop\\muban.jpg");//加载图片,绘制图片
g.drawImage(img1.getImage(), 145, 70, 550, 550, null);
第一条语句,获取照片的地址,第二条语句可以设置图片的位置和大小。但是在我初始化界面的时候按钮是单独设置了容器的,放在了界面的上方,我们画的背景图片只能放在中间的容器,达不到我想要的效果,故我决定采用方法一,索性修改一下界面的布局。我选择把图片作为背景放入图层的最底部。
javax.swing.JFrame jf = new javax.swing.JFrame();
ImageIcon img = new ImageIcon("E:\\workspace\\mayifan\\src\\com\\myf\\gobang1030\\timg.jpg");
JLabel jla = new JLabel(img);
jf.getLayeredPane().add(jla, new Integer(Integer.MIN_VALUE));
jla.setBounds(0, 0, 950, 640);
JPanel jp1 = (JPanel) jf.getContentPane();
jp1.setOpaque(false);
这里一段代码值得解读,JPanel jp1 = (JPanel) jf.getContentPane();这里为jf1来初始化一个容器,如果在后面加上add即可为容器添加一些组件。
jf.getLayeredPane().add(jla, new Integer(Integer.MIN_VALUE));这句代码是为了使jf获取底层容器,并为它添加图片对象。
jf.setSize(950, 640);
//jf.getContentPane().setBackground(Color.ORANGE);//设置背景色
jf.setTitle("五子棋");
jf.setDefaultCloseOperation(3);
// 设置居中显示
jf.setLocationRelativeTo(null);
DrawMouse mouse = new DrawMouse();
基本配置界面的尺寸,设置背景,标题等参数(这篇博客我们主要介绍界面的优化,五子棋的代码我之后再发文详解)。
JButton jb1=new JButton("新游戏");
jf.add(jb1);
jb1.setBounds(675, 185, 100,40);
jb1.addActionListener(mouse);
JButton jb2=new JButton("悔棋");
jf.add(jb2);
jb2.setBounds(675, 265, 100,40);
jb2.addActionListener(mouse);
JButton jb3=new JButton("人机对战");
jf.add(jb3);
jb3.setBounds(675, 345, 100,40);
jb3.addActionListener(mouse);
这是关于按钮的设置,我通过setBounds容任意配置按钮位置。这里读者可以发现,我放弃了原先的边框布局形式,而主动去配置按钮坐标,这里用到了“空布局”的思想。
我们还需要绘制相应棋盘,我的棋盘背景取材于图片,并用drawLine的思想为其绘制棋谱。
public void paint (Graphics g)
{
super.paint(g);
ImageIcon img = new ImageIcon("E:\\workspace\\mayifan\\src\\com\\myf\\gobang1030\\muban.jpg");//加载图片,绘制图片
g.drawImage(img.getImage(), 175, 80, 455, 455, null); //设置图片大小和位置
for(int i=0;i<LINE;i++)//绘制棋盘线
{
g.drawLine(X0, Y0+i*SIZE, X0+(LINE-1)*SIZE, Y0+i*SIZE);
g.drawLine(X0+i*SIZE, Y0, X0+i*SIZE, Y0+(LINE-1)*SIZE);
}
g.drawLine(X0-10,Y0-10,X0+(LINE-1)*SIZE+10,Y0-10);//画棋盘边框
g.drawLine(X0-10,Y0+(LINE-1)*SIZE+10,X0+(LINE-1)*SIZE+10,Y0+(LINE-1)*SIZE+10);
g.drawLine(X0-10,Y0-10,X0-10,Y0+(LINE-1)*SIZE+10);
g.drawLine(X0+(LINE-1)*SIZE+10,Y0-10,X0+(LINE-1)*SIZE+10,Y0+(LINE-1)*SIZE+10);
for(int i=0;i<mouse.index;i++) //棋子恢复的代码
{
Shape shape=arrayshape[i];
if(shape!=null)
{
shape.drawShape(g);
}
else
break;
}
}
我们来看这段代码,super.paint(g);即调用父类方法,是因为我们在这里对方法做了重写。这样我们的棋盘的绘制就完成了,即便最小化窗口并打开,棋盘和棋子也不会消失。我们来看一下最终效果。
构图是不是比之前文艺了很多呢!