Java学习笔记之SWING -- 基本SWING程序(地图编辑器框架大致效果完成)

前言:本来想这次就把地图导入还有输出就直接做掉的,但是自己起床晚了,后来想想反正JMenu还没说呢,索性就这次添加一个中间的项目,把JMenu加上,不过也没多少内容。上一篇里说道我们要研究下这个地图存储的格式问题的。其实个人感觉考虑哈夫曼(Huffman)树是最好的解决方案,但是对于没有学过《数据结构》的人来说单单这个问题要讲透搞懂就要好久 时间,而且还要专门写关于Huffman的类,而且自己也有点懒惰,嘿嘿。所以这里就用一个简单的方法来说明。这次加图片说明,嘿嘿(做了很烂望包含),好了,说了这么多,看思路吧

其实一个地图编辑器少不了的就是些添加修改地图的功能,当然最好不要都直接做到按钮去,这样整个程序界面估计会给JButton给占据掉的,所以一个菜单还是必不可少的。这次就讲讲JMenuBar,JMenu和它的Item:JMenuItem。

JMenu,从字面意思就直到是菜单控件,以前做MFC的肯定知道ToolBar,也就是工具栏咯,那么这里的JMenuBar就是菜单栏了,而JMenu是其中的菜单项,而JMenuItem是点击JMenu后的下拉菜单项,那么到底是什么效果呢?带菜单的JMenuBar 

看到了吧,这个就是整个菜单栏,“文件”和“编辑”这两个是JMenu控检,而“载入地图”和“退出”是JMenuItem控件,而有JMenu所在的整个横条就是JMenuBar了,呵呵。

JMenuItem也有其addActionListener的注册方法,而且在响应函数中和JButton的做法和效果是一致的,所以可以看到退出其实可以和下面的OK的JButton响应为同一个System.exit(0)。

下面讲讲具体的添加方法。首先定义一个JMenu,一个JMenuItem,一个JMenuBar,这样是最简陋的,调用JMenu的add方法,把这个JMenuItem加进去,然后再调用JMenuBar的add方法把这个JMenu加进去,最后调用JFrame的setMenuBar(JMenuBar的实例)就可以了。代码最后公布。

现在讲讲地图的问题。我是用Jcreatro Pro做的,而且建立了一个工程,其实没关系的,你用记事本也一样,大不了全编译过来然后对总的class文件进行运行就行了,没什么本质区别。所以下面我的代码是分蛮多java文件的,但是只要你放在同一个文件夹下就没什么问题。

首先讲下下我自己的思路吧,有建议的朋友快M我,不然我就真的照着这个自己的思路发展下去了咯。因为考虑到地形一般不会多于50个,所以用字母就可以表示52个地形,那地图文件里面就都是些字母了,呵呵。(其实这个是手工写地图要考虑的问题,用地图编辑器就不需要知道到底地图文件是怎么表示的)为此我们需要一个放地图图片的数组,还有一个记录地图信息的数据结构。本着OO的思想,我为他们分别做了两个类,一个叫LandStylePic,一个叫MapsConstruction。

先说说MapsConstruction类。它有四个成员变量:

private   int  index;         //  在LandStyle中的地图样式
private   char  mapsMark;         //  存储或者读取时所表示的字符
private  String landStyleName;     //  地形的名字
private  String info;                          //  对此地形的描述信息

还有四个方法,分别取得这四个属性:getIndex(),getName(),getInfo(),getMark()。

注意:其实这个(MapsConstruction)可以作为LandStylePic的内部类,本来就是给LandStylePic定义的数据结构。不过为了代码的测试性,我还是分开了他们。

下面给出MapsConstruction的代码:

/**
 * 一个地形存储识别的类
 *
*/


public   class  MapsConstruction  {
    
private int index;                // 在LandStyle中的地图样式
    private char mapsMark;            // 存储或者读取时所表示的字符
    private String landStyleName;    // 地形的名字
    private String info;    // 对此地形的描述信息
    
    
/**
     * Method main
     *
     *
     * 
@param args
     *
     
*/

    
public static void main(String[] args) {
        
// TODO: 在这添加你的代码
    }


    
/**
     * Method MapsConstruction
     *
     * 
@param index, mapsMark, name, info
     *
     
*/

    
public MapsConstruction(int index, char mapsMark, String name, String info) {
        
// TODO: 在这添加你的代码
        this.index = index;
        
this.mapsMark = mapsMark;
        
this.landStyleName = name;
        
this.info = info;
    }


    
/**
     * Method getIndex
     *
     *
     * 
@return
     *
     
*/

    
public int getIndex() {
        
// TODO: 在这添加你的代码
        return index;
    }


    
/**
     * Method getMarks
     *
     *
     * 
@return
     *
     
*/

    
public char getMarks() {
        
// TODO: 在这添加你的代码
        return mapsMark;
    }


    
/**
     * Method getName
     *
     *
     * 
@return
     *
     
*/

    
public String getName() {
        
// TODO: 在这添加你的代码
        return this.landStyleName;
    }
    
    
        
/**
     * Method getInfo
     *
     *
     * 
@return
     *
     
*/

    
public String getInfo() {
        
// TODO: 在这添加你的代码
        return this.info;
    }
    
}

 

LandStylePic中有一个静态的ImageIcon数组,负责存储外部的地图文件。其中有专门负责存储相应的地图信息的MapsConstruction数组,以及两个getIndex的查询方法(考虑到数组不会太大,所以就逐个比较吧),分别对应对地图名字和地图的表示符号的查询返回对应的ImageIcon,前者在手动编辑地图时用到,后者则在读入地图文件以及输出地图文件时极为有用!给出代码

/**
 * 记录地图类型存储的类
 *
 *
*/

import  javax.swing.ImageIcon;
import  java.util. * ;

public   final   class  LandStylePic  {
    
// 存放地形图形的数组
    public final static ImageIcon[] LANDSTYLES = {
        
new ImageIcon("../mapResource/water/water_left.PNG"),
        
new ImageIcon("../mapResource/water/water_middle.PNG"),
        
new ImageIcon("../mapResource/water/water_right.PNG"),
        
new ImageIcon("../mapResource/water/water_blue.PNG"),
    }
;
    
    
// 存放地形相关信息的数据结构的数组
    public final static MapsConstruction[] MAPCONS = {
        
new MapsConstruction(0'A'"water_left"
                
"水地形的左边部分,两栖物种以及飞行物种可登陆"),
        
new MapsConstruction(1'B'"water_middle",
                
"水地形的中间部分,两栖物种以及飞行物种可登陆"),
        
new MapsConstruction(2'C'"water_right",
                
"水地形的右边部分,两栖物种以及飞行物种可登陆"),
        
new MapsConstruction(3'D'"water_blue",
                
"水地形的反光部分,两栖物种以及飞行物种可登陆"),
    }
;
    
/**
     * Method main
     *
     *
     * 
@param args
     *
     
*/

    
public static void main(String[] args) {
        
// TODO: 在这添加你的代码
    }


    
/**
     * Method getIndex
     *
     *
     * 
@param name
     *
     * 
@return
     *
     
*/

    
public static int getIndex(String name) {
        
// TODO: 在这添加你的代码
        for(int i = 0; i < MAPCONS.length; i++{
            
if( name.equals( MAPCONS[i].getName() ) )
            
{
                
return MAPCONS[i].getIndex();
            }

        }

        
return -1;
    }


    
/**
     * Method getIndex
     *
     *
     * 
@param mark
     *
     * 
@return
     *
     
*/

    
public static int getIndex(char mark) {
        
// TODO: 在这添加你的代码
        for(int i = 0; i < MAPCONS.length; i++{
            
if ( mark == MAPCONS[i].getMarks() ) {
                
return MAPCONS[i].getIndex();
            }

        }

        
return -1;
    }
    
}

注意到LANDSTYLES和MAPCON这两个数组是一一对应的,MAPCON的getIndex所得到的就是在LANDSTYLES中的索引。这个文件要自己手动添加。

好了,最后给出主程序的代码。分两个文件,一个是Frame,而另一个是调用这个Frame并且显示,完全可以放到一起来做的。里面的东西大家就自己分析分析看看,然后自己写一个出来,嘿嘿。很有意思的哟~

e.g. :

import  java.awt. * ;
import  java.awt.event. * ;
import  javax.swing. * ;
import  java.util. * ;

/**
 * Sample application using JFrame.
 *
 * 
@author SosoAyaen
 * 
@version 1.00 06/08/10
 
*/

public   class  MapsEditorFrame  extends  JFrame  implements  ActionListener {
   
    
// 容器组件等
    private JButton jbOK = null, jbCancel = null, jbIcon = null,
                    jbSave 
= null, jbLoadMapFromFile = null;
    
private JPanel jpCenter = null, jpIcon = null, jpSouth = null,
                    jpNorth 
= null, jpEast = null, jpEastCo = null;
    
private JLabel jlMap = null, jlTitle = null, jlTips = null;
    
private JMenu jmenu = null;
    
private JMenuItem jmiExit = null;
    
private JMenuBar jmb = null;
    
    
private JTextField jtf = null;
    
private int change = 1;            // 控制点击同一按钮后控制不同控件
    
    
// 临时测试用的地图文件数组
    private char[] maps = {
        
'A''B''C''A''A''A''D''D''B''D',
    }
;
    
    
// 随机数
    private Random rand = new Random();
    
private final int WIDTH = 12, HEIGHT = 4;
    
// private Dimension d = null;
    
     
/**
     * The constructor.
     
*/
  
    
public MapsEditorFrame (String title) {
        
super(title);
        
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
// d = new Dimension(11, 20);
        
        
// JMenu
        JMenu jmFile = new JMenu("文件");
        
// 临时定义组件
        JMenuItem jmiLoad = new JMenuItem("载入地图");
        jmiLoad.addActionListener(
this);
        jmFile.add(jmiLoad);
        
        jmiExit 
= new JMenuItem("退出");
        jmiExit.addActionListener(
this);
        
        jmFile.add(jmiExit);
        
        JMenu jmEdit 
= new JMenu("编辑");
        JMenuItem jmiUndo 
= new JMenuItem("撤销");
        jmEdit.add(jmiUndo);
        
        
// JMenuBar
        jmb = new JMenuBar();
        jmb.add(jmFile);
        jmb.add(jmEdit);
        
this.setJMenuBar(jmb);
        
        
// JTextField
        jtf = new JTextField(10);
        jtf.setEditable(
false);
        
        
// JLabel
        
// jlMap = new JLabel(mapsWater[0]);
        jlTitle = new JLabel("SLG地图编辑器");
        jlTips 
= new JLabel();
        
        
// JButton
        jbLoadMapFromFile = new JButton("Load Maps");
        jbLoadMapFromFile.addActionListener(
this);
        jbSave 
= new JButton("Save Maps");
        jbSave.addActionListener(
this);
        jbOK 
= new JButton("OK");
        
// jbOK.setMaximumSize(new Dimension(6, 12));
        jbOK.addActionListener(this);
        
        
// jbOK.setSize(d);
        jbCancel = new JButton("Cancel");
        jbCancel.setEnabled(
false);        
        jbIcon 
= new JButton("WaterMiddle"
            LandStylePic.LANDSTYLES[LandStylePic.getIndex(
"water_right")]);
        
        
// JPanel
        jpSouth = new JPanel(new FlowLayout());
        jpSouth.add(jbOK);
        jpSouth.add(jbCancel);
            
        jpNorth 
= new JPanel(new FlowLayout());
        jpNorth.add(jlTitle);
            
        jpEast 
= new JPanel(new GridLayout(0,1));
        
        jpEastCo 
= new JPanel(new FlowLayout());
        jpEastCo.add(jbIcon);
        jpEast.add(jpEastCo);
        
        jpEastCo 
= new JPanel(new FlowLayout());
        jpEastCo.add(jbSave);
        jpEast.add(jpEastCo);
        
        jpEastCo 
= new JPanel(new FlowLayout());
        jpEastCo.add(jbLoadMapFromFile);
        jpEast.add(jpEastCo);
        
        jpEastCo 
= new JPanel(new FlowLayout());
        jpEastCo.add(jtf);
        jpEast.add(jpEastCo);
        
        jpEastCo 
= new JPanel(new FlowLayout());
        jpEastCo.add(jlTips);
        jpEast.add(jpEastCo);
                
        jpIcon 
= new JPanel(new GridLayout(HEIGHT,WIDTH,0,0));
        
/*
        for(int i = 0, j = 0; i<HEIGHT*WIDTH; i++)
        {
            j = rand.nextInt(4);
            jlMap = new JLabel(LandStylePic.LANDSTYLES[j]);
            jpIcon.add(jlMap);
        }
        //
*/

        
        
// 按数组内容添加地图图片
        for (int i = 0; i < 10; i++{
            jlMap 
= new JLabel( LandStylePic.LANDSTYLES[LandStylePic.getIndex(maps[i])] );
            jpIcon.add(jlMap);
        }

        
// 保证jpIcon内的JLabel不会因为外部窗口的拉伸而走样
        jpCenter = new JPanel(new FlowLayout());
        jpCenter.add(jpIcon);
        
        
// JFrame
        this.setLayout(new BorderLayout());
        
this.setSize(500400);
        
this.setResizable(false);
        
this.add(BorderLayout.NORTH, jpNorth);
        
this.add(BorderLayout.SOUTH, jpSouth);
        
this.add(BorderLayout.CENTER, jpCenter);
        
this.add(BorderLayout.EAST, jpEast);
    }

    
    
/**
     * Method actionPerformed
     *
     *
     * 
@param e
     *
     
*/

    
public void actionPerformed(ActionEvent e) {
        
// TODO: 在这添加你的代码
        if (e.getActionCommand().equals("OK"))
        
{
            System.exit(
0);
        }

        
else if(e.getActionCommand().equals("Save Maps"))
        
{
            change 
*= -1;
            
if(change > 0)
            
{
                jtf.setText(
"Text测试……");
                jlTips.setText(
"");
            }

            
else
            
{
                jlTips.setText(
"Two pigs");
                jtf.setText(
"");
            }

        }

        
else if (e.getActionCommand().equals("Load Maps"|| e.getActionCommand().equals("载入地图"))
        
{
            System.out.println(
"Map loaded...");
        }

        
else if (e.getActionCommand().equals("退出"))
        
{
            System.exit(
0);
        }

    }

}

这里对于上次的文件有些许的改动,比如框架被定死了,不能拉伸啊等等,自己去发掘下不同,细细品味下(虽然我编的东西乱七八糟,没什么值得品位的 T-T)。这里定义的char的数组maps就是我们的地图格式,它的符号可以从LandStylePic定义的MapsConstruction类的数组里得到。

再给个对应的效果图:

大致的效果

这样一下后,下次终于可以讲关于文件读取和存储的问题了,要用到IO了哦~(其实这个我还没开始看,慢慢来吧,反正是读书笔记,不急不急)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值