Android表格自定义控件使用详解
作者:jiulong90 发布时间:2023-12-23 23:35:36
标签:Android,表格控件
近期公司要做报表功能,在网上搜索下表格的样式后便自己写了一个自定义的表格控件,该表格控件能根据设置的数据中数据的最大值自动设置左侧信息栏显示的值,使得条形图能尽量的充满控件,条形图部分支持左右滑动,数据的长度可能超过控件本身所能容纳的长度,所以在绘制的时候做了判断,当需要绘制的部分不再控件范围内则不进行绘制,具体请阅读代码,目前只支持一个名称对应一条数据,如有不足之处,大家提出帮忙修改
使用方法如下:
在xml文件中定义控件属性
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#333333"
tools:context=".MainActivity">
<com.example.administrator.widget.MyChatView
android:id="@+id/chatView"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginTop="100dp"
android:background="#FFFFFF"
/>
</RelativeLayout>
在Activity中设置控件要显示的数据、设置显示的样式
public class MainActivity extends AppCompatActivity {
private MyChatView mMyChatView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyChatView = (MyChatView) this.findViewById(R.id.chatView);
mMyChatView.setData(getData1())
.setDataCompany("美元")
.setDataTitle("测试")
.setLeftTextColor(Color.RED)
.setBottomTextColor(Color.BLUE)
.setmDataTopTextColor(Color.RED) .setDataBackgroundColor(Color.parseColor("#ABCDEF"))
.setDataColor(Color.RED)
.setTitleColor(Color.BLUE)
.setLeftTextSize(12)
.setBottomTextSize(15)
.setDataTopTextSize(10)
.setTitleTextSize(20)
.setSpanBottomText(15);
}
/**
* 获取测试数据
* @return 测试用的数据
*/
private List<Map<String, String>> getData1(){
List<Map<String, String>> data = new ArrayList<>();
HashMap<String, String> map;
int temp;
for (int i=0; i<100; i++) {
map = new HashMap<>();
map.put(MyChatView.NAME, "name:"+i);
temp = (int) (Math.random()*100);
map.put(MyChatView.VALUE, temp +"."+i*i);
data.add(map);
}
return data;
}
}
自定义控件代码:
public class MyChatView extends View {
/** 数据集合中的 Map 集合存放信息的键 */
public static final String NAME = "name";
/** 数据集合中的 Map 集合存放数据的键 */
public static final String VALUE = "value";
/** 上下文 */
private Context mContext;
/** 控件的高度 */
private int mHeight;
/** 控件的宽度 */
private int mWidget;
/** 数据 */
private List<Map<String, String>> mData;
/** 数据单位 */
private String mDataCompany = "单位: ";
/** 底部表格名称 */
private String mDataTitle = null;
/** 底部信息栏文字的大小 */
private int mBottomTextSize;
/** 左侧等分信息栏文字的大小 */
private int mLeftTextSize;
/** 柱状图顶部文字的大小 */
private int mDataTopTextSize;
/** 表格标题文字大小 */
private int mTitleTextSize;
/** 左侧文字与数据区域的间隔 */
private int mSpanLeftText;
/** 柱状图顶部文字与柱状图的间隔 */
int mSpanDataTopText;
/** 底部信息字符串间隔 */
int mSpanBottomText;
/** 底部信息字符串与控件底部间隔 */
int mSpanBottom;
/** 绘制数据部分的背景颜色 */
private int mDataBackgroundColor = Color.WHITE;
/** 底部信息字符串颜色 */
private int mBottomTextColor = Color.BLACK;
/** 柱状图柱状部分颜色 */
private int mDataColor = Color.BLACK;
/** 左边信息栏文字颜色 */
private int mLeftTextColor = Color.BLACK;
/** 柱状图顶部文字颜色 */
private int mDataTopTextColor = Color.BLACK;
/** 标题颜色 */
private int mTitleColor = Color.BLACK;
/** 表格移动的位置 */
private int mChartMovedSize = 0;
/** 用户按下时 X 方向位置 */
private int mDownX = 0;
/** 用户松手是 X 方向位置 */
private int mUpX = 0;
/** 表格 X 方向移动的最大距离 */
private int mChartMaxMovedLengthX;
public MyChatView(Context context) {
this(context, null);
}
public MyChatView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyChatView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
this.mBottomTextSize = dpToPx(context, 15);
this.mLeftTextSize = dpToPx(context, 10);
this.mDataTopTextSize = dpToPx(context, 10);
this.mSpanLeftText = dpToPx(context, 2);
this.mSpanDataTopText = dpToPx(context, 3);
this.mSpanBottomText = dpToPx(context, 10);
this.mSpanBottom = dpToPx(context, 8);
this.mTitleTextSize = dpToPx(context, 20);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mHeight = h;
this.mWidget = w;
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mDownX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
mUpX = (int) event.getX();
shouldMoveChart();
break;
case MotionEvent.ACTION_UP:
mUpX = (int) event.getX();
shouldMoveChart();
break;
}
return true;
}
/**
* 判断移动的距离大于规定距离就移动表格
*/
private void shouldMoveChart (){
if (mChartMaxMovedLengthX<mWidget) {
this.mChartMaxMovedLengthX = (getXTotalLength() - mWidget*2/3);
}
int size = dpToPx(mContext, 2);
if ((mUpX-mDownX)>=size || (mDownX-mUpX)>=size ) {
mChartMovedSize += (mUpX - mDownX);
mDownX = mUpX;
if (mChartMovedSize>=0) {
mChartMovedSize = 0;
}
if (mChartMovedSize<-mChartMaxMovedLengthX) {
mChartMovedSize = -mChartMaxMovedLengthX;
}
this.invalidate();
}
}
private InnerDraw innerDraw;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (innerDraw==null) {
innerDraw = new InnerDraw(canvas);
} else {
innerDraw.initData(canvas);
}
innerDraw.drawLeftMenue();
innerDraw.drawDataBackground();
innerDraw.drawDataTitle();
innerDraw.drawCompany();
int dataSize = mData.size();
for (int i=0; i<dataSize; i++) {
//设置数据,必须在第一行
int state = innerDraw.startDrawBody(mData.get(i), i);
if (state==0) {
continue;
} else if (state==-1) {
break;
}
innerDraw.drawDataTopText();
innerDraw.drawDataBar();
innerDraw.drawBottomMessage();
innerDraw.endDrawBody();
}
}
/**
* 根据文字大小获取文字高度
* @param paint 画笔
* @param textSize 要绘制的文字的大小
* @return 要绘制文字的高度
*/
private int getTextHeight (Paint paint, int textSize){
String text = "测试";
Rect rect = new Rect();
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), rect);
return rect.height();
}
/**
* 根据文字大小获取文字宽度
* @param paint 画笔
* @param text 要绘制的文字
* @param textSize 要绘制的文字的大小
* @return 要绘制文字的宽度
*/
private int getTextWidth (Paint paint, String text, int textSize){
Rect rect = new Rect();
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), rect);
return rect.width();
}
/**
* 获取左侧等分等分信息中文字最长的字符串
* @return 字符串,抹去数字后面小数点
*/
private String getLeftValueMaxString (){
int size = mData.size();
String maxLengthString = "1";
String tempString;
for (int i=0; i<size; i++) {
tempString = mData.get(i).get(VALUE);
if (tempString.length()>maxLengthString.length()) {
maxLengthString = tempString;
}
}
if (maxLengthString.contains(".")) {
maxLengthString = maxLengthString.substring(0, maxLengthString.indexOf('.')+2);
}
return maxLengthString;
}
/**
* 获取最长信息字符串
* @return 底部信息栏中最长字符串
*/
private String getBottomMaxLegthString (){
int size = mData.size();
String maxString = "你好我好大家好才是真的好";
String tempString;
for (int i=0; i<size; i++) {
tempString = mData.get(i).get(NAME);
if (maxString.length()>tempString.length()) {
maxString = tempString;
}
}
return maxString;
}
/**
* 获取数据中的最大值
* @return 数据中的最大值 int float 类型
*/
private int getMaxValue (){
int maxValue = Float.valueOf(mData.get(0).get(VALUE)).intValue();
int tempValue;
for (Map<String, String> map : mData) {
tempValue = Float.valueOf(map.get(VALUE)).intValue();
if (maxValue<tempValue) {
maxValue = tempValue + tempValue/10;
}
}
return maxValue;
}
/**
* 获取表格 X 方向的总长
* @return X 方向总长 int
*/
private int getXTotalLength(){
int xTotalLength = 0;
Paint paint = new Paint();
for (Map<String, String> map : mData) {
xTotalLength += getTextWidth(paint, map.get(NAME), mBottomTextSize);
xTotalLength = xTotalLength + mSpanBottomText;
}
return xTotalLength;
}
/**
* 根据数据中的最大值将数据分成10等分,每等分为10的倍数
* @param maxValue 数据中的最大值
* @return 左侧等分栏的每一等分的数值 int 类型
*/
private int getPiceValue (int maxValue){
int piceValue = 1;
while (maxValue>10) {
maxValue = maxValue/10;
piceValue = piceValue * 10;
}
if (maxValue<=5) {
piceValue = piceValue / 2;
}
return piceValue;
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param context 上下文
* @param dpValue 要转换的 dp 值
* @return 转换后的 px 值
*/
private int dpToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 设置数据
* @param data 表中的数据
* data集合中的Map
* "name"存放名称,使用MyCharView中的常量 NAME
* "value"存放数据,数据为int类型的字符串,使用MyCharView中的常量 VALUE
*/
public MyChatView setData (List<Map<String, String>> data){
try {
this.mData = data==null? new ArrayList<Map<String, String>>():data;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置绘制数据部分背景颜色
* @param dataBackgroundColor 16进制 int 类型颜色
* @return 对象本身
*/
public MyChatView setDataBackgroundColor (int dataBackgroundColor){
try {
this.mDataBackgroundColor = dataBackgroundColor;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置左边信息栏文字颜色
* @param leftTextColor 16进制 int 类型颜色
* @return 对象本身
*/
public MyChatView setLeftTextColor (int leftTextColor){
try {
this.mLeftTextColor = leftTextColor;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置底部信息文字颜色
* @param bottomTextColor 16进制 int 类型颜色
* @return 对象本身
*/
public MyChatView setBottomTextColor (int bottomTextColor){
try {
this.mBottomTextColor = bottomTextColor;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置柱状条的背景颜色
* @param dataColor 16进制 int 类型颜色
* @return 对象本身
*/
public MyChatView setDataColor (int dataColor){
try {
this.mDataColor = dataColor;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置柱状条顶部文字颜色
* @param dataTopTextColor 16进制 int 类型颜色
* @return 对象本身
*/
public MyChatView setmDataTopTextColor (int dataTopTextColor){
try {
this.mDataTopTextColor = dataTopTextColor;
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置标题颜色
* @param titleColor 颜色16进制的 int 类型
* @return 对象本身
*/
public MyChatView setTitleColor (int titleColor){
try {
this.mTitleColor = titleColor;
}catch (Exception e){
e.printStackTrace();
}
return this;
}
/**
* 设置底部信息文字大小
* @param bottomTextSize int 类型 dp
* @return 对象本身
*/
public MyChatView setBottomTextSize (int bottomTextSize){
try {
this.mBottomTextSize = dpToPx(mContext, bottomTextSize);
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置左侧信息文字大小
* @param leftTextSize int 类型 dp
* @return 对象本身
*/
public MyChatView setLeftTextSize (int leftTextSize){
try {
this.mLeftTextSize = dpToPx(mContext, leftTextSize);
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置柱状条顶部文字大小
* @param dataTopTextSize int 类型 dp
* @return 对象本身
*/
public MyChatView setDataTopTextSize (int dataTopTextSize){
try {
this.mDataTopTextSize = dpToPx(mContext, dataTopTextSize);
}catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置底部表格标题文字大小
* @param titleTextSize 标题文字大小
* @return 对象本身
*/
public MyChatView setTitleTextSize (int titleTextSize){
try {
this.mTitleTextSize = dpToPx(mContext,titleTextSize);
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置表格数据单位
* @param dataCompany 数据单位
* @return 对象本身
*/
public MyChatView setDataCompany (String dataCompany){
try {
this.mDataCompany += dataCompany==null? "空":dataCompany;
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置表格标题
* @param dataTitle 表格标题
* @return 对象本身
*/
public MyChatView setDataTitle (String dataTitle){
try {
mDataTitle = dataTitle;
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* 设置底部信息栏文字的间隔 默认为 10dp
* @param spanBottomText 间隔距离 dp
* @return 对象本身
*/
public MyChatView setSpanBottomText (int spanBottomText){
try {
this.mSpanBottomText = dpToPx(mContext, spanBottomText);
} catch (Exception e){
e.printStackTrace();
}
return this;
}
//****************************** 绘制表格的类 **********************************
/**
* 绘制控件界面的类
*/
private class InnerDraw{
private Canvas canvas;
private Paint paint;
/** 记录绘制到的位置 */
private int bottomTextPainted;
/** 底部标题高度 */
private int bottomTitleHeight;
/** 底部信息的高度 */
private int bottomMessageHeight;
/** 左侧信息栏最长文字 */
private String leftValueMaxString;
/** 表格中柱状图上文字高度 */
private int dataTopTextHeight;
/** 左侧信息栏宽度 */
private int leftValueWidth;
/** 绘制数据部分的高度 */
private int chartDataHeight;
/** 左侧等分栏的每等分高度 */
private int piceValueHeight;
/** 左侧等分栏每等分的数值 */
private int piceValue;
/** 柱状的宽度 */
private int dataBarWidth;
/** 底部信息 */
String bottomMessage;
/** 底部信息的宽度 */
private int bottomMessageWidth;
/** 数据信息 */
Map<String, String> data;
/** 要绘制信息的位置 */
int index;
public InnerDraw (Canvas canvas){
initData(canvas);
}
/**
* 初始化数据
*/
public void initData(Canvas canvas){
this.canvas = canvas;
this.paint = new Paint();
this.bottomTitleHeight = mDataTitle==null? 0:(getTextHeight(paint, mTitleTextSize)+mSpanBottom/2);
this.bottomTextPainted = 0;
this.bottomMessageHeight = getTextHeight(paint, mBottomTextSize) + mSpanBottom + bottomTitleHeight;
this.leftValueMaxString = getLeftValueMaxString();
this.dataTopTextHeight = getTextHeight(paint, mDataTopTextSize);
this.leftValueWidth = getTextWidth(paint, leftValueMaxString , mLeftTextSize) + mSpanLeftText;
this.chartDataHeight = mHeight - bottomMessageHeight - mSpanBottom;
this.piceValueHeight = (chartDataHeight-dataTopTextHeight-getTextHeight(paint, mSpanDataTopText))/10;
this.piceValue = getPiceValue(getMaxValue());
this.dataBarWidth = getTextWidth(paint, getBottomMaxLegthString(), mBottomTextSize);
this.bottomMessage = "";
this.bottomMessageWidth = 0;
this.data = new HashMap<>();
this.index = 0;
}
/**
* 绘制左侧等分栏
*/
public void drawLeftMenue(){
paint.setColor(mLeftTextColor);
paint.setTextSize(mLeftTextSize);
int textLeft;
int textTop;
String valueStr;
int strLength;
String maxValueStr = String.valueOf(piceValue * 10);
int textMaxLength = maxValueStr.length();
int topTextHeight = getTextHeight(paint, mDataTopTextSize);
int leftTextHeight = getTextHeight(paint, mLeftTextSize);
for (int i=0; i<=10; i++) {
textLeft = 0;
valueStr = String.valueOf(i * piceValue);
strLength = valueStr.length();
if (strLength<textMaxLength) {
textLeft = getTextWidth(paint, maxValueStr.substring(strLength), mLeftTextSize);
}
textTop = (10-i)*piceValueHeight + topTextHeight + mSpanDataTopText + leftTextHeight/2;
canvas.drawText(valueStr+"", textLeft, textTop, paint);
}
}
/**
* 绘制表格中数据部分背景
*/
public void drawDataBackground() {
paint.setColor(mDataBackgroundColor);
Rect rect = new Rect(leftValueWidth, 0, mWidget, chartDataHeight);
canvas.drawRect(rect, paint);
}
/**
* 绘制底部标题
*/
public void drawDataTitle() {
if (mDataTitle != null) {
paint.setColor(mTitleColor);
paint.setTextSize(mTitleTextSize);
int titleWidget = getTextWidth(paint, mDataTitle, mTitleTextSize);
float titleLeft = (mWidget - titleWidget) / 2;
float titleTop = mHeight - mSpanBottom;
canvas.drawText(mDataTitle, titleLeft, titleTop, paint);
}
}
/**
* 绘制数据单位
*/
public void drawCompany() {
paint.setTextSize(mLeftTextSize);
paint.setColor(mLeftTextColor);
int comPanyLeft = mWidget - getTextWidth(paint, mDataCompany + "111", mLeftTextSize);
int companyBottom = dataTopTextHeight + getTextHeight(paint, mLeftTextSize);
canvas.drawText(mDataCompany, comPanyLeft, companyBottom, paint);
}
/**
* 开始绘制,设置数据,同事设置底部信息宽度
* @param data 数据信息
* @param index 绘制到的位置
* @return 状态码: -1 为结束循环,0 为继续下一个循环,1 为正常绘制
*/
public int startDrawBody(Map<String, String> data, int index){
this.data = data;
this.bottomMessage = data.get(NAME).trim();
this.bottomMessageWidth = getTextWidth(paint, bottomMessage, mBottomTextSize);
this.index = index;
int bottomMsgBegainDrawX = (index + 1) * mSpanBottomText + mChartMovedSize + leftValueWidth + bottomTextPainted;
if ((bottomMsgBegainDrawX+bottomMessageWidth)<leftValueWidth) {//需要绘制的区域在绘制区域的左侧
bottomTextPainted += bottomMessageWidth;
return 0;
}
if (bottomMsgBegainDrawX>mWidget) {//需要绘制的区域超出了控件的右边,结束绘制
return -1;
}
return 1;
}
/**
* 结束绘制
*/
public void endDrawBody(){
bottomTextPainted += bottomMessageWidth;
}
/**
* 绘制底部信息栏
*/
public void drawBottomMessage() {
paint.setColor(mBottomTextColor);
paint.setTextSize(mBottomTextSize);
int bottomLeft = (index + 1) * mSpanBottomText + mChartMovedSize + leftValueWidth + bottomTextPainted;
int bottomTop = chartDataHeight + bottomMessageHeight - bottomTitleHeight - dpToPx(mContext, 2);
if (bottomLeft >= leftValueWidth && bottomLeft < mWidget) {
canvas.drawText(bottomMessage, bottomLeft, bottomTop, paint);
} else if ((bottomLeft+bottomMessageWidth)>leftValueWidth) {
int index = (leftValueWidth-bottomLeft)*bottomMessage.length()/bottomMessageWidth+1;
if (index>=0 && index <bottomMessage.length()) {
canvas.drawText(bottomMessage.substring(index), leftValueWidth, bottomTop, paint);
}
}
}
/**
* 绘制条形数据
*/
public void drawDataBar() {
paint.setColor(mDataColor);
int dataValue = Float.valueOf(data.get(VALUE)).intValue();
int bottomLeft = (index + 1) * mSpanBottomText + mChartMovedSize + leftValueWidth + bottomTextPainted;
int dataLeft = bottomLeft + bottomMessageWidth / 2 - dataBarWidth / 4;
int dataBottom = chartDataHeight;
int dataTop = chartDataHeight - (dataValue * (chartDataHeight - dataTopTextHeight - mSpanDataTopText) / piceValue) / 10;
int dataRight = dataLeft + dataBarWidth / 2;
if (dataLeft < leftValueWidth && dataRight > leftValueWidth) {
dataLeft = leftValueWidth;
}
Rect dataRect = new Rect(dataLeft, dataTop, dataRight, dataBottom);
if (dataRight>leftValueWidth) {
canvas.drawRect(dataRect, paint);
}
}
/**
* 绘制条形数据顶部文字
*/
public void drawDataTopText() {
String topTextMessage = data.get(VALUE);
int topTextWidth = getTextWidth(paint, topTextMessage, mDataTopTextSize);
paint.setColor(mDataTopTextColor);
paint.setTextSize(mDataTopTextSize);
int bottomLeft = (index + 1) * mSpanBottomText + mChartMovedSize + leftValueWidth + bottomTextPainted;
int topTextLeft = bottomLeft + (bottomMessageWidth - topTextWidth) / 2;
int dataValue = Float.valueOf(data.get(VALUE)).intValue();
int dataTop = chartDataHeight - (dataValue*(chartDataHeight-dataTopTextHeight - mSpanDataTopText)/piceValue)/10;
int topTextTop = dataTop - mSpanDataTopText * 2 / 3;
if (topTextLeft >= leftValueWidth && bottomLeft < mWidget) {
canvas.drawText(topTextMessage, topTextLeft, topTextTop, paint);
} else if ((topTextLeft+topTextWidth)>leftValueWidth) {
int index = (leftValueWidth-topTextLeft)*topTextMessage.length()/topTextWidth+1;
if (index>=0 && index <topTextMessage.length()) {
canvas.drawText(topTextMessage.substring(index), leftValueWidth, topTextTop, paint);
}
}
}
}
}
实现效果如下图
来源:https://blog.csdn.net/zhoujiulong90/article/details/51106658
0
投稿
猜你喜欢
- 本文为大家分享的java算法计算阶乘,在学习Java课程时经常会遇到求阶乘问题,今天接跟大家一起探讨一下代码如下:package com.x
- 1 运算符1.1 概述运算符 用于连接 表达式 的 操作数,并对操作数执行运算。例如,表达式num1+num2,其操作数是num1和num2
- 在C#的网络编程中,进程和线程是必备的基础知识,同时也是一个重点,所以我们要好好的掌握一下。一:概念首先我们要知道什么是”进程”,什么是“线
- 在Android Studio中对一个自己库进行生成操作时将会同时生成*.jar与*.aar文件。分别存储位置: &n
- Android 解决TextView排版参差不齐的问题在app中,展示数据时,里面有汉字、数字、特殊字符时,由于全角、半角问题导
- 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机
- 单例模式动机有时候只有一个类的实例是很重要的。比如,一个系统应该只有一个窗口管理实例。单例模式是最简单设计模式:类负责实例化自己,确保只有一
- 早期的项目比较简单,多是用JSP 、Servlet + JDBC 直接搞定,后来使用 Struts1(Struts2)+Spring+Hib
- 1.首先是屏蔽浏览器右键菜单的问题,用以下代码可以让浏览器用自己的右键菜单:tempBrowser.ContextMenuStrip = t
- 要求:取指定目录下面的所有图片,以表格的型式展示并显示该图片的相对路径。服务端代码: public partial class ViewIc
- 一、获取当前文件的路径1. System.Diagnostics.Process.GetCurrentProcess().MainModul
- 麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的.今天在做
- 在用C++来开发Windows程序时,经常看到下面的判断情况:HRESULT hr = ::RegCreateKeyEx(hk, szKey
- 1. JSCH简介JSch 是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。你可
- 一、集合排序概述1、主要内容集合中的基本数据类型排序集合中的字符串排序Comparator接口Comparable接口回顾://数组的排序i
- 本文实例讲述了C#简单读取、改变文件的创建、修改及访问时间的方法。分享给大家供大家参考。具体如下:FileInfo fi = new Fil
- 动态参数拼接的查询语句–传入参数类型为自定义数据类型<select id="queryMessageList" p
- 一.先说结论针对任何一个代码记录都进行Revert Commit操作:①不管此记录是commit未push,还是已经push过;②不管此记录
- 我们知道android是基于Looper消息循环的系统,我们通过Handler向Looper包含的MessageQueue投递Message
- 前言本文主要学习函数的相关内容。1、函数是什么? * 中对函数的定义:子程序在计算机科学中,子程序(英语:Subroutine, proc