近来学习Graphics类,以及绘图方法,做了一个小程序,运行结果如下(按钮部分是ps做出来的图片):
代码如下:
- public class TestDrawPicture extends JFrame {
- private static final long serialVersionUID = 2L;
- private JSplitPane mainJsp;
- private JSplitPane jsp;
- private MenuPane mp = new MenuPane();
- static Waveform dl;
- public TestDrawLine() {
- dl = new Waveform();
- setTitle("电磁波");
- setBounds(200, 100, 810, 500);
- jsp = new JSplitPane();
- jsp.setLeftComponent(new Manager());
- jsp.setRightComponent(dl);
- jsp.setDividerLocation(220);
- jsp.setDividerSize(1);
- jsp.setEnabled(false);
- mainJsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, mp, jsp);
- mainJsp.setDividerLocation(60);
- mainJsp.setDividerSize(1);
- mainJsp.setEnabled(false);
- add(mainJsp,BorderLayout.CENTER);
- this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- setResizable(false);
- setVisible(true);
- }
- public static void main(String[] args) {
- new TestDrawLine();
- }
- }
- class MenuPane extends JPanel {
- /*
- * 菜单面板
- */
- private static String cmd = "正弦波";
- static boolean state = false; //状态是否改变,以便重绘
- private static final long serialVersionUID = 3L;
- private JButton[] btnMenu = {
- new JButton(new ImageIcon("image/zxb.png")),
- new JButton(new ImageIcon("image/yxb.png")),
- new JButton(new ImageIcon("image/fb.png")),
- new JButton(new ImageIcon("image/jcb.png")),
- new JButton(new ImageIcon("image/mcb.png"))
- };
- public MenuPane() {
- setLayout(new GridLayout(0,7,20,0));
- setBackground(new Color(171, 130, 255));
- this.setSize(getWidth()-800, 70);
- for(int i=0; i<btnMenu.length; i++) {
- btnMenu[i].setBackground(new Color(171, 130, 255));
- btnMenu[i].setBorderPainted(false);
- btnMenu[i].addActionListener(new BtnMenuListener());
- add(btnMenu[i]);
- }
- }
- private void setCmd(String _cmd) { //对外不提供接口
- cmd = _cmd;
- }
- public String getCmd() {
- return cmd;
- }
- public void setState(boolean bool) {
- state = bool;
- }
- public boolean getState() {
- return state;
- }
- class BtnMenuListener implements ActionListener {
- public void actionPerformed(ActionEvent e) {
- if(e.getSource() == btnMenu[0]) {
- setCmd("正弦波");
- }
- if(e.getSource() == btnMenu[1]) {
- setCmd("余弦波");
- }
- if(e.getSource() == btnMenu[2]) {
- setCmd("方波");
- }
- if(e.getSource() == btnMenu[3]) {
- setCmd("锯齿波");
- }
- if(e.getSource() == btnMenu[4]) {
- setCmd("脉冲波");
- }
- setState(true);
- }
- }
- }
- class Manager extends JPanel {
- /*
- * 绘图管理面板
- */
- private static final long serialVersionUID = 2L;
- private JSlider hSlider; //水平滚动条
- private JLabel hLabel; //水平偏移量标签
- private JLabel hTips; //水平调节方式标签
- private JComboBox hcb; //水平调节方式选择
- private JPanel hPanel; //水平相关面板
- private JTextField hPosText; //水平偏移量值
- private JSlider vSlider; //垂直滚动条
- private JLabel vLabel; //垂直偏移量标签
- private JComboBox vcb; //垂直调节方式选择
- private JLabel vTips; //垂直调节方式标签
- private JPanel vPanel; //垂直相关面板
- private JTextField vPosText; //垂直偏移量值
- private int wayOfSwitchH; //水平调节方式
- private int wayOfSwitchV; //垂直调节方式
- private static int hPosValue = 0;
- private static int vPosValue = 0;
- private JButton[] btn = {
- new JButton(new ImageIcon("image/left.jpg")),
- new JButton(new ImageIcon("image/right.jpg")),
- new JButton(new ImageIcon("image/left.jpg")),
- new JButton(new ImageIcon("image/right.jpg"))
- };
- static boolean state = false; //状态是否改变,以便重绘
- public Manager() {
- setLayout(new GridLayout(2,0));
- String[] item = {"默认比例","放大2倍","缩小2倍"};
- {
- wayOfSwitchH = 0; //默认比例
- wayOfSwitchV = 0;
- TitledBorder tb = new TitledBorder(BorderFactory.createLineBorder(new Color(255, 0, 0)),"水平中心位置");
- tb.setTitleColor(Color.blue);
- hPanel = new JPanel(null);
- hPanel.setBorder(tb);
- hLabel = new JLabel("偏移量:");
- hLabel.setBounds(25, 150, 80, 20);
- hTips = new JLabel("调节方式");
- hTips.setBounds(25, 30, 80, 20);
- hcb = new JComboBox(item);
- hcb.addItemListener(new CbxListener());
- hcb.setBounds(100, 30, 80, 20);
- hPosText = new JTextField("0");
- hPosText.setEditable(false);
- hPosText.setBounds(100, 150, 80, 20);
- hPosText.setHorizontalAlignment(JTextField.CENTER);
- btn[0].setBounds(18,75,12,25);
- btn[0].addActionListener(new BtnActionListener());
- btn[1].setBounds(185,75,12,25);
- btn[1].addActionListener(new BtnActionListener());
- hSlider = new JSlider(-50, 50, 0);
- hSlider.setBounds(30, 75, 155, 50);
- hSlider.setPaintTicks(true);
- hSlider.setMajorTickSpacing(25);
- hSlider.setMinorTickSpacing(5);
- hSlider.setPaintLabels(true);
- //为调节水平滚动条添加监听器
- hSlider.addChangeListener(new SliderHandler());
- hPanel.add(hLabel);
- hPanel.add(hTips);
- hPanel.add(hcb);
- hPanel.add(hPosText);
- hPanel.add(btn[0]);
- hPanel.add(btn[1]);
- hPanel.add(hSlider);
- add(hPanel);
- }
- {
- TitledBorder tb = new TitledBorder(BorderFactory.createLineBorder(new Color(255, 0, 0)),"水平中心位置");
- tb.setTitleColor(Color.blue);
- vPanel = new JPanel(null);
- vPanel.setBorder(tb);
- vLabel = new JLabel("偏移量:");
- vLabel.setBounds(25, 150, 80, 20);
- vTips = new JLabel("调节方式");
- vTips.setBounds(25, 30, 80, 20);
- vcb = new JComboBox(item);
- vcb.addItemListener(new CbxListener());
- vcb.setBounds(100, 30, 80, 20);
- vPosText = new JTextField("0");
- vPosText.setEditable(false);
- vPosText.setBounds(100, 150, 80, 20);
- vPosText.setHorizontalAlignment(JTextField.CENTER);
- btn[2].setBounds(18,75,12,25);
- btn[2].addActionListener(new BtnActionListener());
- btn[3].setBounds(185,75,12,25);
- btn[3].addActionListener(new BtnActionListener());
- vSlider = new JSlider(-50, 50, 0);
- vSlider.setBounds(30, 75, 155, 50);
- vSlider.setPaintTicks(true);
- vSlider.setMajorTickSpacing(25);
- vSlider.setMinorTickSpacing(5);
- vSlider.setPaintLabels(true);
- //为调节垂直滚动条添加监听器
- vSlider.addChangeListener(new SliderHandler());
- vPanel.add(vLabel);
- vPanel.add(vTips);
- vPanel.add(vcb);
- vPanel.add(vPosText);
- vPanel.add(btn[2]);
- vPanel.add(btn[3]);
- vPanel.add(vSlider);
- add(vPanel);
- }
- }
- public int getHposValue() {
- return hPosValue;
- }
- public int getVposValue() {
- return vPosValue;
- }
- public void setState(boolean bool) {
- state = bool;
- }
- public boolean getState() {
- return state;
- }
- class SliderHandler implements ChangeListener { //对滚动条进行监听
- /*
- * 实时对滚动条进行监听,并及时在数值文本框显示信息
- * 当选择调节方式变时,应及时更新显示的数值
- */
- public void stateChanged(ChangeEvent ce) {
- if(wayOfSwitchH == 0) {
- hPosText.setText(""+hSlider.getValue());
- } else if(wayOfSwitchH == 1) {
- hPosText.setText(""+hSlider.getValue()*2);
- } else {
- hPosText.setText(""+hSlider.getValue()/2);
- }
- hPosValue = Integer.parseInt(hPosText.getText());
- if(wayOfSwitchV == 0) {
- vPosText.setText(""+vSlider.getValue());
- } else if(wayOfSwitchV == 1) {
- vPosText.setText(""+vSlider.getValue()*2);
- } else {
- vPosText.setText(""+vSlider.getValue()/2);
- }
- vPosValue = Integer.parseInt(vPosText.getText());
- state = true; //得到一个状态改变的消息
- }
- }
- class CbxListener implements ItemListener { //对下拉列表进行监听
- /*
- * 对下拉列表进行实时监听,并及时在数值文本框显示信息
- * 当选择调节方式变时,应及时更新显示的数值
- */
- public void itemStateChanged(ItemEvent e) {
- state = true;
- if(e.getSource() == hcb) {
- wayOfSwitchH = hcb.getSelectedIndex();
- if(wayOfSwitchH == 0) {
- hPosText.setText(""+hSlider.getValue());
- } else if(wayOfSwitchH == 1) {
- hPosText.setText(""+hSlider.getValue()*2);
- } else {
- hPosText.setText(""+hSlider.getValue()/2);
- }
- hPosValue = Integer.parseInt(hPosText.getText());
- }
- if(e.getSource() == vcb) {
- wayOfSwitchV = vcb.getSelectedIndex();
- if(wayOfSwitchV == 0) {
- vPosText.setText(""+vSlider.getValue());
- } else if(wayOfSwitchV == 1) {
- vPosText.setText(""+vSlider.getValue()*2);
- } else {
- vPosText.setText(""+vSlider.getValue()/2);
- }
- vPosValue = Integer.parseInt(vPosText.getText());
- }
- }
- }
- class BtnActionListener implements ActionListener { //对四个按钮进行监听
- /*
- * 以上三个监听器实现了信息的同步更新,但是代码冗余量较高
- */
- public void actionPerformed(ActionEvent e) {
- int hPos, vPos;
- hPos = hSlider.getValue();
- vPos = vSlider.getValue();
- state = true;
- if(e.getSource()==btn[0]) {
- hPos--;
- hSlider.setValue(hPos);
- if(wayOfSwitchH == 0) {
- hPosText.setText(""+hSlider.getValue());
- } else if(wayOfSwitchH == 1) {
- hPosText.setText(""+hSlider.getValue()*2);
- } else {
- hPosText.setText(""+hSlider.getValue()/2);
- }
- }
- if(e.getSource()==btn[1]) {
- hPos++;
- hSlider.setValue(hPos);
- if(wayOfSwitchH == 0) {
- hPosText.setText(""+hSlider.getValue());
- } else if(wayOfSwitchH == 1) {
- hPosText.setText(""+hSlider.getValue()*2);
- } else {
- hPosText.setText(""+hSlider.getValue()/2);
- }
- }
- if(e.getSource()==btn[2]) {
- vPos--;
- vSlider.setValue(vPos);
- if(wayOfSwitchV == 0) {
- vPosText.setText(""+vSlider.getValue());
- } else if(wayOfSwitchV == 1) {
- vPosText.setText(""+vSlider.getValue()*2);
- } else {
- vPosText.setText(""+vSlider.getValue()/2);
- }
- }
- if(e.getSource()==btn[3]) {
- vPos++;
- vSlider.setValue(vPos);
- if(wayOfSwitchV == 0) {
- vPosText.setText(""+vSlider.getValue());
- } else if(wayOfSwitchV == 1) {
- vPosText.setText(""+vSlider.getValue()*2);
- } else {
- vPosText.setText(""+vSlider.getValue()/2);
- }
- }
- }
- }
- }
- class Waveform extends JPanel implements Runnable {
- /*
- * 绘图面板
- */
- private static final long serialVersionUID = 1L;
- private Point start;
- private Point end;
- private Point temp = null;
- static int p = -300;
- private MenuPane menuPaint = new MenuPane(); //得到菜单栏的一个引用
- private Manager mgr = new Manager(); //得到管理面板的一个引用
- public Waveform() {
- setBackground(Color.BLACK);
- setBorder(BorderFactory.createEtchedBorder());
- new Thread(this).start(); //自身启动这个线程
- }
- public void paint(Graphics g) {
- super.paint(g);
- Color c = g.getColor(); //记录当前画笔颜色,以便恢复现场
- setBorder(BorderFactory.createEtchedBorder());
- g.fillRect(0, 0, this.getWidth(), this.getHeight());
- g.setColor(Color.red);
- start = new Point(0, 80);
- end = new Point(0, 80);
- g.setColor(Color.BLUE);
- for(int i=0; i<1000; i+=25) { //绘制坐标轴
- g.drawLine(0, i, 1000, i);
- g.drawLine(i, 0, i, 1000);
- }
- g.setColor(Color.RED);
- for(int i=25,x=-100; i<=550; i+=25,x+=10) { //绘制x坐标显示的值
- g.drawString(""+x, i+1, 202);
- }
- for(int i=23,y=70; i<=400; i+=25,y-=10) { //绘制y坐标显示的值
- g.drawString(""+y, 277, i+4);
- }
- g.setColor(Color.GREEN);
- if(menuPaint.getCmd() == "正弦波") {
- for(int x = p; x<1000; x++) { //绘制曲线
- temp = new Point(x+mgr.getHposValue(), mgr.getVposValue()+80+(int)(40*Math.sin(Math.PI*(x-80)/30)));
- g.drawLine(start.x, start.y, end.x, end.y);
- g.drawLine(790-start.x, start.y+120, 790-end.x, end.y+120);
- g.drawLine(start.x, start.y+240, end.x, end.y+240);
- start = end;
- end = temp;
- }
- }
- if(menuPaint.getCmd() == "余弦波") {
- for(int x = p; x<1000; x++) { //绘制曲线
- temp = new Point(x+15+mgr.getHposValue(), mgr.getVposValue()+80+(int)(40*Math.sin(Math.PI*(x-80)/30)));
- g.drawLine(start.x, start.y, end.x, end.y);
- g.drawLine(790-start.x, start.y+120, 790-end.x, end.y+120);
- g.drawLine(start.x, start.y+240, end.x, end.y+240);
- start = end;
- end = temp;
- }
- }
- if(menuPaint.getCmd() == "方波") {
- //GraphicsEnvironment em = GraphicsEnvironment.getLocalGraphicsEnvironment();
- //String[] fontNames = em.getAvailableFontFamilyNames();
- g.setFont(new Font("华文行楷", Font.BOLD, mgr.getHposValue()+50));
- g.drawString("方波波形", 60, mgr.getVposValue()*5+50);
- }
- if(menuPaint.getCmd() == "锯齿波") {
- for(int x = p; x<1000; x++) { //绘制曲线
- temp = new Point(x+mgr.getHposValue(), mgr.getVposValue()+60+(int)(60*(x*0.02-(int)(x*0.02))));
- g.drawLine(start.x, start.y, end.x, end.y);
- g.drawLine(790-start.x, start.y+120, 790-end.x, end.y+120);
- g.drawLine(start.x, start.y+240, end.x, end.y+240);
- start = end;
- end = temp;
- }
- }
- if(menuPaint.getCmd() == "脉冲波") {
- g.setFont(new Font("华文行楷", Font.BOLD, 100));
- g.drawString("脉冲波", 100, 200);
- }
- g.setColor(c); //恢复画笔颜色
- }
- public void run() {
- try {
- while(true) {
- Thread.sleep(10);
- repaint(); //一直重绘
- // if(menuPaint.getState()) { //当条件改变时才重绘
- // repaint();
- // menuPaint.setState(false);
- // }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- class Point {
- int x, y;
- public Point(int _x, int _y) {
- x = _x;
- y = _y;
- }
- }
- }
由于没来得及学习设计模式,也不懂所谓的MVC,但是请教过MVC,不知道自己写的符合不符合MVC,由于只是为了学习,
所以并没有像做一个软件一样刻意去完成某项功能,均是实现为止。至于paint方法里面画的内容均是随便玩而已,关键是有
一点就是多线程实现监听,我最初的想法是监听状态的改变来实现repaint(),主要考虑到一直重绘浪费系统资源(注释掉的
部分代码),但是效果不太理想,所以就直接一直重绘了。