编写一个班级推选优秀生的软件,可列出参与推优的学生名单,能够显示当前投票人数以及每名候选者得票数,以图形化显示得票数。
有一点说明:界面的东边(右边),如果一直投票,0票变为10票,“0票"变"10票”,这个串的长度改变了,进度条区域会有一个错误,再投一次票又恢复正常,所以暂时的解决方案是把东部的"得票"改成"得票数"。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class _2推优 {
public static void main(String[] args) {
Vote vote = new Vote();
}
}
//投票窗口:
class Vote extends JFrame {
private int width = 400, height = 500;//大小
//边布局,东西南北的4个面板:
private JPanel pn = new JPanel(), ps = new JPanel(), pe = new JPanel(), pw = new JPanel();
//各标签:凡是titlexxxL:代表标题的标签
private JLabel titleVotersL = new JLabel("投票人数:"), titleMaxVotesL = new JLabel("最高票:"),
titleCandidatesL = new JLabel("候选人"), titleVotesL = new JLabel("得票数");
//2个编辑框,显示投票人数和最高票,后设置为不可编辑:
private JTextField votersT = new JTextField(5), maxVotesT = new JTextField(5);
//候选人头像(用标签实现)、复选框、得票数标签、得票数整型数组:
private JLabel[] image = new JLabel[5];// 头像
private JCheckBox[] ckb = new JCheckBox[5];// 复选框
private JLabel votesL[] = new JLabel[5];// 候选人得票标签
private int[] votesI = new int[5];// 票数 votes Integer
//投票和取消按钮:
private JButton voteB = new JButton("投票"), cancleB = new JButton("取消");
//以下实现投票时画进度条(只基础功能,不能自动调整比例):
//且如果titleVoteL的内容如果设置为"票数",
//那么候选人的得票数从9变为10,或者从99变成100,或者其他位数变化的情况,
//进度条会突然错误一次,再点投票时即可复原,
//可能的原因是,最初 "东部" 最大长度时2——"票数" 和 "0票"长度都是2,"0票"变成"10票"是,最大长度变了。
//就出现了一个暂时未知的错误,原因有待以后探索
//暂时的解决办法是titleVotesL标签的内容设置为"得票数",这样 “东部”的最大长度是3,"99票"变为"100票"时才会闪一下
public void paintComponents(Graphics g) {
super.paintComponents(g);
g.setColor(Color.pink);
for (int i = 0; i < ckb.length; ++i)
//填充矩形:一票长度设置为5:
g.fillRect(130, 150 + i * 65, votesI[i] * 5, 35);
}
//构造函数:
public Vote() {
super("班级推优");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
//边布局:
setLayout(new BorderLayout());
//北部:North:
//投票人数和最高票先设置为0,且不可编辑:
votersT.setText("0");
maxVotesT.setText("0");
votersT.setEditable(false);
maxVotesT.setEditable(false);
//向面板中添加两个标题标签和两个编辑框:
pn.add(titleVotersL);
pn.add(votersT);
pn.add(titleMaxVotesL);
pn.add(maxVotesT);
//面板添加到窗口中:
add("North", pn);
//南部:South:
add("South", ps);
//投票、取消按钮:
ps.add(voteB);
ps.add(cancleB);
//西部:
add("West", pw);
//西部用网格布局,两列,分别是头像和勾选框:
pw.setLayout(new GridLayout(6, 2));
//设置名字:
ckb[0] = new JCheckBox("宋分题");
ckb[1] = new JCheckBox("李思思");
ckb[2] = new JCheckBox("陈咬金");
ckb[3] = new JCheckBox("梁皮儿");
ckb[4] = new JCheckBox("杨娃娃");
//这里是头像设置,如果没有图就替换成image[i] = new JLabel(); 最后用空标签占位,
for (int i = 0; i < image.length; ++i) {
image[i] = new JLabel(new ImageIcon("E:\\p" + i + ".jpg"));
}
//先用空标签占位,然后添加候选人标题,如此网格的第1行就“用完了”:
pw.add(new JLabel());
pw.add(titleCandidatesL);
//接下来的几行,先添加头像,再添加勾选框:
for (int i = 0; i < ckb.length; ++i) {
pw.add(image[i]);
pw.add(ckb[i]);
}
//东部:East:
add("East", pe);
//也是网格布局,1列,显示得票标签:
pe.setLayout(new GridLayout(6, 1));
//得票标签首先设置为0票,得票整型数组默认值是0,不必修改:
for (int i = 0; i < votesL.length; ++i) {
votesL[i] = new JLabel("0票");
}
//添加得票标题标签:
pe.add(titleVotesL);
//添加候选人的得票标签:
for (int i = 0; i < votesL.length; ++i)
pe.add(votesL[i]);
//投票按钮添加监听器:
voteB.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//投票人数+1
votersT.setText(Integer.parseInt(votersT.getText()) + 1 + "");
//判断每个候选人的勾选框是否勾选,是则更新得票数和得票标签:
for (int i = 0; i < ckb.length; ++i) {
if (ckb[i].isSelected()) {
votesI[i]++;//得票数+1
votesL[i].setText(votesI[i] + "票");//得票数标签更新
//判断最高票是否需要更新:
if (votesI[i] > Integer.parseInt(maxVotesT.getText())) {
maxVotesT.setText(votesI[i] + "");
}
}
}
//投票进度条更新:
paintComponents(getGraphics());
}
});
//取消按钮添加监听器:
cancleB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(-1);
}
});
//位置、可见、不可更改大小:
setLocation(300, 250);
setVisible(true);
setResizable(false);
}
}