关于repaint,paint,paintComponent...的问题

shicong2004 2005-04-19 05:12:35
小弟想把控件设为setEnable(false);开始没问题,可后来在方法中加了一条读Socket的阻塞语句
ReadLine(),问题就来了,界面上每个按钮在阻塞时都没变化,必须要等到方法返回才变为disabled,
如果要它马上变化,试着用repaint(),不行,只能用paintComponent(getGraphics())
问题:1 java里面是否在设置控件属性过后并不马上在屏幕上反映出来呢?如果是,那什么时候系统
会自动重绘或修改控件状态呢,除了最大化最小化等等以外,每个方法返回时也会吗?
2 repaint,paint,update,paintComponent等方法到底是怎么调来调去的呀??帮助说一般不要
直接调用paint之类,只需repaint就行了,但是经常直接调能工作,repaint就不行.java里面让我感觉
有点迷惑,不象vc里只需用消息通知系统重绘就行了,而自己只需重写OnPaint. java里应该怎么用他们
呢?
小弟初学,还请各位讲详细一些,越详细越好,先谢过了
...全文
195 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
shicong2004 2005-04-21
  • 打赏
  • 举报
回复
极其感谢
xjffj 2005-04-20
  • 打赏
  • 举报
回复
因为你要为其他绘制操作保留调用过程,如果覆盖paint,那么就完全由你来完成paint了,update和paintChildren就无法进行。
shicong2004 2005-04-19
  • 打赏
  • 举报
回复
哦,谢谢啦
也就是说事件的处理应尽量能立刻返回,耗时和会引起阻塞的过程都应放到后台线程中去对吧?
最后还有个相关的问题,为什么现在推荐覆盖paintComponent而不推荐覆盖paint呢?
xjffj 2005-04-19
  • 打赏
  • 举报
回复
是的,就是这个道理,所以需要把Socket的操作放到独立线程里去。
shicong2004 2005-04-19
  • 打赏
  • 举报
回复
哦,我好象有点明白了,是不是重绘操作和Button按下的操作先后都排在了事件派发线程中,Button
的阻塞导致了重绘操作的不能执行?
xjffj 2005-04-19
  • 打赏
  • 举报
回复
1、难道你的阻塞不是由Button触发的吗?Button按下的动作就是在事件派发线程里的。
2、paintComponent时是直接绘制,是在Socket触发IDle之前,只要这个方法能被执行到,那么就能重新绘制Button
3、repaint是产生一个重绘事件到事件派发线程里去了,所以才不行,paintComponent没有产生事件而是直接绘制。记住绘制和触发重绘是两个过程。
4、是你使用时的错误,不应该在button的Action事件中处理会导致线程阻塞的动作。之所以推荐repaint,是因为系统会合并绘制,同时repaint还能避免组件相互覆盖时的绘制错误。
shicong2004 2005-04-19
  • 打赏
  • 举报
回复
谢谢楼上的回答,不过还是有点不明白
1 既然设置属性之后重绘事件是被放在派发线程里,那么应该说本线程的阻塞并不会造成派发线程
的阻塞呀,那为什么会设置的视觉结果要等到方法返回时再改变呢?关键是我用paintComponent(getGraphics())就能够立刻得到结果,如果是派发线程重绘事件的问题,那这时能成功又是什么原因呢
2 至于repaint不行而paintComponent就行的问题,照楼上的回答的思路,小弟想是否是因为
repaint时派发线程还没有执行到这个事件,因而不能立刻绘出结果?但如果是这样,因该在等待一会之后就能够有结果呀,但事实为什么不是呢?
3 如果repaint不能立刻得到所想的结果,为什么文档中推荐用户调用的是它而不是直接使用其他
几个方法呢,还是我在使用时存在误区?
还望赐教!!!
xjffj 2005-04-19
  • 打赏
  • 举报
回复
其实java里设置属性后会导致重绘的,只不过由于这个重绘事件也被放在事件派发线程里的,因此就导致了事件派发线程被Idle了,要避免这种情况,将这个堵塞动作放到另外的线程里面完成。
repaint是出发重绘动作,当调用repaint后,会通知repaintManager增加一个重绘区域,repaintManager在一定条件下会合并一些重绘区域,然后派发一个绘制动作到事件派发线程(EventQueue)。
事件派发线程执行到这个绘制事件时,就会调用组件的paint,在paint方法里会先调用update来将重绘区域清空(默认情况下是填充白色),然后再调用paintComponent来绘制自身,最后调用paintChildren来绘制所有的子。具体流程可以参考JComponent里的paint方法。
java项目-俄罗斯方块,供学习。 /** * File: GameCanvas.java * User: Administrator * Date: Dec 15, 2003 * Describe: 俄罗斯方块的每一个方块的绘制 */ import javax.swing.*; import javax.swing.border.EtchedBorder; //EtchedBorder为swing包中的突出或凹进的边框 import java.awt.*; /** * 画布类,内有<行数> * <列数>个方格类的实例。 * 继承JPanel类。 * ErsBlock线程类动态改变画布类的方格颜色,画布类通过 * 检查方格颜色来体现ErsBlock块的移动情况。 */ class GameCanvas extends JPanel { //默认的方块的颜色为桔黄色,背景颜色为黑色 private Color backColor = Color.black, frontColor = Color.orange; private int rows, cols, score = 0, scoreForLevelUpdate = 0; private ErsBox[][] boxes; private int boxWidth, boxHeight; //score:得分,scoreForLevelUpdate:上一次升级后的积分 /** * 画布类的第一个版本的构造函数 * @param rows int, 画布的行数 * @param cols int, 画布的列数 * 行数和列数以方格为单位,决定着画布拥有方格的数目 */ public GameCanvas(int rows, int cols) { this.rows = rows; this.cols = cols; //初始化rows*cols个ErsBox对象 boxes = new ErsBox[rows][cols]; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boxes[i][j] = new ErsBox(false); } } //设置画布的边界 setBorder(new EtchedBorder( EtchedBorder.RAISED, Color.white, new Color(148, 145, 140))); } /** * 画布类的第二个版本的构造函数 * @param rows 与public GameCanvas(int rows, int cols)的rows相同 * @param cols 与public GameCanvas(int rows, int cols)的cols相同 * @param backColor Color, 背景色 * @param frontColor Color, 前景色 */ public GameCanvas(int rows, int cols, Color backColor, Color frontColor) { this(rows, cols); //调用第一个版本的构造函数 this.backColor = backColor; this.frontColor = frontColor; //通过参数设置背景和前景颜色 } /** * 设置游戏背景色彩 * @param backColor Color, 背景色彩 */ public void setBackgroundColor(Color backColor) { this.backColor = backColor; } /** * 取得游戏背景色彩 * @return Color, 背景色彩 */ public Color getBackgroundColor() { return backColor; } /** * 设置游戏方块色彩 * @param frontColor Color, 方块色彩 */ public void setBlockColor(Color frontColor) { this.frontColor = frontColor; } /** * 取得游戏方块色彩 * @return Color, 方块色彩 */ public Color getBlockColor() { return frontColor; } /** * 取得画布中方格的行数 * @return int, 方格的行数 */ public int getRows() { return rows; } /** * 取得画布中方格的列数 * @return int, 方格的列数 */ public int getCols() { return cols; } /** * 取得游戏成绩 * @return int, 分数 */ public int getScore() { return score; } /** * 取得自上一次升级后的积分 * @return int, 上一次升级后的积分 */ public int getScoreForLevelUpdate() { return scoreForLevelUpdate; } /** * 升级后,将上一次升级以来的积分清0 */ public void resetScoreForLevelUpdate() { scoreForLevelUpdate -= ErsBlocksGame.PER_LEVEL_SCORE; } /** * 得到某一行某一列的方格引用。 * @param row int, 要引用的方格所在的行 * @param col int, 要引用的方格所在的列 * @return ErsBox, 在row行col列的方格的引用 */ public ErsBox getBox(int row, int col) { if (row < 0 || row > boxes.length - 1 || col < 0 || col > boxes[0].length - 1) return null; return (boxes[row][col]); } /** * 覆盖JComponent类的函数,画组件。 * @param g 图形设备环境 * paint方法实际上把绘图的主要工作委派给paintComponent方法等方法 */ public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(frontColor); for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { //用前景颜色或背景颜色绘制每个方块 g.setColor(boxes[i][j].isColorBox() ? frontColor : backColor); g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight, true); } } } /** * 根据窗口的大小,自动调整方格的尺寸 */ public void fanning() { boxWidth = getSize().width / cols; boxHeight = getSize().height / rows; } /** * 当一行被游戏者叠满后,将此行清除,并为游戏者加分 * @param row int, 要清除的行,是由ErsBoxesGame类计算的 */ public synchronized void removeLine(int row) { for (int i = row; i > 0; i--) { for (int j = 0; j < cols; j++) boxes[i][j] = (ErsBox) boxes[i - 1][j].clone(); } score += ErsBlocksGame.PER_LINE_SCORE; scoreForLevelUpdate += ErsBlocksGame.PER_LINE_SCORE; repaint(); } /** * 重置画布,置积分为0 */ public void reset() { score = 0; scoreForLevelUpdate = 0; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) boxes[i][j].setColor(false); } repaint(); } }
java编的五子棋 import java.util.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.applet.*; import javax.swing.*; class Gobang extends JFrame implements Runnable, ActionListener { final static int Player=1; final static int AI =-1; ClassLoader cl = this.getClass().getClassLoader(); Toolkit tk = Toolkit.getDefaultToolkit(); int length=14, game_state, winner, check, step; int grid[][] = new int[length][length]; int locX, locY /* 囱竚 */, count /* 硈囱计 */, x, y /* 既竚 */, displace_x=0, displace_y=0 /* 簿秖 */, direction; ArrayList steps = new ArrayList(); /* 癘魁囱˙ */ JPopupMenu control_menu = new JPopupMenu(); /* 龄匡虫 */ JMenuItem[] command = new JMenuItem[4]; String[] command_str={"囱", "郎", "弄郎", "秨"}; int[][] dir = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; boolean[] dir2 = new boolean[8]; boolean turn; String message; final JDialog dialog = new JDialog(this, "叫匡", true); Font font=new Font("new_font", Font.BOLD, 20); Grid grids[][] = new Grid[length][length]; Image white= tk.getImage(cl.getResource("res/white.png")); Image black= tk.getImage(cl.getResource("res/black.png")); Image title= tk.getImage(cl.getResource("res/title.png")); Image temp; JPanel boardPanel, bigpanel; JRadioButton[] choice = new JRadioButton[2]; final static int Start =0; final static int Select =1; final static int Playing =2; final static int End =3; final static int nil=-1; /* 礚よ */ final static int oblique_1 =0; /* オ */ final static int oblique_2 =1; /* オ */ final static int horizontal =2; /* 绢 */ final static int vertical=3; /*  */ Gobang() { super("き囱"); boardPanel = new JPanel(); boardPanel.setLayout(new GridLayout(length, length, 0, 0)); boardPanel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); for(int i=0; i=0 && x=0 && y=0 && x=0 && y=5) { game_state=End; winner=check; ThreadStart(); } else if(direction!=nil) WinCheck2(); } public void ReStart() { for(int i=0; i=length || y<0 || y>=length || grid[x][y]!=0) && displace_y<8); for(int i=0; i<8; i++) dir2[i]=false; if(x>=0 && x=0 && y0; i--) { play=!play; gobangAI4(play); if(turn) return; } for(int i=7; i>=4; i--) { play=!play; step=i/2; gobangAI2(play); if(turn) return; } gobangAI5(); if(!turn) gobangRandom(); } private void gobangAI2(boolean player) { check = player? Player: AI; for(int i=0; i=0 && x=0 && y=0 && x+displace_x=0 && y+displace_y=length || y-step*displace_y<0 || y-step*displace_y>=length || !gobang_SpaceAI(x+displace_x, y+displace_y) || (grid[x-step*displace_x][y-step*displace_y]!=0 && step<3) ) /* 癸翴猵 */ gobangAI3_2(); else setMark2(x+displace_x, y+displace_y); } else gobangAI3_2(); } else gobangAI3(x, y); } else gobangAI3_2(); } private void gobangAI3_2() { if(direction!=vertical) { count=1; direction=direction+1; gobangAI3(locX, locY); } } private void gobangAI4(boolean player) { check = player? Player: AI; for(int i=0; i=0 && x=0 && y=0 && x=0 && y=4) setMark(locX, locY); else if(direction!=nil) gobangAI4(); } private void gobangAI5() { for(int i=0; i=0 && x=0 && y=0 && x=0 && y1) { count = count==4? 3: count; while(x>=0 && x=0 && y=0 && x=0 && y=5) /* 逞緇フ场だΤ硈絬ぇ */ return true; else { space=0; x=locX-displace_x; y=locY-displace_y; while(x>=0 && x=0 && y=5) /* 逞緇フ场だΤ硈絬ぇ */ return true; else return false; } } public void ThreadStart() { new Thread(this).start(); } private void setMark(int x, int y) { steps.add(grids[x][y]); grids[x][y].setValue(-1); WinCheck(); turn=true; } /* 璸衡êよΤ隔 */ private void setMark2(int x, int y) { int space=0, temp_x=x, temp_y=y; do { space=space+1; temp_x=temp_x+displace_x; temp_y=temp_y+displace_y; }while(temp_x>=0 && temp_x=0 && temp_y=5) setMark(x, y); else setMark(x-(step+1)*displace_x, y-(step+1)*displace_y); /* э癸翴 */ } public void run() { try { switch(game_state) { case Start: Thread.sleep(2000); dialog.show(); game_state=Playing; repaint(); break; case End: repaint(); Thread.sleep(1500); ReStart(); repaint(); break; } } catch(InterruptedException ex) { } } public void paint(Graphics g) { super.paint(g); switch(game_state) { case Start: g.drawString("2005.7 by Yu Lin Tao", 91, 240); g.setFont(font); g.setColor(Color.BLUE); g.drawString("Gobang", 112, 120); g.drawImage(title, 134, 135, this); break; case Playing: case End: g.drawString("產: 筿福:", 105, 40); g.drawImage(black, 132, 30, this); g.drawImage(white, 182, 30, this); if(winner!=0) { g.setFont(font); g.setColor(Color.RED); message = winner==1? "墓":"块"; g.drawString(message, 120, 185); } break; } } public void undo() { if(steps.size()>0) { for(int i=0; i<2; i++) { ((Grid)steps.get(steps.size()-1)).Initial(); steps.remove(steps.size()-1); } } } private void Save() { String str; try { File file = new File("innings.men"); file.createNewFile(); BufferedWriter write = new BufferedWriter(new FileWriter(file)); for(int i=0; irepaint(); } public void setValue(int new_value) { locX=x; locY=y; value=grid[x][y]=new_value; repaint(); } public void setSelected(boolean select) { selected=select; repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); if(game_state!=Start && game_state!=Select) { g.drawLine(0, 10, 19, 10); g.drawLine(10, 0, 10, 19); /* 礶娩絬 */ g.setColor(Color.BLUE); if(x==0) g.drawLine(0, 0, 19, 0); else if(x==length-1) g.drawLine(0, 19, 19, 19); if(y==0) g.drawLine(19, 0, 19, 19); else if(y==length-1) g.drawLine(0, 0, 0, 19); if(selected) setBackground(Color.WHITE); else setBackground(Color.LIGHT_GRAY); } //g.drawString(x+" "+y, 1, 10); if(value!=0) { temp = value==1? black: white; g.drawImage(temp, 4, 4, this); } } } }
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; class FrameClass extends Frame // implements ActionListener { MenuBar mb; Menu caozuo,shezhi,bangzhu; MenuItem star,close; TangGraphics p=new TangGraphics(); JButton star1,over; JPanel p1,p2; NextOne p3; Scors p4; Thread tankthread; Random makeobjet; int N,next; boolean isgo=false; Label string; FrameClass() { super("测试俄罗斯方块"); setSize(241,232); setLocation(400,200); setLayout(new BorderLayout(10,10)); makeobjet=new Random(); N=makeobjet.nextInt(19); setBackground(Color.yellow); mb=new MenuBar(); caozuo=new Menu("操作"); shezhi=new Menu("设置"); bangzhu=new Menu("帮助"); caozuo.add(star=new MenuItem("开始")); caozuo.add(close=new MenuItem("结束")); mb.add(caozuo); mb.add(shezhi); mb.add(bangzhu); setMenuBar(mb); string=new Label("制作人: 连泽荣 "); star1=new JButton("开始"); over=new JButton("结束"); p1=new JPanel(new GridLayout(3,1,10,10)); p2=new JPanel(); p3=new NextOne(N); p4=new Scors("0 point"); p4.setBackground(Color.green); p1.add(p3); p1.add(p4); p1.add(p2); p1.setBackground(Color.yellow); // p2.setLayout(new GridLayout(1,2,10,10)); p2.add(string); // p2.add(star1); // p2.add(over); p3.setBackground(Color.black); p3.setSize(100,60); add(p,"Center"); add(p1,"East"); setResizable(false); // star1.addActionListener(this); // over.addActionListener(this); addWindowListener(new windowlistener()); addKeyListener(new keymonitor()); setVisible(true); // tankthread=new Thread(new listenermonitor()); // tankthread.start(); } public void test() { // System.out.print(" ,x="+p3.getWidth()+" y="+p3.getHeight()); p.draw(next); } public void initp() { p.initmap(); while(!p.gameOver()) { p4.getScors(String.valueOf(p.count)+" ponit"); if(p.box.islive()==false) { next=N; N=makeobjet.nextInt(19); p3.getN(N); test(); } } } public static void main(String argc[]) { (new FrameClass()).initp(); } class windowlistener extends WindowAdapter{ public void windowClosing(WindowEvent e){System.exit(0);} } // private class keymonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { p.keyPressed(e); } } } import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.awt.Graphics; import java.util.*; class NextOne extends JPanel { int BOX[][][]= { { {2,2,2,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} }, { {2,0,0,0}, {2,0,0,0}, {2,0,0,0}, {2,0,0,0} }, { {3,3,3,0}, {3,0,0,0}, {0,0,0,0}, {0,0,0,0} }, { {3,3,0,0}, {0,3,0,0}, {0,3,0,0}, {0,0,0,0} }, { {0,0,3,0}, {3,3,3,0}, {0,0,0,0}, {0,0,0,0} }, { {3,0,0,0}, {3,0,0,0}, {3,3,0,0}, {0,0,0,0} }, { {4,4,4,0}, {0,0,4,0}, {0,0,0,0}, {0,0,0,0} }, { {0,4,0,0}, {0,4,0,0}, {4,4,0,0}, {0,0,0,0} }, { {4,0,0,0}, {4,4,4,0}, {0,0,0,0}, {0,0,0,0} }, { {4,4,0,0}, {4,0,0,0}, {4,0,0,0}, {0,0,0,0} }, { {5,5,5,0}, {0,5,0,0}, {0,0,0,0}, {0,0,0,0} }, { {0,5,0,0}, {5,5,0,0}, {0,5,0,0}, {0,0,0,0} }, { {0,5,0,0}, {5,5,5,0}, {0,0,0,0}, {0,0,0,0} }, { {5,0,0,0}, {5,5,0,0}, {5,0,0,0}, {0,0,0,0} }, { {6,6,0,0}, {0,6,6,0}, {0,0,0,0}, {0,0,0,0} }, { {0,6,0,0}, {6,6,0,0}, {6,0,0,0}, {0,0,0,0} }, { {0,7,7,0}, {7,7,0,0}, {0,0,0,0}, {0,0,0,0} }, { {7,0,0,0}, {7,7,0,0}, {0,7,0,0}, {0,0,0,0} }, { {8,8,0,0}, {8,8,0,0}, {0,0,0,0}, {0,0,0,0} } }; int N; Thread tankthread; Random makeobjet; public NextOne(int N) { setBorder(BorderFactory.createRaisedBevelBorder()); setBackground(Color.black); this.N=N; tankthread=new Thread(new listenermonitor()); tankthread.start(); } public void getN(int N){ this.N=N; } public void paint(Graphics g) { int i,j; super.paintComponent(g); Color c=g.getColor(); g.setColor(Color.red); for(i=0;i<4;i++) for(j=0;j<4;j++) { if(BOX[N][i][j]!=0) { g.fill3DRect(40+i*10,10+j*10,10,10,true); } } g.setColor(c); } private class listenermonitor implements Runnable { public void run() { while(true) { repaint(); try { Thread.sleep(350); } catch(Exception e){} } } } }

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧