JAVA中Swing的绘制原理以及如何实现动态图画
2017-10-27 22:04
1091 查看
首先先吐槽一下用JAVA做界面的辛苦,往面板里绘制东西要获取他的Graphics,可往往要往里面画的类是别的类,然后你往里面画的时候…..坑就出来了。
如果不想调用paintComponent(),可以将super.paint()注释掉,这对于Jpanel来说是没有什么问题的,但对于其他组件,例如JButton来说,JButton就不可正常显示了。
图片插入不了,自己脑补吧。
所以可以自己根据实际情况来将自己要写的函数写在paint()或者paintComponent()
这里要注意,如果你在调用了paint()同一个线程里调用repaint(),他不会重新绘制,因为paint()会查看你是否已经绘制了该组件,如果绘制了就不可重新绘制。所以在这里我们新建一个线程来执行重新绘制。同理,在已经绘制组件后获取组件的Graphics进行绘图也不会有任何显示。
例如
源码里的调用时这样的,具体逻辑可在JDK里看。
Timer的主要用处在于创建一个新的线程,也可以用监听器代替。
注意不要写成这样,这样图画会闪烁不连续,具体为什么我也不太清楚了,可能是Swing画图时的会自己创建线程,导致抢资源了。
Swing组件绘制的原理
组件在初始画的时候会调用组件本身自带的paint()和paintComponent(),绘制出他想要的样子,如果你单纯想改变他的形状和样子时,就可以重写paint()或者paintComponent来达成。不过要注意,在Swing的原始组件中的paint()会调用paintComponent(),假如你想在paint()里绘制某个图像,paintComponent中绘制另一个()并且不想两个图像混在一起。看下列实例
以JPanel为例public class MyPanel extends JPanel{ @Override protected void paintComponent (Graphics g) { super.paintComponent(g); System.out.println("component"); } @Override public void paint (Graphics g) { super.paint(g); System.out.println("paint"); } public static void main(String [] ars){ JFrame frame = new JFrame("paintTest"); MyPanel panel = new MyPanel(); frame.add(panel); frame.setSize(300,300); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.setVisible(true); } class MyButton() }
运行结果是: component paint
如果不想调用paintComponent(),可以将super.paint()注释掉,这对于Jpanel来说是没有什么问题的,但对于其他组件,例如JButton来说,JButton就不可正常显示了。
public class MyButton extends JButton { public MyButton (String string) { super(string); } @Override protected void paintComponent (Graphics g) { super.paintComponent(g); } @Override public void paint (Graphics g) { // super.paint(g); } } MyButton button = new MyButton("button"); frame.add(button,BorderLayout.EAST);
图片插入不了,自己脑补吧。
所以可以自己根据实际情况来将自己要写的函数写在paint()或者paintComponent()
repaint()的实质其实是调用paint()重新绘制组件
timer.schedule(new TimerTask() { @Override public void run ( ) { panel.repaint(); } },1000);
这里要注意,如果你在调用了paint()同一个线程里调用repaint(),他不会重新绘制,因为paint()会查看你是否已经绘制了该组件,如果绘制了就不可重新绘制。所以在这里我们新建一个线程来执行重新绘制。同理,在已经绘制组件后获取组件的Graphics进行绘图也不会有任何显示。
例如
public static void main(String [] ars){ JFrame frame = new JFrame("paintTest"); MyPanel panel = new MyPanel(); frame.add(panel); frame.setSize(400,400); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); /*panel.repaint();这样不会panel不会重新绘制*/ /*或者 Graphics graphics = panel.getGraphics(); graphics.drawLine(0,0,50,50) 这样也不会有任何作用 */ }
源码里的调用时这样的,具体逻辑可在JDK里看。
boolean printing = getFlag(IS_PRINTING);
结果是 component paint component paint
动态图画的绘制
下面举出一个实例来实现动态图画
public class MyPanel extends JPanel{ int x =50; int y =50; @Override public void paint (Graphics g) { super.paint(g); g.setColor(Color.red); g.fillOval(x,y,30,30); } public static void main(String [] ars){ JFrame frame = new JFrame("paintTest"); MyPanel panel = new MyPanel(); frame.add(panel); frame.setSize(400,400); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); panel.repaint(); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run ( ) { if(panel.x<=300){ panel.x++; panel.repaint(); } } },0,20); } }
Timer的主要用处在于创建一个新的线程,也可以用监听器代替。
注意不要写成这样,这样图画会闪烁不连续,具体为什么我也不太清楚了,可能是Swing画图时的会自己创建线程,导致抢资源了。
timer.schedule(new TimerTask() { Graphics graphics = panel.getGraphics(); @Override public void run ( ) { if(panel.x<=300){ graphics.setColor(Color.red); graphics.fillOval(panel.x,panel.y,30,30); panel.x++; panel.repaint(); } } },0,10);
相关文章推荐
- java 如何实现动态代理(mybatis底层原理)
- java动态代理的实现以及原理
- JAVA swing中JPanel如何实现分组框的效果以及设置边框颜色
- JAVA动态模块的设计实现以及如何通过newInstance()来创建带参的构造类实例
- CRC32算法学习笔记以及如何用java实现(一)
- Java中ThreadLocal类的作用以及实现原理
- CRC32算法学习笔记以及如何用java实现
- 在Spring中,是如何实现 Aop 的,原理:动态代理+cglib 分步图解
- excel导出时 如何根据java后台返回的结果 动态实现excel复选框的勾选
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- Java中ThreadLocal类的作用以及实现原理
- android动态布局:用java代码实现LinearLayout以及TextView
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- swing中JPanel如何实现分组框的效果以及设置边框颜色
- java实现单项链表以及如何检测回环
- 如何实现动态创建iframe,以及拖动iframe
- 利用Java Reflection(反射)原理,在hibernate里面实现对单表、视图的动态组合查询
- wp7 不重启程序之动态换肤实现原理以及源码
- CRC32算法学习笔记以及如何用java实现(一)
- CRC32算法学习笔记以及如何用java实现(一)