首先,我们需要回顾一些内容(2017-01-04 14:32:14):

1.Swing组件

Swing的组件(component,或者称之为元件),是较widget更为正确的术语,它们就是会放在GUI(Graphical User Interface)上面的东西,这些内容就是一些用户会看到并且与其交互的,如Text Field、Button、scrollable、list、radio button等,这些组件均是继承自java.swing.JComponent;

在Swing中,几乎所有的组件都是安置到其他组件当中。

2.创建GUI的四个步骤:

  • 创建window(JFrame)

JFrame frame=new JFrame();

  • 创建组件

JButton button=new JButton(“click me”);

  • 将组件添加到frame上

frame.getContentPane.add(BorderLayout.EAST,button);

  • 显示出来

frame.setSize(300,300);

frame.setVisible(true);

3.布局管理器(layout Managers)

首先,布局管理器是与特定组件相关联的java对象,他大多数是背景组件。

其次,布局管理器是用来控制所关联组件上携带的其他组件,换言之,如果某个框架带有面板,面板上有按钮的情况下,则面板布局管理器就是控制按钮的大小与位置,而框架的布局管理器是控制着面板的大小与位置。

将对应的按键添加到对应的面板上,可以如下实现:

JPanel jpanel=new JPanel();

JButton button=new JButton(“click me”);

jpanel.add(button);

4.三大首席管理器:

  • border
  • flow
  • box

1)BorderLayout:该管理器会将组建分割成5个区域,每个区域只能放置一个组件,由此管理员安置的组件不会取得默认的大小。这个也是框架默认得布局管理器;

2)FlowLayout:该管理器的行为与文书处理程序的版面配置方式差不多。这个组件会依照理想的大小呈现,并且胡依照从左到右,依次加入的顺序(中间可能会换行)排列,因此如果组建放不下一行的时候会自动换行。这个是面板默认得布局管理器。

3)BoxLayout:它就像FlowLayout一样让每个组件按照默认得大小,依次按照加入的顺序进行排列,它是以垂直的方式排列(也可以水平,但是通常我们只关心垂直的方式)。与FlowLayout不 同的是,它是需要插入某种换行的机制来强制组件从新的一列进行排列。

接下来我们看一下干货:

 import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList; import javax.sound.midi.*;
import javax.swing.*; public class BeatBox {
JPanel mainJPanel;
ArrayList<JCheckBox> checkboxslist;
Sequencer sequencer;
Sequence sequence;
Track track;
JFrame theFrame;
String[]instrumentNames={
"Bass Drum","closed Hi-Hat","open Hi-Hat","Acoustic Snare",
"Crash Cymbal","Hand Clap","High Tome","Hi Bongo","Maracas",
"Whistal","Low Conga","Cowbell","Vibraslap","Low_mid Tom",
"High Agogo","open High Coga"
};//乐器的名称,用String的array维护
int []instrument={35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};//实际乐器的关键字,比如说35是Bass Drum,42是closed Hi-Hat
public static void main(String[] args) {
// TODO Auto-generated method stub
new BeatBox().buildGUI();
}
public void buildGUI(){
theFrame = new JFrame("Cyber BeatBox");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗口关闭时关闭程序
BorderLayout layout = new BorderLayout();//定义了一个BorderLayout面板对象
JPanel background=new JPanel(layout);//将面板对象实例化JPanel对象
background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));//用于设置边缘空白大小 checkboxslist=new ArrayList<JCheckBox>();
Box buttonBox = new Box(BoxLayout.Y_AXIS); JButton start = new JButton("start");
start.addActionListener(new MyStartlistener());
buttonBox.add(start); JButton stop = new JButton("stop");
start.addActionListener(new MyStoplistener());
buttonBox.add(stop); JButton upTempo = new JButton("Tempo up");
start.addActionListener(new MyupTempolistener());
buttonBox.add(upTempo); JButton downTempo = new JButton("Tempo down");
start.addActionListener(new MydownTempolistener());
buttonBox.add(downTempo); Box nameBox=new Box(BoxLayout.Y_AXIS);
for(int i=0;i<16;i++){
nameBox.add(new Label(instrumentNames[i]));
} background.add(BorderLayout.EAST,buttonBox);
background.add(BorderLayout.WEST,nameBox); theFrame.getContentPane().add(background); GridLayout gridLayout=new GridLayout(16,16);//创建具有指定行数和列数的网格布局。 布局中的所有组件都具有相等的大小。
//行和列中的一个(但不是两者)可以为零,这意味着任何数量的对象都可以放置在一行或一列中。
gridLayout.setVgap(1);//将组件之间的垂直间距设置为指定的值。
gridLayout.setHgap(2);//将组件之间的水平间距设置为指定的值。
mainJPanel=new JPanel(gridLayout);
background.add(BorderLayout.CENTER,mainJPanel); for(int i=0;i<256;i++){
JCheckBox checkBox=new JCheckBox();
checkBox.setSelected(false);
checkboxslist.add(checkBox);
mainJPanel.add(checkBox);
}//结束循环
//创建checkBox组,并将其设定成未勾选的false,并添加到arraylist以及面板上 setUpMidi(); theFrame.setBounds(50, 50, 300, 300);
theFrame.pack();//pack()函数:使此窗口的大小适合其子组件的首选大小和布局。 如果任一维度小于由上次调用setMinimumSize方法指定的最小大小,则会自动放大窗口的最终宽度和高度。
//如果窗口和/或其所有者不可显示,则在计算优选大小之前使它们两者都可显示。 窗口在计算其大小后生效。
theFrame.setVisible(true);
}//关闭buildGUI()方法 public void setUpMidi(){
try{ sequencer= MidiSystem.getSequencer();//此方法等效于调用getSequencer(true) 创建sequencer
sequencer.open();
//创建并打开队列 sequence=new Sequence(Sequence.PPQ, 4);
track=sequence.createTrack();
//创建队列并track sequencer.setTempoInBPM(120); }catch(Exception e){
e.printStackTrace();
}
}//关闭 setUpMidi()方法 public void buildTrackAndStart(){ int []trackList=null;//创建出16个元素的数组来存储一项乐器值,如果有该演奏,其值就将会是关键字值,否则将值为零 sequence.deleteTrack(track);
track=sequence.createTrack();//清除旧的track,做一个新的 for (int i = 0; i < 16; i++) {//每个乐器执行一次
trackList=new int[16]; int key=instrument[i];//设代表乐器的关键字 for(int j = 0;j<16;j++){//每一拍执行一次
JCheckBox jc=(JCheckBox)checkboxslist.get(j+16*i);
if(jc.isSelected()){//如果勾选,那么关键字的值放到数组得该位置上,不然的话,就补零
trackList[j]=key;
}else{
trackList[j]=0;
}
}//关闭循环 makeTracks(trackList);
track.add(makeEvent(176,1,127,0,16));//创建此乐器事件,并添加到track上;
}//关闭外循环 track.add(makeEvent(192,9,1,0,15)); try{
sequencer.setSequence(sequence);
sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempoInBPM(120);//以每分钟的拍数设置速度。 播放的实际速度是指定值和速度因子的乘积。
}catch(Exception e){
e.printStackTrace();
}
}//结束buildTrackAndStart方法 public class MyStartlistener implements ActionListener{
//按钮的监听者
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
buildTrackAndStart();
} }//内部类关闭
public class MyStoplistener implements ActionListener{
//按钮的监听者
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
sequencer.stop();
} }//内部类关闭
public class MyupTempolistener implements ActionListener{
//按钮的监听者
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*1.03));//节奏因子,预设为1.0,每次调整3%
} }//内部类关闭
public class MydownTempolistener implements ActionListener{
//按钮的监听者
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
float tempoFactor=sequencer.getTempoFactor();
sequencer.setTempoFactor((float)(tempoFactor*.97));//节奏因子,预设为1.0,每次调整3%
} }//内部类关闭
public void makeTracks(int []list){ for (int i = 0; i < 16; i++) {
int key=list[i];
if (key!=0) {
track.add(makeEvent(144,9,key,100,i));
track.add(makeEvent(128,9,key,100,i+1));//创建Note on以及Note off,并添加到track上
}
}
}//关闭makeTracks方法
public MidiEvent makeEvent(int comd,int chan,int one,int two,int tick){
MidiEvent event=null;
try{
ShortMessage shortMessage=new ShortMessage();//创建消息实例
shortMessage.setMessage(comd, chan, one, two);//调用setMessage
event=new MidiEvent(shortMessage, tick);//制作消息的MidiEvent实例
}catch(Exception e){
e.printStackTrace();
}
return event;
}//关闭makeEvent方法,该方法是制作消息以及事件
}

对应的界面呈现为:

问:框架为什么不能像面板那样直接加上组件呢?

答:JFrame会这么特殊是因为它是让无显示在画面上的接点。

因为Swing的组件纯粹是由Java构成的,JFrame必须要连接到底层的操作系统以便于存储显示装置。我们可以把面板想做是安置在JFrame上的100%的java层,或者把JFrame想作是支撑面板的框架,他甚至可以使用 自定义的方式换掉框架的面板:

  nyframe.setContentpane(myPanel);

最新文章

  1. Linux服务器的那些性能参数指标
  2. 解决cocopods不提示第三方库名字的方法
  3. 2015年10月15日学习html基础笔记
  4. 2014 HDU多校弟五场J题 【矩阵乘积】
  5. UVALive - 4670 Dominating Patterns AC 自动机
  6. 认识ExtJS(04)--常见Web框架的ExtJS改造
  7. 读《effective C++》1
  8. java web轻量级开发面试教程内容精粹:哪些简历得不到面试机会
  9. [案例]某体育用品公司在零售领域BI的产品应用解决方案
  10. vmware彻底隐藏控制栏白条
  11. Python爬虫从入门到进阶(3)之requests的使用
  12. Alpha冲刺! Day3 - 砍柴
  13. 深度学习之循环神经网络RNN概述,双向LSTM实现字符识别
  14. [ SHELL编程 ] 远程服务器传输文件
  15. MyBatis开发Dao层的两种方式(Mapper动态代理方式)
  16. 如何在FreePBX ISO 中文版本安装讯时网关,潮流16FXS 网关和潮流话机
  17. springboot集成模板引擎freemarker和thymeleaf
  18. Java-小技巧-004-jdk时间,jdk8时间,joda,calendar,获取当前时间前一周、前一月、前一年的时间
  19. linux c做服务端使用多线程接收图片并且将图片写入数据库
  20. Java并发编程(六)发布与逸出

热门文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
  2. Hibernatel框架关联映射
  3. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1
  4. 跟我一起云计算(5)——Shards
  5. Partition:增加分区
  6. Security Policy:行级安全(Row-Level Security)
  7. CRL快速开发框架系列教程七(使用事务)
  8. 【转】java通用URL接口地址调用方式GET和POST方式
  9. RSA算法
  10. 微信公众号开发(一)--验证服务器地址的Java实现