⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fitinput.java

📁 用Java开发的实用数学建模程序 简单易懂 初学者可以用来学习java知识
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 *@(#)FitInput.java 2.0 2005/05/04
 *
 *清华大学 精密仪器与机械学系
 *范灿升 fancansheng@163.com
 */

package input;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.io.*;
import java.util.Vector;
//导入系统类

import lib.Library;
import lib.DataFileFilter;
import lib.InvalidFileFormatException;
import algorithm.Fit;
import plot.ViewPlotFrame;
import function.LinearFunction;
import function.PolynomialFunction;
//导入自定义的类

/**
 *该类所提供的方法是供给类{@link Modeling}调用的,用以产生拟合与插值的数据输入界面。
 *@version 2.0, 2005/05/04
 *@author 范灿升
 *@see Modeling
 *@see algorithm.Fit
 */

public class FitInput implements ActionListener,FocusListener
{
	private int i,j;
	private int n,m;//n是回归方程中自变量的数目,m是数据的组数
	private Vector textFieldVector;//只要是新建的JTextField,都把它加入该向量,里面的元素为JTextField[]
	private Vector checkBoxVector;//只要是新建的JCheckBox,都把它加入该向量,里面的元素为JCheckBox
	private JTextField[] tempTextField;//为了方便把JTextField加入上述向量方便而建的临时变量
	private JCheckBox tempCheckBox;//为了方便把JCheckBox加入上述向量方便而建的临时变量
	private int textFieldCount;//标记已经产生多少个JTextField
	private boolean multiInput;//标记是一元拟合还是多元拟合
	private boolean[] selected;//标记JCheckBox是否被选中
	private double[][] xMatrix;
	private double[] yMatrix;
	private double[] xData;
	private JButton multiButton;
	private JButton multiHelpButton;
	private JButton oneButton;
	private JButton saveButton;
	private JButton openButton;
	private JButton oneHelpButton;
	private JComboBox comboBox;
	private String tmp;
	private boolean pass;
	private boolean secondTime;
	
	/**
	 *输入面板的父组件。
	 */
	public Component parentComponent;
	
	/**
	 *数据在该面板上输入,包括自变量与因变量的数据。
	 */
	public JPanel inputPanel;
	
	/**
	 *用来放置计算按钮和帮助按钮等。
	 */
	public JPanel computePanel;
	
	/**
	 *用来放置inputPanel的容器。
	 */
	public JPanel mainPanel;

	/**
	 *产生包含方程组相关参数的类。
	 *@param parentComponent	输入面板的上一层组件
	 *@param inputPanel			数据在该面板上输入
	 *@param computePanel		面板上的按钮为计算用按钮
	 *@param mainPanel			mainPanel是用来放置inputPanel的容器
	 */
	public FitInput(Component parentComponent,JPanel inputPanel,JPanel computePanel,JPanel mainPanel)
	{
		this.parentComponent=parentComponent;
		this.inputPanel=inputPanel;
		this.computePanel=computePanel;
		this.mainPanel=mainPanel;
	}
	
	/**
	 *显示多元线性回归的数据输入界面。
	 *<p>用户从该界面输入数据中的自变量和因变量。
	 */
	public void showMulti()
	{
		multiInput=true;
		
		pass=false;//用于标记是否通过合法性检验
		secondTime=false;
		
		while(!pass)
		{
			if(secondTime==true)
				tmp=JOptionPane.showInputDialog(parentComponent,"请输入一个不少于2的整数!\n请重新输入:","输入自变量数目",JOptionPane.WARNING_MESSAGE);
			else
				tmp=JOptionPane.showInputDialog(parentComponent,"请输入回归方程中自变量的数目:","输入自变量数目",JOptionPane.QUESTION_MESSAGE);
			try
			{
				if(tmp==null)
					return;
				n=-1;
				n=Integer.parseInt(tmp);
			}
			catch(NumberFormatException e)
			{
				secondTime=true;
			}
			if(n>=2)
				pass=true;
			else
				secondTime=true;
		}
		//输入自变量数目
		
		GridLayout inputPanelLayout=new GridLayout(0,n+2);//n个自变量,一个因变量和一个JCheckBox
		inputPanel.setLayout(inputPanelLayout);
		inputPanel.removeAll();
		JLabel[] variableLabel=new JLabel[n+2];
		variableLabel[0]=new JLabel("y",JLabel.CENTER);
		variableLabel[0].setFont(Library.font);
		inputPanel.add(variableLabel[0]);
		for(i=1;i<variableLabel.length-1;i++)
		{
			variableLabel[i]=new JLabel("x"+i,JLabel.CENTER);
			variableLabel[i].setFont(Library.font);
			inputPanel.add(variableLabel[i]);
		}
		variableLabel[n+1]=new JLabel("使用数据",JLabel.CENTER);
		variableLabel[n+1].setFont(Library.font);
		inputPanel.add(variableLabel[n+1]);
		//往输入面板中添加标签
		
		textFieldVector=new Vector();
		checkBoxVector=new Vector();
		textFieldCount=0;
		tempTextField=new JTextField[n+1];
		textFieldCount++;
		tempTextField[0]=new JTextField(Library.TEXTFIELD_LENGTH);
		tempTextField[0].setToolTipText("第"+textFieldCount+"组:y");
		inputPanel.add(tempTextField[0]);
		for(i=1;i<tempTextField.length;i++)//自变量的下标从1开始
		{
			tempTextField[i]=new JTextField(Library.TEXTFIELD_LENGTH);
			tempTextField[i].setToolTipText("第"+textFieldCount+"组:x"+i);
			inputPanel.add(tempTextField[i]);
		}
		textFieldVector.add(tempTextField);
		tempCheckBox=new JCheckBox("使用",false);
		tempCheckBox.setFont(Library.font);
		inputPanel.add(tempCheckBox);
		checkBoxVector.add(tempCheckBox);
		//往输入面板中添加输入域
		tempTextField[tempTextField.length-1].addFocusListener(this);
		
		TitledBorder border=new TitledBorder("输入数据点数据");
		border.setTitleFont(Library.font);
		inputPanel.setBorder(border);
		
		BoxLayout computePanelLayout=new BoxLayout(computePanel,BoxLayout.X_AXIS);
		computePanel.setLayout(computePanelLayout);
		
		multiButton=new JButton("多元线性回归",new ImageIcon(Library.polyhedronIcont_Scaled));
		multiButton.setFont(Library.font);
		computePanel.removeAll();
		computePanel.add(multiButton);
		multiHelpButton=new JButton("帮助",new ImageIcon(Library.helpIcon_Scaled));
		multiHelpButton.setFont(Library.font);
		computePanel.add(multiHelpButton);
		
		JScrollPane scrollPane=new JScrollPane(inputPanel);
		mainPanel.removeAll();
		mainPanel.add(scrollPane,BorderLayout.CENTER);
		mainPanel.add(computePanel,BorderLayout.SOUTH);
		//布局
		
		multiButton.addActionListener(this);
		multiHelpButton.addActionListener(this);
		
		parentComponent.setSize(parentComponent.getPreferredSize());
		parentComponent.setVisible(true);
	}
	
	/**
	 *显示一元拟合的数据输入界面,包括一元线性回归、多项式回归、三次样条插值。
	 *<p>用户从该界面输入数据中的自变量和因变量。
	 */
	public void showOne()
	{
		multiInput=false;
		
		n=1;//为了与多元线性回归的输入程序代码一致,这里采用直接对n赋值的方法
		GridLayout inputPanelLayout=new GridLayout(0,n+2);//一个自变量,一个因变量和一个JCheckBox
		inputPanel.setLayout(inputPanelLayout);
		inputPanel.removeAll();
		JLabel[] variableLabel=new JLabel[n+2];
		variableLabel[0]=new JLabel("y",JLabel.CENTER);
		variableLabel[0].setFont(Library.font);
		inputPanel.add(variableLabel[0]);
		variableLabel[n]=new JLabel("x",JLabel.CENTER);
		variableLabel[n].setFont(Library.font);
		inputPanel.add(variableLabel[n]);
		variableLabel[n+1]=new JLabel("使用数据",JLabel.CENTER);
		variableLabel[n+1].setFont(Library.font);
		inputPanel.add(variableLabel[n+1]);
		//往输入面板中添加标签
		
		textFieldVector=new Vector();
		checkBoxVector=new Vector();
		textFieldCount=0;
		tempTextField=new JTextField[n+1];
		textFieldCount++;
		tempTextField[0]=new JTextField(Library.TEXTFIELD_LENGTH);
		tempTextField[0].setToolTipText("第"+textFieldCount+"组:y");
		inputPanel.add(tempTextField[0]);
		tempTextField[n]=new JTextField(Library.TEXTFIELD_LENGTH);
		tempTextField[n].setToolTipText("第"+textFieldCount+"组:x");
		inputPanel.add(tempTextField[n]);
		textFieldVector.add(tempTextField);
		tempCheckBox=new JCheckBox("使用",false);
		tempCheckBox.setFont(Library.font);
		inputPanel.add(tempCheckBox);
		checkBoxVector.add(tempCheckBox);
		//往输入面板中添加输入域
		tempTextField[tempTextField.length-1].addFocusListener(this);
		
		TitledBorder border=new TitledBorder("输入数据点数据");
		border.setTitleFont(Library.font);
		inputPanel.setBorder(border);
		
		BoxLayout computePanelLayout=new BoxLayout(computePanel,BoxLayout.Y_AXIS);
		computePanel.setLayout(computePanelLayout);
		
		computePanel.removeAll();
		String[] comboBoxString={"选择处理类型","一元线性回归","多项式回归"
				/////////////////
				//,"三次样条插值"
				/////////////////
				};
		comboBox=new JComboBox(comboBoxString);
		comboBox.setFont(Library.font);
		computePanel.add(comboBox);
		oneButton=new JButton("数据分析",new ImageIcon(Library.polyhedronIcont_Scaled));
		oneButton.setFont(Library.font);
		computePanel.add(oneButton);
		saveButton=new JButton("保存数据",new ImageIcon(Library.aidIcon_Scaled));
		saveButton.setFont(Library.font);
		computePanel.add(saveButton);
		openButton=new JButton("导入数据",new ImageIcon(Library.aidIcon_Scaled));
		openButton.setFont(Library.font);
		computePanel.add(openButton);
		oneHelpButton=new JButton(" 帮  助 ",new ImageIcon(Library.helpIcon_Scaled));
		oneHelpButton.setFont(Library.font);
		computePanel.add(oneHelpButton);
		comboBox.setMaximumSize(new Dimension(oneButton.getPreferredSize().width,comboBox.getPreferredSize().height));
		comboBox.setAlignmentX(0);
		
		JScrollPane scrollPane=new JScrollPane(inputPanel);
		mainPanel.removeAll();
		mainPanel.add(scrollPane,BorderLayout.CENTER);
		mainPanel.add(computePanel,BorderLayout.EAST);
		//布局
		
		oneButton.addActionListener(this);
		saveButton.addActionListener(this);
		openButton.addActionListener(this);
		oneHelpButton.addActionListener(this);
		
		parentComponent.setSize(parentComponent.getPreferredSize());
		parentComponent.setVisible(true);
	}
	
	/**
	 *由ActionListener所指定的方法,响应用户单击按钮时的动作
	 *@param e		单击按钮所产生的事件
	 */
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource()==multiButton)
		{
			m=0;
			selected=new boolean[textFieldCount];
			for(i=0;i<textFieldCount;i++)
			{
				if(((JCheckBox)checkBoxVector.get(i)).isSelected())
				{
					selected[i]=true;
					m++;
				}
				else
					selected[i]=false;
			}
			//统计应该使用哪些数据
			yMatrix=new double[m];
			xMatrix=new double[m][n+1];//由于常数项的存在,xMatrix的第1列恒为1
			int index=0;
			
			if(m<n+1)
			{
				JOptionPane.showMessageDialog(parentComponent,"所选的数据的组数必须不小于"+(n+1),"数据不足",JOptionPane.WARNING_MESSAGE);
				return;
			}
			
			for(i=0;i<textFieldCount;i++)
			{
				if(selected[i])
				{
					for(j=0;j<n+1;j++)
					{
						try
						{
							if(j==0)
							{
								yMatrix[index]=Double.parseDouble(((JTextField[])textFieldVector.get(i))[j].getText());
								xMatrix[index][0]=1;
							}
							else
								xMatrix[index][j]=Double.parseDouble(((JTextField[])textFieldVector.get(i))[j].getText());
						}
						catch(NumberFormatException nException)
						{
							if(j==0)
								tmp="第"+(i+1)+"组数据的y值不是有效的数字!\n如果不需要这组数据,请把复选框中的勾去掉。";
							else
								tmp="第"+(i+1)+"组数据的x"+j+"的值不是有效的数字!\n如果不需要这组数据,请把复选框中的勾去掉。";
							JOptionPane.showMessageDialog(parentComponent,tmp,"输入错误",JOptionPane.WARNING_MESSAGE);
							return;
						}
					}
					index++;//index和i是很不相同的
				}
			}
			//完成值的传递
			
			try
			{
				Fit multiFit=new Fit(xMatrix,yMatrix);
				double[] result=multiFit.multiFit();
				StringBuffer buffer=new StringBuffer("相关系数为"+(float)result[result.length-1]+"\n");
				buffer.append("回归方程为:\n");
				buffer.append("y = "+(float)result[0]);
				for(i=1;i<result.length-1;i++)
				{
					if(result[i]>=0)
						buffer.append("+"+(float)result[i]+" * x"+i);
					else if(result[i]<0)
						buffer.append((float)result[i]+" * x"+i);
					//处理正负号
					if(i%3==0)
						buffer.append("\n");
				}
				JOptionPane.showMessageDialog(parentComponent,buffer,
						"回归分析结果",JOptionPane.INFORMATION_MESSAGE,new ImageIcon(Library.polyhedronIcont_Scaled));
			}//把double在显示时转换为float显示效果会好一点
			catch(NullPointerException nullE)
			{
				JOptionPane.showMessageDialog(parentComponent,
						"数据有误。\n适合数据的回归方程有无穷多个。\n请重新检查数据!","数据错误",JOptionPane.WARNING_MESSAGE);
			}
			//显示求解结果
		}
		//multiButton的动作
		
		if(e.getSource()==multiHelpButton)
		{
			ImageIcon helpMessage=new ImageIcon("resource\\MultiFitHelp.GIF");
			JOptionPane.showMessageDialog(parentComponent,helpMessage,"输入帮助",JOptionPane.INFORMATION_MESSAGE,new ImageIcon(Library.helpIcon_Scaled));
		}
		
		if(e.getSource()==oneButton)
		//一元拟合
		{
			m=0;
			selected=new boolean[textFieldCount];
			for(i=0;i<textFieldCount;i++)
			{
				if(((JCheckBox)checkBoxVector.get(i)).isSelected())
				{
					selected[i]=true;
					m++;
				}
				else
					selected[i]=false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -