JPanel繪圖
在Java Swing中簡易繪圖,可以直接把JPanel當成畫布來使用。上圖視窗中加入一個JPanel, 命名為canvas. 然後再加入一顆按鈕btn。
canvas的中心點(ox, oy)的取得,可以由(canvas.getWidth()/2, canvas.getHeight()/2)取得。
JPanel繪圖,需先使用canvas.getGraphics()取得 Graphics物件 g。然後再由 g 進行繪圖,如
g.drawLine(), g.drawCircle()…等方法
private void btnActionPerformed(java.awt.event.ActionEvent evt) { int x, y, px, py, ox, oy; int w=canvas.getWidth(); int h=canvas.getHeight(); ox=w/2;//中心點x座標 oy=h/2;//中心點y座標 int n=100;//要畫的點數 double radius=50;//半徑 Graphics painter=canvas.getGraphics(); //畫x, y軸 painter.setColor(Color.RED); painter.drawLine(0,h/2, w, h/2); painter.drawLine(w/2, 0, w/2, h); painter.setColor(Color.BLUE); //畫圓型 for (int j=0;j<10;j++){ radius=radius+20; px=(int)radius+ox;py=oy; int r=(int)(Math.random()*256); int g=(int)(Math.random()*256); int b=(int)(Math.random()*256); for (int i=0;i<=n;i++){ double angle=i*360.0/n; painter.setColor(new Color(r, g, b)); x=(int)(radius*Math.cos(Math.PI/180.0*angle)+ox);
y=(int)(radius*Math.sin(Math.PI/180.0*angle)+oy); /* painter.drawOval(x, y, 40,20); //painter.drawLine(px, py, x, y); */ Graphics2D p=(Graphics2D)painter; Ellipse2D c=new Ellipse2D.Double(px, py, 5, 5); p.fill(c); px=x;py=y; } }
}
paint方法
JPanel在視窗成形,resize,或外部update時,就會執行paint()方法。所以如果希望上述在移動視窗時,圖形還是保留著,那就就要把上面的代碼寫在paint()方法中。
所以此時需繼承JPanel類別,然後覆寫paint()方法
class MyPanel extends JPanel{ public void paint(Graphics g){ super.paint(g); int x, y, px, py, ox, oy; int w=getWidth(); int h=getHeight(); ox=w/2;//中心點x座標 oy=h/2;//中心點y座標 int n=100;//要畫的點數 double radius=50;//半徑 //Graphics painter=getGraphics(); //畫x, y軸 g.setColor(Color.RED); g.drawLine(0,h/2, w, h/2); g.drawLine(w/2, 0, w/2, h); g.setColor(Color.BLUE); //畫圓型 for (int j=0;j<10;j++){ radius=radius+20; px=(int)radius+ox;py=oy; int rc=(int)(Math.random()*256); int gc=(int)(Math.random()*256); int bc=(int)(Math.random()*256); for (int i=0;i<=n;i++){ double angle=i*360.0/n; g.setColor(new Color(rc, gc, bc)); x=(int)(radius*Math.cos(Math.PI/180.0*angle)+ox); y=(int)(radius*Math.sin(Math.PI/180.0*angle)+oy); //g.drawOval(x, y, 40,20); //g.drawLine(px, py, x, y); Graphics2D g2d=(Graphics2D)g; Ellipse2D c=new Ellipse2D.Double(px, py, 5, 5); g2d.fill(c); px=x;py=y; } } } }
然後在btnActionPerformed加入MyPanel()即可
private void btnActionPerformed(java.awt.event.ActionEvent evt) {
MyPanel p=new MyPanel();
canvas.setLayout(new javax.swing.BoxLayout(canvas, javax.swing.BoxLayout.Y_AXIS));
canvas.add(p);
canvas.updateUI();
}
動畫
底下代碼,可以實現Eve的動畫。eve圖檔下載
import java.awt.Dimension; import java.awt.Image; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.SwingUtilities; public class MainFrame extends javax.swing.JFrame { public MainFrame() { initComponents(); } @SuppressWarnings("unchecked") // private void initComponents() { canvas = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); jPanel3 = new javax.swing.JPanel(); jPanel4 = new javax.swing.JPanel(); btnStop = new javax.swing.JButton(); btnNew = new javax.swing.JButton(); jPanel5 = new javax.swing.JPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS)); javax.swing.GroupLayout canvasLayout = new javax.swing.GroupLayout(canvas); canvas.setLayout(canvasLayout); canvasLayout.setHorizontalGroup( canvasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 897, Short.MAX_VALUE) ); canvasLayout.setVerticalGroup( canvasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 360, Short.MAX_VALUE) ); getContentPane().add(canvas); jPanel2.setMaximumSize(new java.awt.Dimension(32767, 50)); jPanel2.setMinimumSize(new java.awt.Dimension(0, 50)); jPanel2.setPreferredSize(new java.awt.Dimension(897, 50)); jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.X_AXIS)); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 378, Short.MAX_VALUE) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 50, Short.MAX_VALUE) ); jPanel2.add(jPanel3); jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.X_AXIS)); btnStop.setText("結束"); btnStop.setMaximumSize(new java.awt.Dimension(70, 50)); btnStop.setMinimumSize(new java.awt.Dimension(70, 50)); btnStop.setPreferredSize(new java.awt.Dimension(70, 50)); btnStop.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnStopActionPerformed(evt); } }); jPanel4.add(btnStop); btnNew.setText("產生"); btnNew.setMaximumSize(new java.awt.Dimension(70, 50)); btnNew.setMinimumSize(new java.awt.Dimension(70, 50)); btnNew.setPreferredSize(new java.awt.Dimension(70, 50)); btnNew.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnNewActionPerformed(evt); } }); jPanel4.add(btnNew); jPanel2.add(jPanel4); javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); jPanel5.setLayout(jPanel5Layout); jPanel5Layout.setHorizontalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 378, Short.MAX_VALUE) ); jPanel5Layout.setVerticalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 50, Short.MAX_VALUE) ); jPanel2.add(jPanel5); getContentPane().add(jPanel2); pack(); }// List<Eve> ls=new ArrayList<>(); private void btnNewActionPerformed(java.awt.event.ActionEvent evt) { try{ Eve e=new Eve((int)(Math.random()*70)+20); ls.add(e); canvas.add(e); canvas.setLayout(new javax.swing.BoxLayout(canvas, javax.swing.BoxLayout.X_AXIS)); } catch(IOException e){} } private void btnStopActionPerformed(java.awt.event.ActionEvent evt) { for (Eve e : ls){ e.close(); } System.exit(0); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MainFrame().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton btnNew; private javax.swing.JButton btnStop; private javax.swing.JPanel canvas; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel5; // End of variables declaration } class Eve extends JLabel{ ImageIcon[]imgs; Thread thread; boolean runFlag=true; int index=0; int delay; public Eve(int delay) throws IOException{ int w=200; int h=180; this.delay=delay; this.setMaximumSize(new Dimension(w, h)); this.setMinimumSize(new Dimension(w, h)); this.setPreferredSize(new Dimension(w, h)); imgs=new ImageIcon[36]; for (int i=0;i<imgs.length;i++){ Image img=ImageIO.read(new File(String.format("frame_%02d.png", i+1))); imgs[i]=new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)); } thread=new Thread(()->{ while(runFlag){ SwingUtilities.invokeLater(()->{this.setIcon(imgs[index]);}); try{Thread.sleep(this.delay);} catch(InterruptedException e){} index=(index+1)%imgs.length; } }); thread.start(); } public void close(){ runFlag=false; thread.interrupt(); } }