1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂)

1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂),第1张

今天开始讲RecycleView的系列教程。分割线,分组,局部刷新,动态添加,缓存原理,抖音效果,瀑布流。嵌套,动画等等

RecyclerView的分割线是通过canvas和设置item偏移画出来的.需要知道2个方法

getItemOffsets()和onDraw方法

getItemOffsets 是针对每一个 ItemView

onDraw:遍历,进行颜色修改

我们可以看到自定义的 TestDividerItemDeoration 只实现了一个方法 getItemOffsets()。方法里面有四个参数。

Rect outRect

View view

RecyclerView parent

RecyclerView.State state

绿色区域代表 RecyclerView 中的一个 ItemView,而外面橙色区域也就是相应的 outRect,也就是 ItemView 与其它组件的偏移区域,等同于 margin 属性,通过复写 getItemOffsets() 方法,然后指定 outRect 中的 top、left、right、bottom 就可以控制各个方向的间隔了。

这实现了简单的分隔线效果,但这种方法分隔线的效果只能取决于背景色,如果我要定制分割线的颜色呢?这个时候就要 onDraw()。

————————————————

源码分析:在recycleview中的

分割线要注意,没有颜色,默认是白色的,会看不出来

第一种方案,通过

getItemOffsets()方法进行分割线!

判断是否是第一个,最后一个,是单个还是双个,是什么类型

/***

* 分割线要注意,没有颜色,默认是白色的,会看不出来

* @param outRect

* @param view

* @param parent

* @param state

*/

private void testItemOffset(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

int childAdapterPosition = parent.getChildAdapterPosition(view)

    if (childAdapterPosition ==0) {

outRect.set(0, 20, 0, 20)

    }else {

outRect.set(0, 0, 0, 20)

    }

}

第二种方案:ondraw()

@Override

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

super.onDraw(c, parent, state)

    int childCount = parent.getChildCount()

    for (int i =0i <childCounti++) {

View view = parent.getChildAt(i)

        int index = parent.getChildAdapterPosition(view)

        //第一个ItemView不需要绘制

        if (index ==0) {

continue

        }

float dividerTop = view.getTop() -mDividerHeight

        float dividerLeft = parent.getPaddingLeft()

        float dividerBottom = view.getTop()

        float dividerRight = parent.getWidth() - parent.getPaddingRight()

        c.drawRect(dividerLeft, dividerTop, dividerRight, dividerBottom, mPaint)

    }

}

 GridLayoutManager布局item左右间距均等

思路分析

首先,我们知道,对于 GridLayoutmanager ,当我们设置的 spancount 为 3 的时候,那么每个 item 的最大宽度为 itemMaxW = recycylerW / spancount = recycylerW / 3.

假设我们 spancount 为 3,那么在不设置 itemDercation 的情况下它的分布是这样的,可以看到第一列与最后一行的距离是不一样的

GridVIew出现的问题:本来固定item.高度和宽度

1.分割线有,不是理想的,左右均等

2.上下没有分割线

源码得到:

按上面分析的源码,我们可以知道,调用outRect.set(int left, int top, int right, int bottom)方法时,left一直为0,right一直为divider的宽度,而每一项item的宽度都要减去(left+right)大小,

left一直为0,right一直为divider的宽度

左上右下到底是什么的值?

计算每一个item移动的距离,左边和右边的移动距离

计算分析:

1.左边的分割线宽度为sW  (已知)

2.每个显示item的宽度,布局定义的itemWidth

3. 总共分割线宽度:totalDivider=屏幕宽度-spanCount*itemWidth

4.列之间的分割线宽度为dw   =(屏幕宽度-spanCount*item-2*sW )/(spantcount-1)

5.每个item需要留出的空间 ew=totalDivider/spanCount(即paddingLeft+paddingRight)

left:  左边的间距值(绝对值,差值)

right:右边的间距值

每个item移动的距离:

第一个Item:L0=sW                                  R0=eW-sW

第二个Item:L1=dW-R0=dW-eW+sW       R1=eW-L1=2eW-dW-sW

第三个Item:L2=dW-R1=2(dW-eW)+sW   R2=eW-L2=3eW-2dW-sW

得出公式:

Ln=(position%spanCount)*(dw-ew)+sw

Rn=ew-Ln

总结:得到3个值dw,ew, sw的值

sw:左边的距离

ew:每个的平均的分割线

dw: 列之间的分割线宽度

int firstLastSpace =50//最左边的分割线宽度

@SuppressLint("LongLogTag")

@Override

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

super.getItemOffsets(outRect, view, parent, state)

    count++

    outRect.top =20

    mDividerHeight =0

    int itemWidth =dip2px(context, 100)

    int screenWidth = getScreenWidth(context)

    int dw = (screenWidth -3 * itemWidth -2 *firstLastSpace) /2//最终计算出这个padding值

    //误区:中间的分割线的总距离,左右可能是不等的

    int totalDivder = screenWidth -3 * itemWidth

    Log.d("TestDividerItemDecoration", "totalDivder" + totalDivder)

    int eachDivder = totalDivder /3

    int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition()

    //不要用for循环

    outRect.left = (itemPosition %3) * (dw - eachDivder) +firstLastSpace

    outRect.right = eachDivder - outRect.right

}

错误的思路:

//误区:中间的分割线的总距离,左右可能是不等的

//不要用for循环

int firstLastSpace =50//最左边的分割线宽度

@SuppressLint("LongLogTag")

@Override

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

super.getItemOffsets(outRect, view, parent, state)

    count++

    outRect.top =20

    mDividerHeight =0

    int itemWidth =dip2px(context, 100)

    int screenWidth = getScreenWidth(context)

    int padding = (screenWidth -3 * itemWidth -2 *firstLastSpace) /4//最终计算出这个padding值

    //不能这么算,必须保证每个item的分割线一样才行。

    Log.d("TestDividerItemDecoration", "getItemOffsets" +count +"item宽度:" + itemWidth +"padding" + padding)

    //仅仅计算左边和右边的距离

    int childCount = parent.getChildCount()

    for (int i =0i <childCounti++) {

if (i %3 ==0) {//最左边的item

            outRect.left =firstLastSpace

            outRect.right = padding

        }else if (i %3 ==1) {

outRect.left = padding

            outRect.right = padding

        }else if (i %3 ==2) {

outRect.left = padding

            outRect.right =firstLastSpace

        }

}

}

瀑布流的设置:

int spanIndex = layoutParams.getSpanIndex()

public class FeedDecorationextends RecyclerView.ItemDecoration {

private HomePageCardAdaptermHomePageCardAdapter

    public FeedDecoration(HomePageCardAdapter mHomePageCardAdapter) {

this.mHomePageCardAdapter = mHomePageCardAdapter

    }

@Override

    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {

if (mHomePageCardAdapter ==null) {

return

        }

if (mHomePageCardAdapter.getItemViewType(parent.getChildAdapterPosition(view)) == HomePageMultipleCard.HOMEPAGE_MULTIPLE_CARD_TYPE_FITNESS_FEED) {

StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()

            int spanIndex = layoutParams.getSpanIndex()

            if (spanIndex ==0) {

outRect.set(DensityUtil.dip2px(ShadowApp.context(), 14), 0, DensityUtil.dip2px(ShadowApp.context(), 5), DensityUtil.dip2px(ShadowApp.context(), 10))

            }else {

outRect.set(DensityUtil.dip2px(ShadowApp.context(), 5), 0, DensityUtil.dip2px(ShadowApp.context(), 14), DensityUtil.dip2px(ShadowApp.context(), 10))

            }

}

}

}

demo地址: https://github.com/pengcaihua123456/shennandadao

java写的,可行

package ex1

import java.awt.BorderLayout

import java.awt.Color

import java.awt.Dimension

import java.awt.Font

import java.awt.GridLayout

import java.awt.event.ActionEvent

import java.awt.event.ActionListener

import java.text.DecimalFormat

import javax.swing.BorderFactory

import javax.swing.ButtonGroup

import javax.swing.JButton

import javax.swing.JCheckBoxMenuItem

import javax.swing.JFrame

import javax.swing.JMenu

import javax.swing.JMenuBar

import javax.swing.JMenuItem

import javax.swing.JPanel

import javax.swing.JRadioButtonMenuItem

import javax.swing.JTextField

public class Calcutor extends JFrame {

private JTextField tf

private JPanel panel1, panel2, panel3, panel4

private JMenuBar myBar

private JMenu menu1, menu2, menu3

private JMenuItem editItem1, editItem2, help1, help2, help3

private JRadioButtonMenuItem seeItem1, seeItem2//单选框

private JCheckBoxMenuItem seeItem3//复选框

private ButtonGroup bgb

private String back

private boolean IfResult = true, flag = false

private String oper = "="

private double result = 0

private Num numActionListener

private DecimalFormat df

public Calcutor(){

super("科学计算器")//设置标题栏

df = new DecimalFormat("#.####")//保留四位小数

this.setLayout(new BorderLayout(10, 5))

panel1 = new JPanel(new GridLayout(1, 3, 10, 10))

panel2 = new JPanel(new GridLayout(5, 6, 5, 5))//5行6列

panel3 = new JPanel(new GridLayout(5, 1, 5, 5))

panel4 = new JPanel(new BorderLayout(5, 5))

/**

* 菜单栏

*/

myBar = new JMenuBar()

menu1 = new JMenu("编辑(E)")

menu2 = new JMenu("查看(V)")

menu3 = new JMenu("帮助(H)")

menu1.setFont(new Font("宋体", Font.PLAIN, 12))

menu2.setFont(new Font("宋体", Font.PLAIN, 12))

menu3.setFont(new Font("宋体", Font.PLAIN, 12))

/**

* 编辑栏

*/

editItem1 = new JMenuItem("复制(C) Ctrl+C")

editItem2 = new JMenuItem("粘贴(P) Ctrl+V")

editItem1.setFont(new Font("宋体",Font.PLAIN,12))

editItem2.setFont(new Font("宋体",Font.PLAIN,12))

/**

* 查看栏

*/

seeItem1 = new JRadioButtonMenuItem("科学型(T)")

seeItem2 = new JRadioButtonMenuItem("标准型(S)")

seeItem3 = new JCheckBoxMenuItem("数字分组(I)")

seeItem1.setFont(new Font("宋体",Font.PLAIN,12))

seeItem2.setFont(new Font("宋体",Font.PLAIN,12))

seeItem3.setFont(new Font("宋体",Font.PLAIN,12))

/**

* 帮助栏

*/

help1 = new JMenuItem("帮助主题(H)")

help2 = new JMenuItem("关于计算器(A)")

help1.setFont(new Font("宋体",Font.PLAIN,12))

help2.setFont(new Font("宋体",Font.PLAIN,12))

bgb = new ButtonGroup()//选项组

menu1.add(editItem1)

menu1.add(editItem2)

menu2.add(seeItem1)

menu2.add(seeItem2)

menu2.addSeparator()//添加一条分割线

menu2.add(seeItem3)

menu3.add(help1)

menu3.addSeparator()//添加一条分割线

menu3.add(help2)

myBar.add(menu1)

myBar.add(menu2)

myBar.add(menu3)

this.setJMenuBar(myBar)

numActionListener = new Num()//实现数字监听

/**

* 文本域,即为计算器的屏幕显示区域

*/

tf = new JTextField()

tf.setEditable(false)//文本区域不可编辑

tf.setBackground(Color.white)//文本区域的背景色

tf.setHorizontalAlignment(JTextField.RIGHT)//文字右对齐

tf.setText("0")

tf.setBorder(BorderFactory.createLoweredBevelBorder())

init()//对计算器进行初始化

}

/**

* 初始化 *** 作

* 添加按钮

*/

private void init(){

addButton(panel1, "Backspace", new Clear(), Color.red)

addButton(panel1, "CE", new Clear(), Color.red)

addButton(panel1, "C", new Clear(), Color.red)

addButton(panel2, "1/x", new Signs(), Color.magenta)

addButton(panel2, "log", new Signs(), Color.magenta)

addButton(panel2, "7", numActionListener, Color.blue)

addButton(panel2, "8", numActionListener, Color.blue)

addButton(panel2, "9", numActionListener, Color.blue)

addButton(panel2, "÷", new Signs(), Color.red)

addButton(panel2, "n!", new Signs(), Color.magenta)

addButton(panel2, "sqrt", new Signs(), Color.magenta)

addButton(panel2, "4", numActionListener, Color.blue)

addButton(panel2, "5", numActionListener, Color.blue)

addButton(panel2, "6", numActionListener, Color.blue)

addButton(panel2, "×", new Signs(), Color.red)

addButton(panel2, "sin", new Signs(), Color.magenta)

addButton(panel2, "x^2", new Signs(), Color.magenta)

addButton(panel2, "1", numActionListener, Color.blue)

addButton(panel2, "2", numActionListener, Color.blue)

addButton(panel2, "3", numActionListener, Color.blue)

addButton(panel2, "-", new Signs(), Color.red)

addButton(panel2, "cos", new Signs(), Color.magenta)

addButton(panel2, "x^3", new Signs(), Color.magenta)

addButton(panel2, "0", numActionListener, Color.blue)

addButton(panel2, "-/+", new Clear(), Color.blue)

addButton(panel2, ".", new Dot(), Color.blue)

addButton(panel2, "+", new Signs(), Color.red)

addButton(panel2, "tan", new Signs(), Color.magenta)

addButton(panel2, "%", new Signs(), Color.magenta)

addButton(panel2, "π", numActionListener, Color.orange)

addButton(panel2, "e", numActionListener, Color.orange)

addButton(panel2, "′″", new Signs(), Color.orange)

addButton(panel2, "=", new Signs(), Color.red)

JButton btns = new JButton("计算器")

btns.setBorder(BorderFactory.createLoweredBevelBorder())

btns.setEnabled(false)//按钮不可 *** 作

btns.setPreferredSize(new Dimension(20, 20))

panel3.add(btns)//加入按钮

addButton(panel3, "MC", null, Color.red)

addButton(panel3, "MR", null, Color.red)

addButton(panel3, "MS", null, Color.red)

addButton(panel3, "M+", null, Color.red)

panel4.add(panel1, BorderLayout.NORTH)

panel4.add(panel2, BorderLayout.CENTER)

this.add(tf, BorderLayout.NORTH)

this.add(panel3, BorderLayout.WEST)

this.add(panel4)

pack()

this.setResizable(false)//窗口不可改变大小

this.setLocation(300, 200)

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

}

/**

* 统一设置按钮的的使用方式

* @param panel

* @param name

* @param action

* @param color

*/

private void addButton(JPanel panel, String name, ActionListener action, Color color){

JButton bt = new JButton(name)

panel.add(bt)//在面板上增加按钮

bt.setForeground(color)//设置前景(字体)颜色

bt.addActionListener(action)//增加监听事件

}

/**

* 计算器的基础 *** 作(+ - × ÷)

* @param x

*/

private void getResult (double x){

if(oper == "+"){result += x}

else if(oper == "-"){result -= x}

else if(oper == "×"){result *= x}

else if(oper == "÷"){result /= x}

else if(oper == "="){result = x}

tf.setText(df.format(result))

}

/**

* 运算符号的事件监听

*/

class Signs implements ActionListener{

public void actionPerformed(ActionEvent e) {

/*

* 用ActionEvent对象的getActionCommand()方法

* 取得与引发事件对象相关的字符串

*/

String str = e.getActionCommand()

/* sqrt求平方根 */

if(str.equals("sqrt")){

double i = Double.parseDouble(tf.getText())

if(i>=0){

/*

* String.valueOf() 转换为字符串

* df.format() 按要求保留四位小数

* Math.sqrt() 求算数平方根

*/

tf.setText(String.valueOf(df.format(Math.sqrt(i))))

}

else{

tf.setText("负数不能开平方根")

}

}

/* log求常用对数 */

else if(str.equals("log")){

double i = Double.parseDouble(tf.getText())

if(i>0){

tf.setText(String.valueOf(df.format(Math.log(i))))

}else{

tf.setText("负数不能求对数")

}

}

/* %求百分比 */

else if(str.equals("%")){

tf.setText(df.format(Double.parseDouble(tf.getText()) / 100))

}

/* 1/x求倒数 */

else if(str.equals("1/x")){

if(Double.parseDouble(tf.getText()) == 0){

tf.setText("除数不能为零")

}else{

tf.setText(df.format(1 / Double.parseDouble(tf.getText())))

}

}

/* sin求正弦函数 */

else if(str.equals("sin")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.sin(i))))

}

/* cos求余弦函数 */

else if(str.equals("cos")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.cos(i))))

}

/* tan求正切函数 */

else if(str.equals("tan")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.tan(i))))

}

/* n!求阶乘 */

else if(str.equals("n!")){

double i = Double.parseDouble(tf.getText())

if((i%2==0)||(i%2==1))//判断为整数放进行阶乘 *** 作

{

int j = (int)i//强制类型转换

int result=1

for(int k=1k<=jk++)

result *= k

tf.setText(String.valueOf(result))

}

else

{

tf.setText("无法进行阶乘")

}

}

/* x^2求平方 */

else if(str.equals("x^2")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(i*i)))

}

/* x^3求立方 */

else if(str.equals("x^3")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(i*i*i)))

}

/* ′″角度转换 */

/**

* 将角度值转换成弧度值,方便三角函数的计算

*/

else if(str.equals("′″")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(i/180*Math.PI))

}

else{

if(flag){

IfResult = false

}

if(IfResult){

oper = str

}else{

getResult(Double.parseDouble(tf.getText()))

oper = str

IfResult = true

}

}

}

}

/**

* 清除按钮的事件监听

*/

class Clear implements ActionListener{

public void actionPerformed(ActionEvent e) {

/*

* 用ActionEvent对象的getActionCommand()方法

* 取得与引发事件对象相关的字符串

*/

String str = e.getActionCommand()

if(str == "C"){

tf.setText("0")

IfResult = true

result = 0

}else if(str == "-/+"){

double i = 0 - Double.parseDouble(tf.getText().trim())

tf.setText(df.format(i))

}else if(str == "Backspace"){

if(Double.parseDouble(tf.getText()) >0){

if(tf.getText().length() >1){

tf.setText(tf.getText().substring(0, tf.getText().length() - 1))

//使用退格删除最后一位字符

}else{

tf.setText("0")

IfResult = true

}

}else{

if(tf.getText().length() >2){

tf.setText(tf.getText().substring(0, tf.getText().length() - 1))

}else{

tf.setText("0")

IfResult = true

}

}

}else if(str == "CE"){

tf.setText("0")

IfResult = true

}

}

}

/**

* 数字输入的事件监听

*/

class Num implements ActionListener{

public void actionPerformed(ActionEvent e) {

String str = e.getActionCommand()

if(IfResult){

tf.setText("")

IfResult = false

}

if(str=="π")

{

tf.setText(String.valueOf(Math.PI))

}

else if(str=="e")

{

tf.setText(String.valueOf(Math.E))

}

else{

tf.setText(tf.getText().trim() + str)

if(tf.getText().equals("0")){

tf.setText("0")

IfResult = true

flag = true

}

}

}

}

/**

* 小数点的事件监听

*/

class Dot implements ActionListener{

public void actionPerformed(ActionEvent e) {

IfResult = false

if(tf.getText().trim().indexOf(".") == -1){

tf.setText(tf.getText() + ".")

}

}

}

/**

* main方法

*/

public static void main(String[] args) {

new Calcutor().setVisible(true)

}

}

java EE是java企业级开发平台的意思,实在是看不出跟计算器这种小程序有什么关联。不知道楼主要找的是不是这个。

package ex1

import java.awt.BorderLayout

import java.awt.Color

import java.awt.Dimension

import java.awt.Font

import java.awt.GridLayout

import java.awt.event.ActionEvent

import java.awt.event.ActionListener

import java.text.DecimalFormat

import javax.swing.BorderFactory

import javax.swing.ButtonGroup

import javax.swing.JButton

import javax.swing.JCheckBoxMenuItem

import javax.swing.JFrame

import javax.swing.JMenu

import javax.swing.JMenuBar

import javax.swing.JMenuItem

import javax.swing.JPanel

import javax.swing.JRadioButtonMenuItem

import javax.swing.JTextField

public class Calcutor extends JFrame {

private JTextField tf

private JPanel panel1, panel2, panel3, panel4

private JMenuBar myBar

private JMenu menu1, menu2, menu3

private JMenuItem editItem1, editItem2, help1, help2, help3

private JRadioButtonMenuItem seeItem1, seeItem2//单选框

private JCheckBoxMenuItem seeItem3//复选框

private ButtonGroup bgb

private String back

private boolean IfResult = true, flag = false

private String oper = "="

private double result = 0

private Num numActionListener

private DecimalFormat df

public Calcutor(){

super("科学计算器")//设置标题栏

df = new DecimalFormat("#.####")//保留四位小数

this.setLayout(new BorderLayout(10, 5))

panel1 = new JPanel(new GridLayout(1, 3, 10, 10))

panel2 = new JPanel(new GridLayout(5, 6, 5, 5))//5行6列

panel3 = new JPanel(new GridLayout(5, 1, 5, 5))

panel4 = new JPanel(new BorderLayout(5, 5))

/**

* 菜单栏

*/

myBar = new JMenuBar()

menu1 = new JMenu("编辑(E)")

menu2 = new JMenu("查看(V)")

menu3 = new JMenu("帮助(H)")

menu1.setFont(new Font("宋体", Font.PLAIN, 12))

menu2.setFont(new Font("宋体", Font.PLAIN, 12))

menu3.setFont(new Font("宋体", Font.PLAIN, 12))

/**

* 编辑栏

*/

editItem1 = new JMenuItem("复制(C) Ctrl+C")

editItem2 = new JMenuItem("粘贴(P) Ctrl+V")

editItem1.setFont(new Font("宋体",Font.PLAIN,12))

editItem2.setFont(new Font("宋体",Font.PLAIN,12))

/**

* 查看栏

*/

seeItem1 = new JRadioButtonMenuItem("科学型(T)")

seeItem2 = new JRadioButtonMenuItem("标准型(S)")

seeItem3 = new JCheckBoxMenuItem("数字分组(I)")

seeItem1.setFont(new Font("宋体",Font.PLAIN,12))

seeItem2.setFont(new Font("宋体",Font.PLAIN,12))

seeItem3.setFont(new Font("宋体",Font.PLAIN,12))

/**

* 帮助栏

*/

help1 = new JMenuItem("帮助主题(H)")

help2 = new JMenuItem("关于计算器(A)")

help1.setFont(new Font("宋体",Font.PLAIN,12))

help2.setFont(new Font("宋体",Font.PLAIN,12))

bgb = new ButtonGroup()//选项组

menu1.add(editItem1)

menu1.add(editItem2)

menu2.add(seeItem1)

menu2.add(seeItem2)

menu2.addSeparator()//添加一条分割线

menu2.add(seeItem3)

menu3.add(help1)

menu3.addSeparator()//添加一条分割线

menu3.add(help2)

myBar.add(menu1)

myBar.add(menu2)

myBar.add(menu3)

this.setJMenuBar(myBar)

numActionListener = new Num()//实现数字监听

/**

* 文本域,即为计算器的屏幕显示区域

*/

tf = new JTextField()

tf.setEditable(false)//文本区域不可编辑

tf.setBackground(Color.white)//文本区域的背景色

tf.setHorizontalAlignment(JTextField.RIGHT)//文字右对齐

tf.setText("0")

tf.setBorder(BorderFactory.createLoweredBevelBorder())

init()//对计算器进行初始化

}

/**

* 初始化 *** 作

* 添加按钮

*/

private void init(){

addButton(panel1, "Backspace", new Clear(), Color.red)

addButton(panel1, "CE", new Clear(), Color.red)

addButton(panel1, "C", new Clear(), Color.red)

addButton(panel2, "1/x", new Signs(), Color.magenta)

addButton(panel2, "log", new Signs(), Color.magenta)

addButton(panel2, "7", numActionListener, Color.blue)

addButton(panel2, "8", numActionListener, Color.blue)

addButton(panel2, "9", numActionListener, Color.blue)

addButton(panel2, "÷", new Signs(), Color.red)

addButton(panel2, "n!", new Signs(), Color.magenta)

addButton(panel2, "sqrt", new Signs(), Color.magenta)

addButton(panel2, "4", numActionListener, Color.blue)

addButton(panel2, "5", numActionListener, Color.blue)

addButton(panel2, "6", numActionListener, Color.blue)

addButton(panel2, "×", new Signs(), Color.red)

addButton(panel2, "sin", new Signs(), Color.magenta)

addButton(panel2, "x^2", new Signs(), Color.magenta)

addButton(panel2, "1", numActionListener, Color.blue)

addButton(panel2, "2", numActionListener, Color.blue)

addButton(panel2, "3", numActionListener, Color.blue)

addButton(panel2, "-", new Signs(), Color.red)

addButton(panel2, "cos", new Signs(), Color.magenta)

addButton(panel2, "x^3", new Signs(), Color.magenta)

addButton(panel2, "0", numActionListener, Color.blue)

addButton(panel2, "-/+", new Clear(), Color.blue)

addButton(panel2, ".", new Dot(), Color.blue)

addButton(panel2, "+", new Signs(), Color.red)

addButton(panel2, "tan", new Signs(), Color.magenta)

addButton(panel2, "%", new Signs(), Color.magenta)

addButton(panel2, "π", numActionListener, Color.orange)

addButton(panel2, "e", numActionListener, Color.orange)

addButton(panel2, "′″", new Signs(), Color.orange)

addButton(panel2, "=", new Signs(), Color.red)

JButton btns = new JButton("计算器")

btns.setBorder(BorderFactory.createLoweredBevelBorder())

btns.setEnabled(false)//按钮不可 *** 作

btns.setPreferredSize(new Dimension(20, 20))

panel3.add(btns)//加入按钮

addButton(panel3, "MC", null, Color.red)

addButton(panel3, "MR", null, Color.red)

addButton(panel3, "MS", null, Color.red)

addButton(panel3, "M+", null, Color.red)

panel4.add(panel1, BorderLayout.NORTH)

panel4.add(panel2, BorderLayout.CENTER)

this.add(tf, BorderLayout.NORTH)

this.add(panel3, BorderLayout.WEST)

this.add(panel4)

pack()

this.setResizable(false)//窗口不可改变大小

this.setLocation(300, 200)

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

}

/**

* 统一设置按钮的的使用方式

* @param panel

* @param name

* @param action

* @param color

*/

private void addButton(JPanel panel, String name, ActionListener action, Color color){

JButton bt = new JButton(name)

panel.add(bt)//在面板上增加按钮

bt.setForeground(color)//设置前景(字体)颜色

bt.addActionListener(action)//增加监听事件

}

/**

* 计算器的基础 *** 作(+ - × ÷)

* @param x

*/

private void getResult (double x){

if(oper == "+"){result += x}

else if(oper == "-"){result -= x}

else if(oper == "×"){result *= x}

else if(oper == "÷"){result /= x}

else if(oper == "="){result = x}

tf.setText(df.format(result))

}

/**

* 运算符号的事件监听

*/

class Signs implements ActionListener{

public void actionPerformed(ActionEvent e) {

/*

* 用ActionEvent对象的getActionCommand()方法

* 取得与引发事件对象相关的字符串

*/

String str = e.getActionCommand()

/* sqrt求平方根 */

if(str.equals("sqrt")){

double i = Double.parseDouble(tf.getText())

if(i>=0){

/*

* String.valueOf() 转换为字符串

* df.format() 按要求保留四位小数

* Math.sqrt() 求算数平方根

*/

tf.setText(String.valueOf(df.format(Math.sqrt(i))))

}

else{

tf.setText("负数不能开平方根")

}

}

/* log求常用对数 */

else if(str.equals("log")){

double i = Double.parseDouble(tf.getText())

if(i>0){

tf.setText(String.valueOf(df.format(Math.log(i))))

}else{

tf.setText("负数不能求对数")

}

}

/* %求百分比 */

else if(str.equals("%")){

tf.setText(df.format(Double.parseDouble(tf.getText()) / 100))

}

/* 1/x求倒数 */

else if(str.equals("1/x")){

if(Double.parseDouble(tf.getText()) == 0){

tf.setText("除数不能为零")

}else{

tf.setText(df.format(1 / Double.parseDouble(tf.getText())))

}

}

/* sin求正弦函数 */

else if(str.equals("sin")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.sin(i))))

}

/* cos求余弦函数 */

else if(str.equals("cos")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.cos(i))))

}

/* tan求正切函数 */

else if(str.equals("tan")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(Math.tan(i))))

}

/* n!求阶乘 */

else if(str.equals("n!")){

double i = Double.parseDouble(tf.getText())

if((i%2==0)||(i%2==1))//判断为整数放进行阶乘 *** 作

{

int j = (int)i//强制类型转换

int result=1

for(int k=1k<=jk++)

result *= k

tf.setText(String.valueOf(result))

}

else

{

tf.setText("无法进行阶乘")

}

}

/* x^2求平方 */

else if(str.equals("x^2")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(i*i)))

}

/* x^3求立方 */

else if(str.equals("x^3")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(df.format(i*i*i)))

}

/* ′″角度转换 */

/**

* 将角度值转换成弧度值,方便三角函数的计算

*/

else if(str.equals("′″")){

double i = Double.parseDouble(tf.getText())

tf.setText(String.valueOf(i/180*Math.PI))

}

else{

if(flag){

IfResult = false

}

if(IfResult){

oper = str

}else{

getResult(Double.parseDouble(tf.getText()))

oper = str

IfResult = true

}

}

}

}

/**

* 清除按钮的事件监听

*/

class Clear implements ActionListener{

public void actionPerformed(ActionEvent e) {

/*

* 用ActionEvent对象的getActionCommand()方法

* 取得与引发事件对象相关的字符串

*/

String str = e.getActionCommand()

if(str == "C"){

tf.setText("0")

IfResult = true

result = 0

}else if(str == "-/+"){

double i = 0 - Double.parseDouble(tf.getText().trim())

tf.setText(df.format(i))

}else if(str == "Backspace"){

if(Double.parseDouble(tf.getText()) >0){

if(tf.getText().length() >1){

tf.setText(tf.getText().substring(0, tf.getText().length() - 1))

//使用退格删除最后一位字符

}else{

tf.setText("0")

IfResult = true

}

}else{

if(tf.getText().length() >2){

tf.setText(tf.getText().substring(0, tf.getText().length() - 1))

}else{

tf.setText("0")

IfResult = true

}

}

}else if(str == "CE"){

tf.setText("0")

IfResult = true

}

}

}

/**

* 数字输入的事件监听

*/

class Num implements ActionListener{

public void actionPerformed(ActionEvent e) {

String str = e.getActionCommand()

if(IfResult){

tf.setText("")

IfResult = false

}

if(str=="π")

{

tf.setText(String.valueOf(Math.PI))

}

else if(str=="e")

{

tf.setText(String.valueOf(Math.E))

}

else{

tf.setText(tf.getText().trim() + str)

if(tf.getText().equals("0")){

tf.setText("0")

IfResult = true

flag = true

}

}

}

}

/**

* 小数点的事件监听

*/

class Dot implements ActionListener{

public void actionPerformed(ActionEvent e) {

IfResult = false

if(tf.getText().trim().indexOf(".") == -1){

tf.setText(tf.getText() + ".")

}

}

}

/**

* main方法

*/

public static void main(String[] args) {

new Calcutor().setVisible(true)

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11909095.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存