2016/04/21

本文介绍如何使用Swing创建一个简单的Java图形界面应用——学生管理系统,包括界面风格选择、容器设置及组件布局等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。
工具包中所有的包都是以swing作为名称,例如javax.swing,javax.swing.event
用Swing创建图形界面步骤:
(1)导入Swing包
(2)选择界面风格
(3)设置顶层容器
(4)设置按钮和标签
(5)将组件放到容器上
(6)为组件增加边框
(7)处理事件
(8)辅助技术支持
1。导入Swing包
下面语句导入Swing包
import javax.swing.*;
大部分Swing程序用到了AWT的基础底层结构和事件模型,因此需要导入两个包:
import java.awt.*;
import java.awt.event.*;
如果图形界面中包括了事件处理,那么还需要导入事件处理包:
import javax.swing.event.*;
2.选择界面风格
Swing允许选择程序的图形界面风格常用的有java风格,windows风格等
下面的代码用于选择图形界面风格,这里选择的是跨平台的Java界面风格。
try { UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName( )); }
catch (Exception e) { }
(3) 设置顶层容器
图形界面至少要有一个顶级Swing容器
顶级Swing容器为其它Swing组件在屏幕上的绘制和处理事件提供支持
常用的顶级容器:
JFrame(框架):表示主程序窗口
JDialog(对话框):每个JDialog对象表示一个对话框,对话框属于二级窗口
JApplet(小程序):在浏览器内显示一个小程序界面
一个框架包括边界、菜单栏、工具栏、状态栏,以及中间占主要部分的窗格
窗格也可以看作是一种面板,但它是框架的一个组成部分
组件不会直接放到框架上,而是放在若干个面板上,这些面板再放到窗格上
用框架对象的getContentPane()函数来获得窗格,再调用窗格的add()函数放置面板
public static void main(String[ ]args){JFrame frame=new JFrame("SwingApplication");
JPanel panel1=new JPanel();
frame.getContentPane().add(panel1,BorderLayout.CENTER);
......//添加其他组件
frame.pack();frame.setVisible(true);}

 

package com.wode.test;
/**
 * 学生管理系统
 */
import java.awt.Container;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class Student extends JFrame{

 public Student(String title){
  super(title);
  this.setSize(400, 300);
  this.setLocationRelativeTo(null);
  this.setLayout(null);
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setResizable(false);
  JLabel jLabelName = new JLabel("用户名:");
  JLabel jLabelpassword = new JLabel("密码:");
  JPanel jPanel = new JPanel();  
  jPanel.setLayout(null);  
  jPanel.setBounds(1, 1, 400, 300);
  jLabelName.setBounds(100, 65, 60, 20);
  jLabelpassword.setBounds(100, 120, 60, 20);
  jPanel.add(jLabelpassword);
  jPanel.add(jLabelName);
  JTextField txtName = new JTextField();
  txtName.setBounds(180, 65, 85, 20);
  jPanel.add(txtName);
  JPasswordField txtpassword = new JPasswordField();
  txtpassword.setBounds(180, 120, 85, 20);
  jPanel.add(txtpassword);
  JButton okbtn=new JButton("确定");
  okbtn.setBounds(110, 200, 60, 40);
  jPanel.add(okbtn);
  JButton cancelbtn=new JButton("取消");
  cancelbtn.setBounds(220, 200, 60, 40);
  jPanel.add(cancelbtn);
  JRadioButton supervise = new JRadioButton("管理登陆");
  supervise.setBounds(100,25, 120, 20);
  jPanel.add(supervise);
  JRadioButton studnet = new JRadioButton("学生登陆");
  studnet.setBounds(220,25, 120, 20);
  jPanel.add(studnet);
  JLabel newName = new JLabel("注册账号");
  newName.setBounds(280, 65, 60, 20);
  jPanel.add(newName);
  JLabel password = new JLabel("密码找回");
  password.setBounds(280, 120, 60, 20);
  jPanel.add(password);
  JCheckBox remember = new JCheckBox("记住密码");
  remember.setBounds(110, 160, 110, 20);
  jPanel.add(remember);
  JCheckBox automatic = new JCheckBox("自动登陆");
  automatic.setBounds(225, 160, 110, 20);
  jPanel.add(automatic);
  this.add(jPanel);
  this.setVisible(true);
  
 }
 public static void main(String[] args) {
  new Student("学生管理系统");
 }
}

 

转载于:https://www.cnblogs.com/chenyangpeng/p/5419060.html

`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 22:42:04 05/07/2016 // Design Name: // Module Name: mul // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// //behavioral floating-point multiplication module mul (flp_a, flp_b, sign, exponent, exp_unbiased, exp_sum, prod,sum); input [31:0] flp_a, flp_b; output sign; output [7:0] exponent, exp_unbiased; output [8:0] exp_sum; output [22:0] prod; output [31:0] sum ; integer i; //variables used in an always block are declared as registers reg sign_a, sign_b; reg [7:0] exp_a, exp_b; reg [7:0] exp_a_bias, exp_b_bias; reg [8:0] exp_sum; reg [22:0] fract_a, fract_b; reg [45:0] prod_dbl; reg [22:0] prod; reg sign; reg [31:0] sum ; reg [7:0] exponent, exp_unbiased; //define sign, exponent, and fraction always @ (flp_a or flp_b) begin sign_a = flp_a[31]; sign_b = flp_b[31]; exp_a = flp_a[30:23]; exp_b = flp_b[30:23]; fract_a = flp_a[22:0]; fract_b = flp_b[22:0]; //bias exponents exp_a_bias = exp_a + 8'b0111_1111; exp_b_bias = exp_b + 8'b0111_1111; //add exponents exp_sum = exp_a_bias + exp_b_bias; //remove one bias exponent = exp_sum - 8'b0111_1111; exp_unbiased = exponent - 8'b0111_1111; //multiply fractions //if (flp_a != 0 || flp_b!=0) begin prod_dbl = fract_a * fract_b; prod = prod_dbl[45:23]; if (prod == 0) begin sum = 32'b0; end else begin for (i = 0; i < 22; i = i + 1) begin if (prod[22] == 0) begin prod = prod << 1; exp_unbiased = exp_unbiased - 1; end end end sign = sign_a ^ sign_b; if (prod ==0) begin sum =32'b0; end else sum ={sign, exp_unbiased, prod}; end // always @(posedge clk ) begin // if(rst) begin // result <= 0; // inp_north <= flp_a; // inp_west <= flp_b; // outp_east <= 0; // outp_south <= 0; // end // else if( alu_start )begin // multi <= inp_north*inp_west; // result <= result + sum; // outp_east <= inp_west; // outp_south <= inp_north; // end // end //end endmodulej解释
最新发布
03-13
<think>嗯,我现在要理解这个Verilog模块mul的功能。看起来这是一个浮点数乘法器的行为级实现。首先,输入是两个32位的浮点数flp_a和flp_b,输出包括符号位sign、指数exponent、无偏指数exp_unbiased、指数和exp_sum、乘积prod以及最终的sum。 首先,模块的输入是两个32位的数,这应该对应单精度浮点数,符合IEEE 754标准。每个32位浮点数由1位符号位、8位指数位和23位尾数位组成。接下来,模块的输出有很多,可能需要逐步分析。 在always块里,当flp_a或flp_b变化时触发。首先提取各自的符号位、指数和尾数。符号位直接取最高位,exp_a和exp_b是接下来的8位,剩下的23位是尾数fract_a和fract_b。 然后处理指数部分。原IEEE 754的指数是偏移码(bias为127),这里代码里将exp_a和exp_b加上8'b0111_1111(即127),得到exp_a_bias和exp_b_bias。然后将这两个有偏的指数相加,得到exp_sum。接着,减去一个bias(127)得到exponent,这应该是正确的乘法后的指数步骤,因为两个指数相加时需要减去一次bias,因为每个指数都是带有bias的,相加后总共有两个bias,所以需要减去一个。 然后计算无偏的指数exp_unbiased,可能用于后续处理或输出观察。接着,将两个尾数相乘,得到45位的结果prod_dbl。这里尾数是23位,相乘后应该是46位?不过代码中是23位乘23位,结果应该是45位?或者可能是24位(包括隐含的1)?这里可能需要确认。不过代码里prod_dbl是45:0,即46位,所以可能是两个24位数相乘得到48位,但这里只取了45位?或者可能代码中存在省略隐含位的处理。 然后prod取prod_dbl的高23位(45:23)。接下来,如果prod为0,sum设为0。否则,进入循环,循环22次,检查prod的最高位是否为0。如果是,就左移并减少exp_unbiased。这应该是规格化处理,确保尾数的最高位是1。但循环次数是22次,可能有问题,因为如果prod的最高位一开始是0,可能需要左移多次,但循环次数可能不够,或者应该循环直到最高位为1?或者这里的循环次数是固定的22次,但可能不正确,因为比如prod可能需要左移超过22次才能得到最高位为1? 然后,符号位是两个输入符号位的异或,符合乘法规则。最后,如果prod为0,sum设为0,否则组合符号位、无偏指数和prod作为最终的sum输出。 另外,注释里提到有一个被注释掉的always块,可能涉及时钟和复位,但当前代码中没有使用,所以可能这个模块是纯组合逻辑?不过原代码的always块没有敏感列表中的边沿,所以是组合逻辑。但原always块的触发条件是flp_a或flp_b,所以当它们变化时执行。 可能存在的一些问题: 1. 处理尾数时是否考虑了隐含的前导1?IEEE 754单精度浮点数的尾数在存储时省略了前导1,所以在实际运算时需要加上。但这段代码中的fract_a和fract_b是直接取输入的23位,可能没有处理隐含的1,导致乘法结果不正确。例如,正确的尾数应该是1.M的形式,但这里可能只处理了M部分,所以乘积的时候需要将1.M_a * 1.M_b,得到的形式可能需要在计算时添加这些隐含位。如果代码中没有处理,这可能导致错误。 2. 指数部分的处理是否正确?原代码中,将exp_a和exp_b各自加上127,得到exp_a_bias和exp_b_bias,然后将它们相加得到exp_sum,再减去127得到exponent。但是正确的步骤应该是:两个指数的真值(即exp_a - 127和exp_b - 127)相加,再加上新的偏移127。或者,当两个指数都是带有偏移的,exp_a + exp_b = (E1 + 127) + (E2 + 127) = E1 + E2 + 254,所以正确的指数应该是E1 + E2 + 127,即exp_sum - 127。这里的代码中,exponent = exp_sum - 8'b01111111,即exp_sum - 127,所以是正确的。这应该是对的。 3. 乘积后的规格化处理是否正确?在prod_dbl = fract_a * fract_b之后,prod取高23位。但正确的乘积应该是(1 + A)*(1 + B) = 1 + A + B + AB,所以结果可能大于等于4,或者在1到4之间。如果fract_a和fract_b是23位的小数部分,则乘积需要处理隐含的1。例如,假设实际的尾数是1.fract_a和1.fract_b,它们的乘积是(1 + A)*(1 + B) = 1 + A + B + AB,这会是一个在1到4之间的数。所以乘积的二进制形式可能会有两位整数部分(比如10.xxxx或11.xxxx),这时候需要右移一位,并调整指数。或者如果乘积是1.xxxx,则不需要移位。但代码中的处理是,prod_dbl = fract_a * fract_b,这似乎没有包含隐含的1,所以这可能是一个错误,导致结果不正确。 例如,正确的尾数乘积应该是(1 << 23 + fract_a) * (1 << 23 + fract_b),得到一个更大的数,然后取高位部分。但代码中直接将两个23位相乘,得到46位的结果,然后取高23位。这可能忽略了隐含的1,导致结果错误。这可能是一个关键错误。 4. 规格化循环的问题:代码中有一个循环,从i=0到i=22,共22次?循环条件是检查prod[22]是否为0,如果是,则左移一位,并减少指数。prod是23位,最高位是prod[22]。所以如果最高位是0,就左移,直到最高位是1。但循环执行了22次,不管prod的情况如何,这可能不正确。例如,如果prod的最高位一开始就是1,循环仍然会执行22次,每次检查,此时i会从0到21,但prod可能已经不需要移位了。所以这可能导致不必要的移位,或者如果prod需要移位超过22次的话,无法完成。例如,假设prod是23位的0,那么左移22次后,仍然无法得到最高位为1,这时候指数可能已经减到负数,而prod仍然为0,这会导致sum为0。这种情况可能需要处理,但代码中的循环逻辑可能存在问题。 正确的规格化应该是循环左移,直到最高位为1,或者直到所有位数都检查完,但循环次数不应固定为22次,而应该是一个动态的循环。例如,使用一个while循环,但Verilog中循环次数需要在编译时确定,所以可能需要用for循环,但次数应该足够覆盖所有可能的移位情况。比如最多23次移位,因为prod是23位,可能所有位都是0,最多移位23次。但代码中的循环只执行22次,这可能不够。 此外,在循环中,i从0到22,但条件写的是i < 22,所以循环次数是22次?因为i从0开始,到i=21结束,共22次?例如,i < 22的话,循环体执行22次,i从0到21。每次移位一次,所以总共移位22次?对于23位的prod来说,最多需要移位22次才能将最高位变为1?例如,如果prod是23'b000...001,那么需要左移22次才能让最高位为1。所以这可能正确。但如果prod在移位过程中已经最高位为1,则会提前停止移位吗?但代码中的写法是,在循环内部每次检查prod[22],如果为0则移位。然而,循环是固定执行22次,不管prod的状态。例如,假设prod在第5次移位时最高位变成1,但接下来的17次移位仍然会被执行,导致prod被左移22次,指数被减22次,这显然是错误的。所以这个循环的逻辑有问题,应该是在移位到最高位为1后立即停止,而不是继续执行剩余的循环次数。因此,这个循环的写法不正确,会导致错误的规格化。 例如,正确的处理应该是在for循环中,一旦prod的最高位为1,就break退出循环。但Verilog不支持break语句,所以需要使用其他方法,比如一个标志位来控制循环是否继续。否则,这里的循环会强制移位22次,不管实际是否需要,这会导致指数被多减去很多,从而结果错误。 5. sum的组装:最后,sum被组合为{sign, exp_unbiased, prod}。但exp_unbiased是经过调整后的指数,可能已经减去了循环中移位的次数。此时,这个指数应该是带有偏移的,即需要将exp_unbiased加上127(即存储的指数是exp_unbiased + bias)吗?原代码中的exp_unbiased是exponent - 127,而exponent是exp_sum - 127。exp_sum是exp_a_bias + exp_b_bias,其中exp_a_bias = exp_a + 127,exp_b_bias = exp_b + 127。所以 exp_sum = (exp_a + 127) + (exp_b + 127) = exp_a + exp_b + 254。然后 exponent = exp_sum - 127 = exp_a + exp_b + 127。这应该是对的,因为正确的指数应该是E1 + E2 + bias,其中E1和E2是各自的指数真值,即E1 = exp_a - 127,E2 = exp_b - 127,所以E1 + E2 + bias = (exp_a -127) + (exp_b -127) + 127 = exp_a + exp_b -127,而exponent的值是exp_a + exp_b + 127?这里可能哪里出错了? 或者原计算可能有错误。假设输入的exp_a和exp_b是IEEE 754中的指数(即存储的是E + 127)。当两个数相乘时,正确的指数应该是E1 + E2 + 127。因为 E1 = exp_a - 127, E2 = exp_b -127,所以总指数是 E1 + E2 = exp_a + exp_b - 254。因此,正确的存储的指数应该是 E1 + E2 + 127 = exp_a + exp_b -254 + 127 = exp_a + exp_b -127。 但原代码中,exp_sum是 (exp_a +127) + (exp_b +127) = exp_a + exp_b +254。然后 exponent = exp_sum - 127 = exp_a + exp_b + 254 -127 = exp_a + exp_b +127。 这显然比正确的结果多了254 -127 = 127。 所以这里明显存在错误。正确的指数应该是E1 + E2 + bias = (exp_a -127) + (exp_b -127) +127 = exp_a + exp_b -127。 但代码中得到的是exp_a + exp_b +127,这明显是错误的。所以指数处理部分存在根本性错误,导致指数计算错误。 这可能是因为原代码在计算exp_a_bias和exp_b_bias时错误地加上了bias。正确的做法应该是,当两个数的指数是带有bias的,它们的和应该是E1 + E2 + 2*bias,所以正确的总指数应该是E1 + E2 + bias = (exp_a + exp_b) + bias。 因此,正确的计算应该是:exp_sum = exp_a + exp_b,然后 exponent = exp_sum - bias。但原代码中exp_a_bias是exp_a + 127,exp_b_bias是exp_b +127,所以exp_sum = exp_a + exp_b + 254。然后 exponent = exp_sum -127 = exp_a + exp_b + 127。这明显比正确值多了254 -127 = 127。正确的应该是exp_a + exp_b -127。所以这里的指数计算错误,导致结果指数过大,无法正确表示。 因此,指数计算部分存在严重错误,可能是原代码中的误解导致的。 另一个可能的错误是在处理尾数时,没有考虑隐含的1。例如,正确的尾数应该是1.fract_a和1.fract_b,所以在相乘的时候应该先加上1<<23,然后进行乘法。例如,假设fract_a是23位,那么实际尾数是1 + fract_a/(2^23)。所以乘积应该是(1 + A)*(1 + B) = 1 + A + B + AB。而代码中直接将两个23位整数相乘,得到的结果是A*B,忽略了1 + A和1 + B的乘积。这将导致乘积结果不正确,缺少了必要的部分。因此,这部分的处理也是错误的。 总结来看,这个mul模块存在几个关键问题: 1. 指数计算错误,导致结果指数过大。 2. 尾数相乘时没有考虑隐含的前导1,导致乘积结果错误。 3. 规格化循环的逻辑错误,强制移位22次,不管实际是否需要,导致指数被错误地减少。 这些错误可能导致整个浮点乘法器的结果不正确。需要修正这些部分才能正确实现浮点乘法。</think>以下是您提供的Verilog浮点乘法模块 `mul` 的逐步分析解释: --- ### **模块功能概述** 这是一个单精度浮点数乘法器的行为级实现,遵循IEEE 754标准,输入为两个32位浮点数 `flp_a` 和 `flp_b`,输出为乘法结果的符号、指数、尾数及最终组合结果 `sum`。 --- ### **关键代码解析** #### **1. 输入输出定义** ```verilog input [31:0] flp_a, flp_b; // 输入:两个IEEE 754单精度浮点数 output sign; // 输出符号位 output [7:0] exponent; // 带偏置的指数结果 output [7:0] exp_unbiased; // 无偏置指数(调试用) output [8:0] exp_sum; // 指数求和中间值 output [22:0] prod; // 规格化后的尾数乘积 output [31:0] sum; // 最终32位浮点结果 ``` - **单精度格式**:32位 = 1位符号 + 8位指数(偏置127) + 23位尾数(隐含前导1)。 --- #### **2. 符号位与指数处理** ```verilog always @(flp_a or flp_b) begin sign_a = flp_a[31]; // 提取符号位 sign_b = flp_b[31]; exp_a = flp_a[30:23]; // 提取指数部分 exp_b = flp_b[30:23]; fract_a = flp_a[22:0]; // 提取尾数部分(不含隐含1) fract_b = flp_b[22:0]; ``` - **符号位**:直接取最高位。 - **指数与尾数**:按IEEE 754格式分段提取。 --- #### **3. 指数计算** ```verilog exp_a_bias = exp_a + 8'b0111_1111; // 加偏置127 exp_b_bias = exp_b + 8'b0111_1111; exp_sum = exp_a_bias + exp_b_bias; // 指数求和(含双偏置) exponent = exp_sum - 8'b0111_1111; // 移除一个偏置 exp_unbiased = exponent - 8'b0111_1111; // 无偏置指数(调试用) ``` - **问题**:此处错误地添加了两次偏置,导致指数计算结果错误。正确公式应为: $$E_{\text{result}} = (E_a - 127) + (E_b - 127) + 127 = E_a + E_b - 127$$ - **修复建议**:直接相加原始指数后减去一个偏置: ```verilog exp_sum = exp_a + exp_b; exponent = exp_sum - 8'b0111_1111; ``` --- #### **4. 尾数乘法与规格化** ```verilog prod_dbl = fract_a * fract_b; // 23位尾数相乘(忽略隐含1) prod = prod_dbl[45:23]; // 取高23位 // 规格化循环(问题:固定移位22次) for (i = 0; i < 22; i = i + 1) begin if (prod[22] == 0) begin // 若最高位为0 prod = prod << 1; // 左移 exp_unbiased = exp_unbiased - 1; // 指数减1 end end ``` - **问题**: 1. **隐含1缺失**:未将隐含的`1.fract`纳入计算,导致乘积范围错误。 2. **固定移位次数**:强制移位22次,而非动态调整到最高位为1。 - **修复建议**: 1. 尾数相乘前补隐含1: ```verilog prod_dbl = {1'b1, fract_a} * {1'b1, fract_b}; // 24位x24位=48位 ``` 2. 动态移位直至最高位为1。 --- #### **5. 结果组合** ```verilog sign = sign_a ^ sign_b; // 符号位异或 sum = {sign, exp_unbiased, prod}; // 组合最终结果 ``` - **问题**:`exp_unbiased` 未重新偏置,导致指数错误。 - **修复建议**:使用带偏置的指数: ```verilog sum = {sign, exponent, prod}; ``` --- ### **关键问题总结** 1. **指数计算错误**:重复添加偏置,导致指数值过大。 2. **尾数处理缺失**:忽略隐含的前导1,乘积范围不正确。 3. **规格化逻辑缺陷**:固定移位次数而非动态调整。 --- ### **改进方向** 1. **修正指数计算**:直接使用原始指数相加后减去一个偏置。 2. **补全隐含1**:尾数乘法前添加隐含的1。 3. **动态规格化**:循环移位直至最高位为1,避免固定次数。 此模块需调整核心计算逻辑以符合IEEE 754标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值