📄 table.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.border.*;
//*****表格中的竖线*****
class MyLineL
{ int x,y1,y2;
MyLineL(int a,int b,int c)
{
x=a;y1=b;y2=c;
}
void paintL(Graphics g) //画线
{
g.drawLine(x,y1,x,y2);
}
void setLineL(int a,int b,int c)
{
x=a;y1=b;y2=c;
}
}
//*****表格中的横线*****
class MyLineH
{ int x1,x2,y;
MyLineH(int a,int b,int c)
{
x1=a;x2=b;y=c;
}
void paintH(Graphics g)//画线
{
g.drawLine(x1,y,x2,y);
}
void setLineH(int a,int b,int c)
{
x1=a;x2=b;y=c;
}
}
//*****单元格中的字符*****
class MyString
{
String str;
int x; //字符的横坐标
int y; //字符的纵坐标
MyString(String s)
{ str=s; }
}
/*****用来输入行数列数的窗口*****
把标签列数、行数放在一个从上到下显示其组件的box1里,
把text1和text2放在一个也是从上到下显示其组件的box2里,再把box1和box2放在一个
从左到右显示其组件的boxBase1里,把按钮button1和button2放在boxBase2里,
最后把boxBase1和boxBase2放在窗口里显示*/
class TableFrame extends JFrame implements ActionListener
{ Box boxBase1,boxBase2,box1,box2;
JPanel panel;
JLabel label1,label2;
JTextField text1,text2;
JButton button1,button2;
TableFrame()
{
label1=new JLabel("列数");
label1.setFont(new java.awt.Font("黑体", 0, 20)); //设置标签字体
label2=new JLabel("行数");
label2.setFont(new java.awt.Font("黑体", 0, 20));
box1= Box.createVerticalBox(); //上到下显示其组件的box1
box1.add(Box.createVerticalStrut(50));//添加竖向的支撑
box1.add(label1); //把标签label1夹在box1上
box1.add(Box.createVerticalStrut(30));
box1.add(label2);
box1.add(Box.createVerticalStrut(30));
text1=new JTextField(10);
text1.setFont(new java.awt.Font("黑体", 0, 20));
text2=new JTextField(10);
text2.setFont(new java.awt.Font("黑体", 0, 20));
box2= Box.createVerticalBox();
box2.add(Box.createVerticalStrut(50));
box2.add(text1);
box2.add(Box.createVerticalStrut(30));
box2.add(text2);
box2.add(Box.createVerticalStrut(30));
boxBase1=Box.createHorizontalBox(); //从左到右显示其组件的boxBase1
boxBase1.add(box1);
boxBase1.add(Box.createHorizontalStrut(60));//添加横向的支撑
boxBase1.add(box2);
button1=new JButton("确定");
button1.setFont(new java.awt.Font("黑体", 0, 20));
button2=new JButton("取消");
button2.setFont(new java.awt.Font("黑体", 0, 20));
boxBase2=Box.createHorizontalBox();
boxBase2.add(button1);
boxBase2.add(Box.createHorizontalStrut(60));
boxBase2.add(button2);
add(boxBase1);
add(boxBase2);
text2.addActionListener(this); //把窗口作为text2的监听器
button1.addActionListener(this);
button2.addActionListener(this);
addWindowListener(new WindowAdapter() //使用WindowAdapter适配器以实现窗口关闭
{ public void windowClosing(WindowEvent e)
{ System.exit(0); }
});
setLayout(new FlowLayout()); //设置布局
setBounds(120,125,400,350);
setVisible(true);
validate();
}
public void actionPerformed(ActionEvent e) { //实现接口ActionListener的抽象方法
if(e.getSource()==text2)
{
WinTable win=new WinTable();
}
if(e.getSource()==button1)
{
WinTable win=new WinTable();
}
if(e.getSource()==button2)
{
text1.setText("");
text2.setText("");
}
}
//*****作为TableFrame的内部类,用于生成表格*****
class WinTable extends Frame implements MouseListener,MouseMotionListener,KeyListener
{
int l=Integer.parseInt(text1.getText());
int h=Integer.parseInt(text2.getText());
MyLineL []lineL=new MyLineL[l+1]; //需要画l+1根竖线
MyLineH []lineH=new MyLineH[h+1]; //需要画h+1根横线
MyString []mystr=new MyString[h*l]; //有h*l个单元格,就有h*l个字符串
boolean boolL=false; //用于标记鼠标按下的位置是否是列所在的位置
boolean boolH=false; //用于标记鼠标按下的位置是否是行所在的位置
int dragL; //用于标记是第几列被鼠标拖动
int dragH; //用于标记是第几行被鼠标拖动
int editL; //用于标记是第几列被编辑输入字符
int editH; //用于标记是第几行被编辑输入字符
WinTable()
{
for(int j=0;j<l+1;j++) //初始化表格中的列
lineL[j]=new MyLineL(50+80*j,50,50+50*h);
for(int i=0;i<h+1;i++) //初始化表格中的行
lineH[i]=new MyLineH(50,50+80*l,50+50*i);
for(int s=0;s<h*l;s++) //初始化单元格中的字符串
mystr[s]=new MyString(new String());
addMouseListener(this); //用于处理鼠标事件
addMouseMotionListener(this);//用于处理鼠标事件
addKeyListener(this); //用于处理键盘事件
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0); }
});
setBounds(400,400,600,500);
setVisible(true);
}
public void paint(Graphics g)
{ g.setFont(new Font("黑体", 0, 20)); //设置写出字符的字体
for(int i=0;i<h+1;i++) //画出列
lineH[i].paintH(g);
for(int j=0;j<l+1;j++) //画出列
lineL[j].paintL(g);
for(int s=0;s<h*l;s++) //写出字符串
{
g.drawString(mystr[s].str,mystr[s].x,mystr[s].y);
}
}
public void mousePressed(MouseEvent e) {
for(int i=0;i<h+1;i++)
for(int j=0;j<l+1;j++)
{
if((e.getY()>=lineH[i].y-5)&&(e.getY()<=lineH[i].y+5)) //当鼠标在某一行纵坐标的左右5个点范围内按下时,即返回
{ //此行的值,并标记拖动行,拖动列的标识为false,用以防止
dragH=i; //鼠标拖动时行和列都在移动
boolH=true;
boolL=false;
}
if((e.getX()>=lineL[j].x-5)&&(e.getX()<=lineL[j].x+5))
{
dragL=j;
boolL=true;
boolH=false;
}
}
if(e.getX()<(lineL[0].x-10)||e.getX()>(lineL[l].x+20)||e.getY()<(lineH[0].y-10)||e.getY()>(lineH[h].y+20))
{
boolL=false; //防止鼠标在表格外移动时,导致表格线的变化
boolH=false;
}
}
public void mouseDragged(MouseEvent e) {
if(boolH==true) //如果鼠标是在拖动行时
{ if(dragH==0||dragH==h) //如果拖动的是第一行或者最后一行时
{
lineH[dragH].setLineH(lineL[0].x,lineL[l].x,e.getY()); //改变行的坐标
for(int j=0;j<l+1;j++) //每一列的坐标也要改变
lineL[j].setLineL(lineL[j].x,lineH[0].y,lineH[h].y);
}
else //如果拖动的不是第一行或者最后一行
lineH[dragH].setLineH(lineL[0].x,lineL[l].x,e.getY());
}
if(boolL==true) //如果鼠标是在拖动列
{ if(dragL==0||dragL==l) //如果拖动的是第一列或者最后一列时
{
lineL[dragL].setLineL(e.getX(),lineH[0].y,lineH[h].y); //改变列的坐标
for(int i=0;i<h+1;i++) //每一行的坐标也要改变
lineH[i].setLineH(lineL[0].x,lineL[l].x,lineH[i].y);
}
else //如果拖动的不是第一列或者最后一列
lineL[dragL].setLineL(e.getX(),lineH[0].y,lineH[h].y);
}
for(int i=1;i<h+1;i++) //行或者列的坐标改变单元格字符串的位置也要改变
for(int j=0;j<l;j++)
{ mystr[(i-1)*l+j].x=lineL[j].x+20;
mystr[(i-1)*l+j].y=lineH[i].y-10;
}
repaint();
}
public void mouseMoved(MouseEvent e) { //鼠标光标的改变有些情况下没能实现
Cursor c=Cursor.getPredefinedCursor(Cursor. DEFAULT_CURSOR); //默认光标类型
for(int i=0;i<h+1;i++)
{ for(int j=0;j<l+1;j++)
{ if(e.getY()<=(lineH[i].y+5)&&e.getY()>(lineH[i].y-5))
{ c=Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR); //调整窗口上边框位置的光标类型
setCursor(c);
}
if(e.getX()==lineL[j].x)
{ c=Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); //调整窗口左边框位置的光标类型
setCursor(c);
}
if(e.getY()!=lineH[i].y&&e.getX()!=lineL[j].x)
{ c=Cursor.getPredefinedCursor(Cursor. DEFAULT_CURSOR);
setCursor(c);
}
}
}
}
public void keyTyped(KeyEvent e) { //处理键盘输入事件
int i=editH; //单元格字符串数组的是以右下角点所在行和列来命名的。
int j=editL; //例如,右下角点在第2行第0列,该单元格就为mystr【2*l】
mystr[(i-1)*l+j].str=mystr[(i-1)*l+j].str.concat(new String().valueOf(e.getKeyChar()));//在
mystr[(i-1)*l+j].x=lineL[j].x+20;
mystr[(i-1)*l+j].y=lineH[i].y-10;
Graphics g=getGraphics();
g.setFont(new Font("黑体", 0, 20));
g.drawString( mystr[(i-1)*l+j].str,mystr[(i-1)*l+j].x,mystr[(i-1)*l+j].y);
}
public void mouseClicked(MouseEvent e) {
for(int i=1;i<h+1;i++) //当鼠标在单元格内单击时,改变鼠标光标为文字光标
for(int j=0;j<l;j++)
if((e.getY()>lineH[i-1].y+5)&&(e.getY()<lineH[i].y-5)&&(e.getX()>lineL[j].x+5)&&(e.getX()<lineL[j+1].x-5))
{
editL=j;
editH=i;
Cursor c=Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
setCursor(c);
}
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
}
public class Table { //主类
public static void main(String args[])
{
new TableFrame();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -