大家好,接下来的部分可能有点乱,但是并不复杂,我希望我能尽量给大家捋清楚思路。
老套路,这是我的前两篇系列,需要的同学了解一下: JAVA写文本编辑器(二)JAVA写文本编辑器(一)
下面我们要实现的是一个点击选择文本格式的窗口,这里同样是要画一个窗口,跟(二)差不多。要实现的功能呢,主要是有几个ComboBox弹出list出来,选中的属性改变下面的文本。最下面两个按钮,确定则主窗口文本改变,取消则不改变。
在这里我建议大家可以先重新开一个工程,然后一步一步的测试完成后,将代码拷回来,把main删掉就可以了。
刚刚提到的界面最上方有几个下拉框,这个需要用JComboBox实现,而内容的填充呢,需要相对应的数组。
public class about_Format extends JFrame{
private JComboBox choose_word_style;
private JComboBox choose_word_big;
private JComboBox choose_word_pattern;
private JComboBox choose_word_color;
private String[] styles = {"宋体","黑体","楷体","微软雅黑","隶书"};
private String[] colors = {"红色","蓝色","绿色","黑色","白色","黄色"};
private String[] word_big = {"2","4","8","16","24","32","64","72"};
private String[] pattern = {"常规","倾斜","粗体"};
private JPanel paneNorth;//用于装四个ComboBox
public about_Format() {
initBox();
initLocation();
this.setSize(550,200);
this.setTitle("文字格式");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
/**
* 初始化布局
* 将每个控件按照一定得布局排在this窗口中
*/
public void initLocation() {
paneNorth = new JPanel();
paneNorth.add(new JLabel("字体:"));
paneNorth.add(choose_word_style);
paneNorth.add(new JLabel("字号:"));
paneNorth.add(choose_word_big);
paneNorth.add(new JLabel("字形:"));
paneNorth.add(choose_word_pattern);
paneNorth.add(new JLabel("颜色:"));
paneNorth.add(choose_word_color);
this.add(paneNorth,BorderLayout.NORTH);
}
/**
* 初始化几个comboBox
* 把相应的选项加入
*/
public void initBox() {
choose_word_style = new JComboBox(styles);
choose_word_big = new JComboBox(word_big);
choose_word_pattern = new JComboBox(pattern);
choose_word_color = new JComboBox(colors);
}
public static void main(String[] args) {
about_Format a = new about_Format();
}
}
首先我们在类内声明了变量,然后通过initBox()方法,进行初始化,这样显得结构比较整齐。方法内将comboBox实例化,并且将相应的字符串数组放入,这样list效果就会出来了。
接下来,我们需要一个容器panel来把四个JComboBox装进去,所以在initLocation()方法里实例化一个panel,把一大堆JLabel,JComboBox装进去了。然后再将panel装进父窗体,设置属性north。
下来是一个文本显示区域,可以有很多种,我这里选了JTextField,这里需要提前讲一下,这里我还提前定义了一堆的字体属性,是为了最终子父窗体属性的影响而存在的,这里不需要在意:
public class about_Format extends JFrame{
...
private JPanel paneNorth;//用于装四个ComboBox
private JPanel paneCenter;
private JTextField showText ;
// 用一个font来装选中的的属性,每选中一次,对对应的属性修改
//然后集成一个font里进行修改
//对selectedFont 设置默认属性
private Font selectedFont = new Font("黑体",Font.PLAIN, 32);
private String selectedStyle = "宋体";
private int selectedBig = 32;
private int selectedPattern = Font.PLAIN;
private Color selectedColor = Color.BLACK;
public about_Format() {
initBox();
initText(); // 这里要放在Location前因为initText里有元素被Location访问 否则会出现空指针异常
initLocation();
this.setSize(550,200);
this.setTitle("文字格式");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
/**
* 初始化布局
* 将每个控件按照一定得布局排在this窗口中
*/
public void initLocation() {
paneNorth = new JPanel();
...
paneCenter = new JPanel();
paneCenter.add(showText);
this.add(paneCenter, BorderLayout.CENTER);
}
/**
* 初始化展示字体区域
*/
public void initText() {
showText = new JTextField("字体展示");
showText.setFont(selectedFont);
showText.setEditable(false);
showText.setSize(100,160);
//showText.setForeground(Color.red);
}
/**
* 初始化几个comboBox
* 把相应的选项加入
*/
public void initBox() {
...
}
public static void main(String[] args) {
about_Format a = new about_Format();
}
}
相信到这里大家的思路都清晰了吧,其实没有那么复杂。我们只需要把每一个部件拆开来看,一个个的去实现就可以了。
接下来我们只需要添加两个按钮,然后统一响应JComboBox和Button的事件就好了,照例在面板下部添加button,然后继承接口,处理回调事件。
添加两个button的代码:
public class about_Format extends JFrame{
...
private JPanel paneNorth;//用于装四个ComboBox
private JPanel paneCenter;
private JPanel paneSouth;
private JButton btn_ok;
private JButton btn_cancel;
private JTextField showText ;
...
public about_Format() {
initBox();
initText();
initButton();
initLocation();
this.setSize(550,200);
this.setTitle("文字格式");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
/**
* 初始化ok 和cancel 两个按钮
*/
private void initButton() {
btn_ok = new JButton("OK");
btn_cancel = new JButton("CANCEL");
}
/**
* 初始化布局
* 将每个控件按照一定得布局排在this窗口中
*/
public void initLocation() {
...
this.add(paneCenter, BorderLayout.CENTER);
paneSouth = new JPanel();
paneSouth.add(btn_ok);
paneSouth.add(btn_cancel);
this.add(paneSouth, BorderLayout.SOUTH);
}
/**
* 初始化展示字体区域
*/
public void initText() {
showText = new JTextField("字体展示");
showText.setFont(selectedFont);
showText.setEditable(false);
showText.setSize(100,160);
//showText.setForeground(Color.red);
}
/**
* 初始化几个comboBox
* 把相应的选项加入
*/
public void initBox() {
...
}
public static void main(String[] args) {
about_Format a = new about_Format();
}
}
下面统一添加监听器,这回我们用ItemListener,ActionListener两个接口,我们可以把button跟item分开来。如果想要统一监听也可以自己改。
添加监听器后代码:
public class about_Format extends JFrame implements ItemListener,ActionListener{
...
...
private JButton btn_ok;
private JButton btn_cancel;
private JTextField showText ;
// 用一个font来装选中的的属性,每选中一次,对对应的属性修改
//然后集成一个font里进行修改
//对selectedFont 设置默认属性
private Font selectedFont = new Font("黑体",Font.PLAIN, 32);
private String selectedStyle = "宋体";
private int selectedBig = 32;
private int selectedPattern = Font.PLAIN;
private Color selectedColor = Color.BLACK;
public about_Format() {
initBox();
initText();
initButton();
initLocation();
initListener();
addBtnListener();
this.setSize(550,200);
this.setTitle("文字格式");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
/**
* 时间监听回调函数
* 对每个item做出事件响应
*/
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getItem() == "宋体") {
selectedStyle = "宋体";
renewFont();
}else if (e.getItem() == "黑体") {
selectedStyle = "黑体";
renewFont();
}else if (e.getItem() == "楷体") {
selectedStyle = "楷体";
renewFont();
}else if (e.getItem() == "微软雅黑") {
selectedStyle = "微软雅黑";
renewFont();
}else if (e.getItem() == "隶书") {
selectedStyle = "隶书";
renewFont();
}else if (e.getItem() == "常规") {
selectedPattern = Font.PLAIN;
renewFont();
}else if (e.getItem() == "倾斜") {
selectedPattern = Font.ITALIC;
renewFont();
}else if (e.getItem() == "粗体") {
selectedPattern = Font.BOLD;
renewFont();
}else if (e.getItem() == "2") {
selectedBig = 2;
renewFont();
}else if (e.getItem() == "4") {
selectedBig = 4;
renewFont();
}else if (e.getItem() == "8") {
selectedBig = 8;
renewFont();
}else if (e.getItem() == "16") {
selectedBig = 16;
renewFont();
}else if (e.getItem() == "24") {
selectedBig = 24;
renewFont();
}else if (e.getItem() == "32") {
selectedBig = 32;
renewFont();
}else if (e.getItem() == "64") {
selectedBig = 64;
renewFont();
}else if (e.getItem() == "72") {
selectedBig = 72;
renewFont();
}else if (e.getItem() == "红色") {
selectedColor = Color.red;
renewFont();
}else if (e.getItem() == "黑色") {
selectedColor = Color.black;
renewFont();
}else if (e.getItem() == "蓝色") {
selectedColor = Color.blue;
renewFont();
}else if (e.getItem() == "黄色") {
selectedColor = Color.yellow;
renewFont();
}else if (e.getItem() == "绿色") {
selectedColor = Color.green;
renewFont();
}else if (e.getItem() == "白色") {
selectedColor = Color.WHITE;
renewFont();
}
}
/**
* 两个btn的监听事件回调
* @param arg0
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn_cancel) {
this.dispose();//销毁当前窗口
}else if (e.getSource() == btn_ok) { // 调用父窗体的实例,拿到textarea并对其setFont
//fileManagement.getEdit_text_area().setFont(selectedFont); // 这里的Edit_text_area设置为静态变量static 函数也一样 这样才能调用
//fileManagement.getEdit_text_area().setForeground(selectedColor); // 设置颜色
// 在父窗口内必须将Edit_text_area设置为static变量(静态变量)
// 静态变量的特点是,已经对象一经实例化(test1被new出来) 其中的静态变量也会在内存中存在,一直持续到实例被销毁
// 这时我们我们可以对其进行访问
/*test1 t1 = new test1();
t1.getEdit_text_area().setFont(selectedFont);*/
/**
* 以上这个方法是不行的,因为会通过实例化test1 窗口来设置一个新的Font的窗口,与我们想要的效果不相符
* 我们想要的是在原父窗口内将其字体改变格式
*/
this.dispose();
}
}
public void renewFont() {
selectedFont = new Font(selectedStyle,selectedPattern,selectedBig);
showText.setFont(selectedFont);
showText.setForeground(selectedColor);
}
/**
* 对ComboBox添加监听器
*/
private void initListener() {
choose_word_style.addItemListener(this);
choose_word_big.addItemListener(this);
choose_word_pattern.addItemListener(this);
choose_word_color.addItemListener(this);
}
/**
* 给两个btn添加监听器
*/
public void addBtnListener() {
btn_ok.addActionListener(this);
btn_cancel.addActionListener(this);
}
/**
* 初始化ok 和cancel 两个按钮
*/
private void initButton() {
btn_ok = new JButton("OK");
btn_cancel = new JButton("CANCEL");
}
/**
* 初始化布局
* 将每个控件按照一定得布局排在this窗口中
*/
public void initLocation() {
...
}
/**
* 初始化展示字体区域
*/
public void initText() {
...
}
/**
* 初始化几个comboBox
* 把相应的选项加入
*/
public void initBox() {
...
}
public static void main(String[] args) {
about_Format a = new about_Format();
}
}
大家可能被吓到了,一下子跳出来那么多代码。莫慌,这里一个个分析还是很简单的。刚才也说过了,我们现在需要对button和item添加监听器,然后在回调函数里处理就好了,至于处理的内容。无非就是两个button点击然后关闭窗口。item选择对showText改变Font,至于怎么变,前面我们声明的selected属性就很有用了,可以通过他们减少很多代码量。这里不需要多说,大家看一眼就明白了。
OK,到这里,一个完整的可以选择文本格式的小窗口已经独立的出来了。那我们接下来就是把除了main之外的其他内容拷到原来的工程里,当然要新建一个.java。完成之后,我们就可以考虑btn_ok点击的时候主窗体文本改变的问题。
不多说,首先在父窗体的actionPerformed里处理事件,把about_Format窗口弹出来再说。
在主窗体.java内,将JTextArea 设置为static,然后给一个getter 方法:
private static JTextArea edit_text_area;
//private JTextArea edit_text_area; // 原来
public static JTextArea getEdit_text_area() {
//public JTextArea getEdit_text_area() {
return edit_text_area;
}
在about_Format.java里给btn_ok添加事件:
else if (e.getSource() == btn_ok) { // 调用父窗体的实例,拿到textarea并对其setFont
test5.getEdit_text_area().setFont(selectedFont); // 这里的Edit_text_area设置为静态变量static 函数也一样 这样才能调用
//fileManagement.getEdit_text_area().setForeground(selectedColor); // 设置颜色
// 在父窗口内必须将Edit_text_area设置为static变量(静态变量)
// 静态变量的特点是,已经对象一经实例化(test1被new出来) 其中的静态变量也会在内存中存在,一直持续到实例被销毁
// 这时我们我们可以对其进行访问
/*test1 t1 = new test1();
t1.getEdit_text_area().setFont(selectedFont);*/
/**
* 以上这个方法是不行的,因为会通过实例化test1 窗口来设置一个新的Font的窗口,与我们想要的效果不相符
* 我们想要的是在原父窗口内将其字体改变格式
*/
this.dispose();
}
这里给大家留一个小bug,给大家自己去发现,看看是否能实现。
到此为止,第二个窗口就画完了。
总结一下本章完成的工作:一、在主窗口点击item,弹出窗口。二、给窗口画出三层结构,第一层几个单选列,第二层一个显示文本,第三层两个按钮。 三、给JComboBox添加监听事件,并对事件做处理,给两个按钮添加事件,对事件做处理。