import java.awt.*;
//import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import javax.swing.*;
public class PCTest extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String[] args){
PCTestFrame frame=new PCTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
}
}
class PCTestFrame extends JFrame{
private static final long serialVersionUID = 1L;
public PCTestFrame(){
setTitle("Pxg→生产者〓消费者");
setSize(DEFAULT_W,DEFAULT_H);
Image icon=Toolkit.getDefaultToolkit().getImage("icon.jpg");
setIconImage(icon);
int screenH=Toolkit.getDefaultToolkit().getScreenSize().height;
int screenW=Toolkit.getDefaultToolkit().getScreenSize().width;
setLocation((screenW-DEFAULT_W)/2, (screenH-DEFAULT_H)/2);
GridBagLayout layout=new GridBagLayout();
setLayout(layout);
//ActionListener listener=new FontAction();
//construct componets
JLabel maxCLable=new JLabel("仓库容量:");
maxContainerField=new JTextField("",3);
JLabel nowCLable=new JLabel("仓库现存:");
nowContainerField=new JTextField("",3);
JLabel producterNLabel=new JLabel("生产者数:");
producterNumField=new JTextField("",3);
JLabel consumerNLabel=new JLabel("消费者数:");
consumerNumField=new JTextField("",3);
JLabel productNLabel=new JLabel("生产数量:");
productNumField=new JTextField("",20);
JLabel consumeNLabel=new JLabel("消费数量:");
consumeNumField=new JTextField("",20);
JButton okButton=new JButton("提 交");
JButton cancelButton=new JButton("恢复");
JButton startButton=new JButton("开始线程");
JButton stopButton=new JButton("重绘仓库");
pcPanel=new PCTestPanel();
pcPanel.setBorder(BorderFactory.createEtchedBorder());
explainArea=new JTextArea();
explainArea.setEditable(false);
explainArea.setLineWrap(true);
explainArea.setBorder(BorderFactory.createEtchedBorder());
//explainArea.set
add(maxCLable,new GBC(0,0).setAnchor(GBC.EAST));
add(maxContainerField,new GBC(1,0).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(producterNLabel,new GBC(2,0).setAnchor(GBC.EAST));
add(producterNumField,new GBC(3,0).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(productNLabel,new GBC(4,0).setAnchor(GBC.EAST));
add(productNumField,new GBC(5,0,2,1).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(okButton,new GBC(7,0).setFill(GBC.HORIZONTAL));
add(nowCLable,new GBC(0,1).setAnchor(GBC.EAST));
add(nowContainerField,new GBC(1,1).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(consumerNLabel,new GBC(2,1).setAnchor(GBC.EAST));
add(consumerNumField,new GBC(3,1).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(consumeNLabel,new GBC(4,1).setAnchor(GBC.EAST));
add(consumeNumField,new GBC(5,1,2,1).setFill(GBC.HORIZONTAL).setWeight(100,0).setInsets(1));
add(cancelButton,new GBC(7,1).setFill(GBC.HORIZONTAL));
add(startButton,new GBC(0,2,2,1).setAnchor(GBC.CENTER).setWeight(100, 80));
add(stopButton,new GBC(0,5,2,1).setAnchor(GBC.CENTER).setWeight(100, 100));
add(pcPanel,new GBC(2,2,5,6).setFill(GBC.BOTH).setWeight(100, 100));
add(explainArea,new GBC(7,2,1,4).setFill(GBC.BOTH).setWeight(100, 100));
//提交按钮事件
ActionListener okListener=new
ActionListener(){
public void actionPerformed(ActionEvent event){
setPC();
}
};
okButton.addActionListener(okListener);
//取消按钮事件
ActionListener cancelListener=new
ActionListener(){
public void actionPerformed(ActionEvent event){
maxContainerField.setText("");
nowContainerField.setText("");
producterNumField.setText("");
consumerNumField.setText("");
productNumField.setText("");
consumeNumField.setText("");
explainArea.setText("");
pcPanel.paintContainer(maxC,0);
}
};
cancelButton.addActionListener(cancelListener);
//开始线程按钮事件
ActionListener startListener=new
ActionListener(){
public void actionPerformed(ActionEvent event){
startPC();
}
};
startButton.addActionListener(startListener);
//结束线程按钮事件
ActionListener stopListener=new
ActionListener(){
public void actionPerformed(ActionEvent event){
//notifyAll();
pcPanel.paintContainer(maxC,nowC);
}
};
stopButton.addActionListener(stopListener);
}
public static final int DEFAULT_W=800;
public static final int DEFAULT_H=500;
private JTextField maxContainerField;
private JTextField nowContainerField;
private JTextField producterNumField;
private JTextField consumerNumField;
private JTextField productNumField;
private JTextField consumeNumField;
private JTextArea explainArea;
private PCTestPanel pcPanel;
public void setPC(){
maxC=Integer.parseInt(maxContainerField.getText().trim());
nowC=Integer.parseInt(nowContainerField.getText().trim());
producterN=Integer.parseInt(producterNumField.getText().trim());
consumerN=Integer.parseInt(consumerNumField.getText().trim());
productN=new int[producterN];
consumeN=new int[consumerN];
pc=new ProductContainer();
strToNum(productNumField.getText().trim(),productN,producterN);
strToNum(consumeNumField.getText().trim(),consumeN,consumerN);
s="";
}
public void startPC(){
p=new Producter[producterN];
c=new Consumer[consumerN];
for(int i=0;i p[i]=new Producter(productN[i],pc,"PRO_"+(i+1));
p[i].start();
}
for(int i=0;i c[i]=new Consumer(consumeN[i],pc,"CON_"+(i+1));
c[i].start();
}
}
public void strToNum(String str,int[] num,int len){
String ss[]=str.split(" ");
for(int i=0;i num[i]=Integer.parseInt(ss[i]);
}
}
private String s;
private int maxC;
private int nowC;
private int consumerN;
private int producterN;
private int[] productN = null;
private int[] consumeN = null;
private ProductContainer pc;
private Producter[] p;
private Consumer[] c;
class Producter extends Thread{
//produce num one time
private int produceNum;
//Producter need visit container
private ProductContainer pc;
//Non-argument Constructor
public Producter(){}
//Argument Constructor
public Producter(int produceNum,ProductContainer pc,String produceName){
//init thread
this.produceNum=produceNum;
this.pc=pc;
this.setName(produceName);
}
//producter work method
public void run(){
//load syn-method product produce
pcPanel.paintContainer(maxC,nowC);
pc.produceProduct(produceNum, this.getName());
}
}
class Consumer extends Thread{
//Consume num one time
private int ConsumeNum;
//Consumer need visit container
private ProductContainer pc;
//Non-argument Constructor
public Consumer(){}
//Argument Constructor
public Consumer(int ConsumeNum,ProductContainer pc,String ConsumeName){
//init thread
this.ConsumeNum=ConsumeNum;
this.pc=pc;
this.setName(ConsumeName);
}
//consumer work method
public void run(){
//load syn-method product produce
pcPanel.paintContainer(maxC,nowC);
pc.consumeProduct(ConsumeNum, this.getName());
}
}
class ProductContainer{
//Non-argument Constructor
public ProductContainer(){
explainArea.setText("★仓库容量:"+maxC+"★\n★仓库现存:"+nowC+"★");
explainArea.repaint();
pcPanel.paintContainer(maxC,nowC);
}
//Produce-syn-method
public synchronized void produceProduct(int produceNum,String produceName){
//Test if the produce done
while(nowC+produceNum>maxC){
//don't need produce
s+="◆"+produceName+":"+produceNum+","+produceNum+"+nowC explainArea.setText(s);
explainArea.repaint();
pcPanel.paintContainer(maxC,nowC);
try{
wait();
}
catch(Exception e){
e.printStackTrace();
}
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
}
//Produce product
nowC=nowC+produceNum;
s+="◆"+produceName+":"+produceNum+",nowC:"+nowC+"。"+produceName+" pro_Over!\n";
explainArea.setText(s);
explainArea.repaint();
pcPanel.paintContainer(maxC,nowC);
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
notifyAll();
}
public synchronized void consumeProduct(int consumeNum,String consumeName){
//Test if consume done
while(consumeNum>nowC){
//nowC s+="★"+consumeName+":"+consumeNum+","+consumeNum+">nowC。"+consumeName+" wait!\n";
explainArea.setText(s);
explainArea.repaint();
pcPanel.paintContainer(maxC,nowC);
try{
wait();
}
catch(Exception e){
e.printStackTrace();
}
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
}
//Consume
nowC=nowC-consumeNum;
s+="★"+consumeName+":"+consumeNum+",nowC:"+nowC+"。"+consumeName+" con_Over!\n";
explainArea.setText(s);
explainArea.repaint();
pcPanel.paintContainer(maxC,nowC);
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
notifyAll();
}
}
}
class PCTestPanel extends JPanel{
private static final long serialVersionUID = 1L;
public void paintContainer(int maxH,int nowH){
Graphics g=getGraphics();
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
double nowHeight=(double)(nowH*height/maxH);
LeftX=(getWidth()-width)/2-20;
maxTopY=(getHeight()-height)/2;
nowTopY=maxTopY+height-nowHeight;
Rectangle2D rectMaxContainer=new Rectangle2D.Double(LeftX,maxTopY,width,height);
g2.setPaint(new Color(255,0,0));
g2.draw(rectMaxContainer);
Rectangle2D rectNowContainer=new Rectangle2D.Double(LeftX,nowTopY,width,nowHeight);
g2.setPaint(new Color(0,255,0));
g2.fill(rectNowContainer);
g2.setPaint(new Color(0,0,255));
g2.drawString("Max / "+maxH, (float)(LeftX+width+10), (float)(maxTopY+5));
if(nowH!=maxH)
g2.drawString("Now / "+nowH, (float)(LeftX+width+10), (float)(maxTopY+height-nowHeight+5));
else
g2.drawString("Now=Max / "+nowH, (float)(LeftX+width+10), (float)(maxTopY+height-nowHeight+5));
g2.drawString("仓库示意图", (float)(LeftX+110), (float)(maxTopY+height+15));
}
private double LeftX;
private double maxTopY;
private double nowTopY;
private double height=300;
private double width=280;
}