前篇:本文和Random的由来
话说软工III做完已经有这么多天了,自己浑浑噩噩的想着要写点什么东西来纪念下自己Random小组的成果,虽然只有一点点小小的心得,不过还是想记录下在大学时自己第一次当组长带队的感觉。
先从这个小组的组成开始说起,我,zfx,tz,sjl,dp共5个人,可以说是别的组挑剩下的,话说我当初是真心想随机的,可是后面考虑到某些因素,所以还是在老师发布的没有组队的那些人中挑选了4个比较有可能会做事的人,鉴于自己不能Random,所以队伍取名叫做Random。
Random的组员我一开始比较熟悉的是t(tz)和z(zfx),他们两个是我比较早认识的两个人,Random组第一次开会是在图书馆的研讨室3204,第一次讨论的是大家的长处,t懂得代码架构,z和d(dp)精通文档编写,s(sjl)会数据库管理,所以其实第一次开会完成之后,我心里大概就有了一个底子,谁该干什么,谁会干什么我大都已经清楚了,不过我还是在幻想,幻想着每个人能在自己不熟悉的领域上面能够发挥下自己的作用,尽量在项目实践期间能够参与到每个环节中来。后来我发现,我错了……
正文一:作为组长的心得感悟
其实组长真的不是那么好当的,自以为看了本《人月神话》就能很好规划团队的我,最后只剩下傻傻的笑。也许是理论付诸于实践方面的错误,是我的方法不对。
首先,我们听从老师的安排写下的那些条条框框显然不适用,到后来迟到的迟到,缺席的缺席。记得s的缺席原因告诉我说是因为自己洗澡没时间来开会。开会时定在每周二、四晚和周六下午,这可是定死的啊,就因为要洗澡就不来是什么样的荒唐逻辑!我只能呵呵了。
关于团队决策方面,我觉得我根本就没有起到什么作用,关于代码架构,只要t一句话,他就可以根据自己的思维随心所欲的改动代码,而我,只能每次都因为理由不足而被他驳回,实际上我是骨子里面有股惰性的人,我懒得和你去争论,因为我知道,你这样可以,知道你的代码架构的很好,但是我的方案有我的优点,我知道就行,因为你,只会一味的执着于自己的意见,丝毫不顾及他人对此代码架构的理解。这次的项目经历了两次架构上的大变革,有些真是使我手足无措,我只能说“文档很重要,架构需谨慎,改动尽量小”,像我们这种架构,两次大幅度的更改已经是我的最高忍耐限度了。
关于团队的分工。一开始是想大家既然在做一个项目,就应该体验一下真实的流程,大家应该尽可能的参与到项目开发中来,所以一开始还是鼓励大家做多点自己不太擅长的事情,后来发现,也许是因为人的惰性,大家还是倾向于做自己擅长的方面。这点以后的项目实践中我会很重视的。还有就是在计划之下的任务分工,这次项目基本上是deadline驱动,所以计划驱动在Random看来只不过是浮云,这点是我不满意的地方,因为在计划日来临时给组员的动力远远比不上deadline。我很是懊恼这个问题。
关于项目的进度,这点也是我的另一个决策大失误,每一次都是deadline来临了,大家才有动力去做事情,没有一个人是真正投身到项目中来的,或许是不太抱希望到这个项目里面,或许因为我们是半Random的缘故,他们没有激情。给他们能在两天之内做好的事情,两个礼拜还没做好,最后交给我的还是完成度70%的半成品,我真的绝望了。似乎认识到靠别人不如靠自己。这个团队整体上都没有积极性,都太过依赖于我,以为我会把所有的事情做完,因为Random是我组织的。所以我在5月30日检查的时候给了他们一个警示,告诉他们我们项目离做完还差得远呢,希望能够提起他们的积极性。当时助教检查的时候我就给他看了login界面和数据库,其他的都以没做为由告诉助教,这时候的团队危机感似乎就有了,我以为这下子团队应该能够接手下一步的任务了,所以当他们问我是否想要将任务分解出来的时候,我只是委婉地说了一句:“不用,我做得完。”然后可能就是因为这句话,团队到了懒散到崩溃的状态。于是我找了个时间——端午3天,把项目的客户端代码写完了,服务器也完善好了,单元测试和集成测试也粗略的过了一遍。当我告知他们我写完这些的时候,团队崩溃的一发不可收拾了。z,他后期帮我完善了界面的美化和测试;d,最后一晚进行了测试。其他人,没有任何测试的欲望,仿佛没了他们什么事情。总之项目进度该如何调整才能使的队员们有紧张感愿意去做事情,我还是有点经验不足,希望在下次的项目中能有体会吧。
关于团队交流和规则的实施,这点我真是不知道要怎么讲才好,也许是我太心软了,开会时候迟到,缺席,开会时候玩游戏,听音乐,心不在焉,大家的一系列行为我都不好意思开口去说,以为他们知道错误会去改,我又错了。所以我还是要坚信,规则是铁一般的原则,任何一个人违反都应该毫不犹豫的告知并且制止。
关于团队组员的闪光点,t对代码架构有着自己独到的见解,UML图使用的非常的顺,RMI大数据传输算法的改进方面都做得很好。s的数据库管理技术比我好多了,界面雏形结构也做的比较好。d的文档编写能力实在是很强。z的代码编写,图片处理技术,界面美化以及代码规范化方面做的也是很好的。
正文二,JAVA使用中的一点小技术
这次我们写的是一个旅行者系统,主要还是有一些功能点要实现的,下面简要介绍下,我在这个项目里面设计时想到的几个亮点。
1. (伪)新手指引
所谓伪新手指引,其实是这么设计的,将一个jDialog的背景设为透明,然后在全屏幕上贴一张全屏大小的图片,客户端的界面正好和全屏幕上图片界面重合,达到是是而非的效果。具体代码:有人工和自动播放两种模式。
package helper;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
public class NewComerHelper extends JDialog{
public static final int WIDTH=(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() ;
public static final int HEIGHT=(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() ;
public static final int BUTTONWIDTH=80; //定义确认和取消键宽
public static final int BUTTONHEIGHT=25; //定义确认和取消键高
public static final int SIZE=40; //拥有的新手指南图片张数
JLabel picturelabel;
JButton okButton,button;
int index=0;
JFrame parents;
public NewComerHelper(final JFrame parents,int type){
this.parents=parents;
parents.setEnabled(false);
if(type==0){
helpByUser();
}else {
new Thread(new Runnable() {
@Override
public void run() {
helpByRobot();
}
}).start();
}
}
public void helpByUser(){
final JDialog dialog = new JDialog(); //以下3行目的是设置jDialog背景透明。
dialog.setUndecorated(true);
dialog.setBackground(new Color(255,255,255,1));
dialog.getContentPane().setLayout(null);
picturelabel = new JLabel(new ImageIcon("./helperPicture/0.png"));
index=0;
picturelabel.setBounds(0, 0, WIDTH, HEIGHT);
picturelabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event){
if(index<=SIZE){
index++;
picturelabel.setIcon(new ImageIcon("./helperPicture/"+index+".png"));
if(index==SIZE){
okButton.setVisible(false);
button.setText("close");
}
}
}
});
okButton = new JButton("next");
okButton.setBounds(WIDTH-250, HEIGHT-100, BUTTONWIDTH, BUTTONHEIGHT);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if(index<=SIZE){
index++;
picturelabel.setIcon(new ImageIcon("./helperPicture/"+index+".png"));
if(index==SIZE){
okButton.setVisible(false);
button.setText("close");
}
}
}
});
dialog.getContentPane().add(okButton);
button = new JButton("cancel");
button.setBounds(WIDTH-150, HEIGHT-100, BUTTONWIDTH, BUTTONHEIGHT);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
parents.setEnabled(true);
dialog.dispose();
}
});
dialog.getContentPane().add(button);
dialog.getContentPane().add(picturelabel);
dialog.setSize(WIDTH,HEIGHT);
dialog.setVisible(true);
}
public void helpByRobot(){
final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setBackground(new Color(255,255,255,1));
dialog.getContentPane().setLayout(null);
picturelabel = new JLabel(new ImageIcon("./helperPicture/0.png"));
index=0;
picturelabel.setBounds(0, 0, WIDTH, HEIGHT);
button = new JButton("cancel");
button.setBounds(WIDTH-150, HEIGHT-100, BUTTONWIDTH, BUTTONHEIGHT);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
parents.setEnabled(true);
dialog.dispose();
}
});
dialog.getContentPane().add(button);
dialog.getContentPane().add(picturelabel);
dialog.setSize(WIDTH,HEIGHT);
dialog.setVisible(true);
picturelabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event){
if(index<=SIZE){
index++;
picturelabel.setIcon(new ImageIcon("./helperPicture/"+index+".png"));
if(index==SIZE){
button.setText("close");
}
}else {
JOptionPane.showMessageDialog(null, "您已经学习完了,退出吧,亲!");
}
}
});
display();
}
public void display(){
for(index=0;index<=SIZE;index++){
picturelabel.setIcon(new ImageIcon("./helperPicture/"+index+".png"));
try {
Thread.sleep(2013);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// new NewComerHelper(1);
}
}
2. 验证码的BufferImage实现序列化
刚开始让我头疼的验证码是用label上面的数字实现的,后来组员反应太低级,所以在服务器序列化BufferedImage可以实现图片在客户端和服务器之间的传输,简单许多。原理,服务器随机生成数字,然后生成一张图片,再然后传到客户端识别。序列化代码如下:(源代码来源于网络)
package po;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerializedImage implements Serializable {
/**
* A BufferedImage to serialized.
* @serial bimage A BufferedImage to serialized.
*/
private BufferedImage bimage;
/**
* Create a SerializedImage with a BufferedImage (<I>Can be use with RMI</I>).
* @param bufferedImage Initial BufferedImage.
*/
public SerializedImage(BufferedImage bufferedImage) {
bimage=bufferedImage;
}
/**
* Create a SerializedImage (<I>Can be use with RMI</I>).
* @param image Initial Image.
* @param width Width of this image.
* @param Height height of this image.
*/
public SerializedImage(Image image,int width,int height) {
boolean errorFlag=false;
PixelGrabber pg = new PixelGrabber(image,0,0,width,height,true);
try {
pg.grabPixels();
} catch (InterruptedException e) {
System.out.println("* Error while creating SerializedImage from Image");
errorFlag=true;
}
bimage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
if (!errorFlag) {
bimage.setRGB(0,0,width,height,(int[])pg.getPixels(),0,width);
}
}
/**
* Get an BufferedImage of this SerializedImage.
*/
public BufferedImage getBImage() {
return bimage;
}
/**
* Get the width of this SerializedImage.
* @return Width in pixels.
*/
public int getWidth() {
return bimage.getWidth();
}
/**
* Get the height of this SerializedImage.
* @return Height in pixels.
*/
public int getHeight() {
return bimage.getHeight();
}
/**
* Returns a string representation of the object.
* Like this : SerializedImage[w=bimageWidth,h=bimageHeight].
*/
public String toString() {
return new String("SerializedImage[w=" + bimage.getWidth() + ",h=" + bimage.getHeight() + "]");
}
// Serialization of the BufferedImage
private void writeObject(ObjectOutputStream s) throws IOException {
s.writeInt(bimage.getWidth());
s.writeInt(bimage.getHeight());
s.writeInt(bimage.getType());
for(int i=0;i<bimage.getWidth();i++) {
for(int j=0;j<bimage.getHeight();j++) {
s.writeInt(bimage.getRGB(i,j));
}
}
s.flush();
}
private void readObject(ObjectInputStream s) throws IOException,ClassNotFoundException {
bimage = new BufferedImage(s.readInt(),s.readInt(),s.readInt());
for(int i=0;i<bimage.getWidth();i++) {
for(int j=0;j<bimage.getHeight();j++) {
bimage.setRGB(i,j,s.readInt());
}
}
}
}
验证码的生成以及验证(有点小BUG,原因是static池里面只能存一个验证码,所以你懂得!)
public SerializedImage getVCode() throws RemoteException {
return new SerializedImage(getValidateCode());
}
private static BufferedImage getValidateCode() {
int width = 80;
int height = 23;
BufferedImage image =
new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(new Color(
getRandom(200, 250),
getRandom(200, 250),
getRandom(200, 250)));
g.fillRect(0, 0, width, height);
int number = 4;
code="";
for(int i = 1; i <= number; i++) {
g.setColor(new Color(
getRandom(0,100),
getRandom(0,100),
getRandom(0,100)));
g.setFont(new Font(getFontName(), getStyle(), 16));
g.drawString(""+getChar(),
width * i / (number + 3), (int) (height / 1.5));
}
code=code.trim();
BasicStroke stroke = new BasicStroke(getRandom(1, 3),
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g.setStroke(stroke);
g.drawLine(getRandom(0, 10), height / getRandom(1, 10),
width, height / getRandom(1, 2));
g.drawLine(getRandom(0, 10), height / getRandom(3, 10),
width, height / getRandom(1, 3));
g.drawLine(getRandom(0, 10), height / getRandom(3, 10),
width, height / getRandom(1, 2));
return image;
}
private static char getChar() {
char c;
int random = (int) (Math.random() * 62);
if (random < 10) {
c= (char)(random + 48);
code += random;
} else if (random < 36) {
random = random - 10 + 65;
c = (char) random;
code += c;
} else {
random = random - 36 + 97;
c= (char) random;
code += c;
}
return c;
}
private static String getFontName() {
String[] names =
{"楷体","SimSun", "Times New Roman", "Arial", "Courier New"};
return names[getRandom(0, names.length)];
}
private static int getStyle() {
int[] styles =
{Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC};
return styles[getRandom(0, styles.length)];
}
private static int getRandom(int start, int end) {
int index = -1;
while(!(index >= start && index <= end)) {
index = (int) (Math.random() * end);
}
return index;
}
@Override
public boolean isVCodeAvaliable(String string) throws RemoteException {
return code.toLowerCase().equals(string.toLowerCase());
}
3.只能输入数字和限制长度的JTextField的实现
功能如标题,代码如下:
只能输入数字:
package UI;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class NumOnlyDocument extends PlainDocument {
public void insertString(int offset, String s, AttributeSet attrSet)
throws BadLocationException {
try {
Integer.parseInt(s);
} catch (NumberFormatException ex) {
return;
}
if (this.getLength() >= 24){
return;
}
super.insertString(offset, s, attrSet);
}
}
限制长度:
package UI;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class ShortInputDocument extends PlainDocument{
public static final int max_size=24;
public void insertString(int offs,String str,AttributeSet a)throws BadLocationException{
if (this.getLength() >= max_size){
return;
}
super.insertString(offs,str,a);
}
}
拓展:限制Ctrl+C(复制) 和 Ctrl+V(粘贴) 的JTextArea 有效地防止老师的暴力测试,嘿嘿。
JTextArea textArea = new JTextArea(){
@Override public void copy(){}
@Override public void paste(){}
};
4. (伪)傻瓜式拖拽的实现
所谓伪就是指仿照windows下的拖拽方式来实现在一个界面上面对“某种对象”的拖拽操作。其实就是通过一个隐藏的JDialog实现参数的传递。具体的代码如下:
设定指定拖拽区域:
tipsLabel= new JLabel("拖至此处转载该计划");
tipsLabel.setFont(new Font("楷体", Font.PLAIN, 26));
tipsLabel.setForeground(Color.YELLOW);
tipsLabel.setBounds(6, 375, 250, 50);
tipsLabel.setVisible(true);
tipsLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent arg0) {
tipsLabel.setForeground(Color.YELLOW);
}
@Override
public void mouseEntered(MouseEvent arg0) {
tipsLabel.setForeground(Color.BLACK);
}
});
panel.add(tipsLabel);
设定拖拽显示小框
public OtherPlanSmallUI(String planName,String userName) {
this.planName=planName;
this.userName=userName;
setBounds(100, 100, 155, 85);
setUndecorated(true);
setBackground(new Color(255,255,255,1));
getContentPane().setLayout(new BorderLayout(0, 0));
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel);
contentPanel.setLayout(null);
JLabel label = new JLabel("计划:");
label.setBounds(10, 10, 36, 15);
contentPanel.add(label);
JLabel label_1 = new JLabel("作者:");
label_1.setBounds(10, 55, 36, 15);
contentPanel.add(label_1);
lblNewLabel = new JLabel("");
lblNewLabel.setText(planName);
lblNewLabel.setBounds(54, 10, 91, 15);
contentPanel.add(lblNewLabel);
lblNewLabel_1 = new JLabel("");
lblNewLabel_1.setText(userName);
lblNewLabel_1.setBounds(54, 55, 91, 15);
contentPanel.add(lblNewLabel_1);
setVisible(true);
}
public void setLabel(String planName,String userName){
lblNewLabel.setText(planName);
lblNewLabel_1.setText(userName);
this.planName=planName;
this.userName=userName;
}
设定拖拽中小框显示:
public void mouseDragged(MouseEvent e) {
String nameString = list.getModel().getElementAt(selectedIndex);
String part[] = nameString.split(" BY ");
String info[] = part[0].split(" ");
String type = info[0];
if(type.equals("[日志]")){
JOptionPane.showMessageDialog(null, "日志不支持拖拽!");
return;
}else{
myDialog.setBounds(e.getXOnScreen(), e.getYOnScreen(),155, 85);
myDialog.setVisible(true);
tipsLabel.setVisible(true);
}
}
设定按下和释放条件:release的时候必须进入指定区域
public void mousePressed(MouseEvent e){
selectedIndex=list.getSelectedIndex();
String nameString = list.getModel().getElementAt(selectedIndex);
String part[] = nameString.split(" BY ");
String info[] = part[0].split(" ");
String type = info[0];
String name = info[1];
String travellerName = part[1];
if(type.equals("[计划]")){
myDialog.setLabel(name, travellerName);
myDialog.setBounds(e.getXOnScreen(), e.getYOnScreen(),155, 85);
myDialog.setVisible(false);
}
}
public void mouseReleased(MouseEvent e){
int mouseX=e.getLocationOnScreen().x;
int mouseY=e.getLocationOnScreen().y;
int labelX=tipsLabel.getLocationOnScreen().x;
int labelY=tipsLabel.getLocationOnScreen().y;
int width = tipsLabel.getWidth();
int height = tipsLabel.getHeight();
myDialog.setVisible(false);
if(mouseX>labelX&&mouseX<labelX+width&&mouseY>labelY&&mouseY<labelY+height){
int selection = JOptionPane.showConfirmDialog(null,
"你确定转载该计划?", null, 2);
if (selection == JOptionPane.CANCEL_OPTION) {
// Do NoThing
} else if (selection == JOptionPane.YES_OPTION) {
try {
Plan plan =IServiceFactory.getPlanService().findMyPlan(myDialog.getUserName(),myDialog.getPlanName());
String beforUserName = plan.getUserName();
String beforePlanName = plan.getPlanName();
if(beforePlanName.length()>=5&&beforePlanName.substring(0, 4).equals("[转载]")){
JOptionPane.showMessageDialog(null, "请转载原作者文章,该篇计划已经被转载过");
return;
}
if(beforUserName.equals(userName)){
JOptionPane.showMessageDialog(null, "别闹!转载自己计划干嘛!");
return;
}
plan.setUserName(userName);
plan.setPlanName("[转载]" + plan.getPlanName());
if (IServiceFactory.getPlanService().addPlan(plan)) {
JOptionPane.showMessageDialog(null, "转载成功");
} else {
JOptionPane.showMessageDialog(null, "您已经转载该计划");
}
plan.setUserName(beforUserName);
plan.setPlanName(beforePlanName);
} catch (RemoteException e111) {
JOptionPane.showMessageDialog(null, "网络连接错误!");
}
}
}
}
5. SubstanceLookAndFeel的使用 。
简单易懂,下个Substance.jar然后加上下面的代码:这是我的偏好。。。。。。
try {
JFrame.setDefaultLookAndFeelDecorated(true);
UIManager.setLookAndFeel(new SubstanceLookAndFeel());
UIManager.put("swing.boldMetal", false);
System.setProperty("sun.awt.noerasebackground", "true");
//设置当前的主题风格,同样我 们还可以设置当前的按钮形状,水印风格等等
SubstanceLookAndFeel.setCurrentTheme(new SubstanceLightAquaTheme());
// SubstanceLookAndFeel.setCurrentButtonShaper(new ClassicButtonShaper());
SubstanceLookAndFeel.setCurrentWatermark(new SubstanceBinaryWatermark());
SubstanceLookAndFeel.setCurrentBorderPainter(new StandardBorderPainter());
//设置渐变渲染
SubstanceLookAndFeel.setCurrentGradientPainter(new StandardGradientPainter());
//设置标题
SubstanceLookAndFeel.setCurrentTitlePainter(new FlatTitlePainter());
} catch (Exception e) {
System.err.println("Oops! Something went wrong!");
}
6. 日期下拉框的实现:
简单的日期下拉框,可以方便的选择如期,不过关于Combox的使用还请参照我的另一篇博文。谢谢,代码如下:源代码来源于网络
package UI;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class DateCombox implements ItemListener {
JComboBox comYear;
JComboBox comMonth;
JComboBox comDate;
int count = 0;// 此属性用来存贮天数
GregorianCalendar calend = new GregorianCalendar();// 用来获取系统的当前日期
GregorianCalendar calend1;// 此日期对象用来表示用户所选择的日期
/*
* 构造方法
*/
public DateCombox(JComboBox comYear, JComboBox comMonth, JComboBox comDate) {
this.comYear = comYear;
this.comMonth = comMonth;
this.comDate = comDate;
}
public void load() {
loadJcom();
// 默认显示当前年份
comYear.setSelectedItem(calend.get(Calendar.YEAR) + "");
// 默认显示当前月份
comMonth.setSelectedItem((calend.get(Calendar.MONTH) + 1) + "");
loadComDate();
comDate.setSelectedItem(calend.get(Calendar.DATE) + "");
comYear.addItemListener(this);
comMonth.addItemListener(this);
}
public void load(String year, String month, String day) {
// 默认显示当前年份
comYear.setSelectedItem(Integer.parseInt(year) + "");
// 默认显示当前月份
comMonth.setSelectedItem(Integer.parseInt(month) + "");
comDate.setSelectedItem(Integer.parseInt(day) + "");
}
private void loadJcom() {
// 年份从1970到2020年
// comYear.removeAllItems();
// comMonth.removeAllItems();
for (int i = 1970; i <= 2020; i++) {
comYear.addItem(i + "");// 加上双引号变成字符串
}
for (int i = 1; i <= 12; i++) {
comMonth.addItem(i + "");
}
}
private void loadComDate() {
// 从comYear中或取用户选择的年份
int year = Integer.parseInt((String) comYear.getSelectedItem());
// 从comMonth中获取用户选择的月份
int month = Integer.parseInt((String) comMonth.getSelectedItem());
// 用用户选择的年份和月份重新实例化一个日期对象
calend1 = new GregorianCalendar(year, month, 1);
// 从一月到十二月每个月的天数
int[] dateCount = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// 根据用户选择的月份下拉列表的选择下标获取这个月所对应的天数
count = dateCount[comMonth.getSelectedIndex()];
// 判断是否闰年如果是闰年并且是二月的话则将存贮天数的变量count加1
if (calend1.isLeapYear(year) && comMonth.getSelectedIndex() == 1) {
count++;
}
for (int i = 1; i <= count; i++) {
comDate.addItem(i + "");
}
}
public static void main(String args[]) {
JFrame f = new JFrame("测试");
f.setLayout(new FlowLayout());
JComboBox year = new JComboBox();
JComboBox month = new JComboBox();
JComboBox date = new JComboBox();
DateCombox com = new DateCombox(year, month, date);
com.load();
f.add(new JLabel("开始时间"));
f.add(year);
f.add(month);
f.add(date);
f.setSize(450, 200);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void itemStateChanged(ItemEvent e) {
// TODO 自动生成的方法存根
comDate.removeAllItems();// 将comDate中的选项全部清空
loadComDate();// 重新加载天数
}
}
7. 最小化到托盘的实现
点击下就到托盘里面去了,boss什么的就看不到了,方便快捷,代码如下:源代码来源于网络
private void miniTray() { //窗口最小化到任务栏托盘
ImageIcon trayImg = new ImageIcon("./picture/myicon.png");//托盘图标
PopupMenu pop = new PopupMenu(); //增加托盘右击菜单
MenuItem show = new MenuItem("还原");
MenuItem exit = new MenuItem("退出");
final TrayIcon trayIcon = new TrayIcon(trayImg.getImage(), "Traveller系统",pop);
show.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { // 按下还原键
tray.remove(trayIcon);
mainFrame.setVisible(true);
mainFrame.setExtendedState(JFrame.NORMAL);
mainFrame.toFront();
}
});
exit.addActionListener(new ActionListener() { // 按下退出键
public void actionPerformed(ActionEvent e) {
try {
IServiceFactory.getLogInService().logout(userName);
tray.remove(trayIcon);
System.exit(0);
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
pop.add(show);
pop.add(exit);
trayIcon.setImageAutoSize(true);
trayIcon.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) { // 鼠标器双击事件
if (e.getClickCount() == 2) {
tray.remove(trayIcon); // 移去托盘图标
mainFrame.setVisible(true);
mainFrame.setExtendedState(JFrame.NORMAL); // 还原窗口
mainFrame.toFront();
}
}
});
try {
tray.add(trayIcon);
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
完,回忆不起来了,转眼就过去一年了