2013-05-06 98 views
0

我正在物理模擬器上工作,並使用swing進行渲染。我想通過添加菜單欄和其他組件來改進界面。然而,當我嘗試和剪輯的圖紙是,在菜單欄的高度沒有考慮到,作爲一個結果,我的畫轉移比它應該 這裏是更高一些示例代碼來說明:活動渲染時如何解釋菜單欄高度?

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.Insets; 
import java.awt.Rectangle; 
import java.awt.image.BufferStrategy; 
import javax.swing.border.Border; 
public class TestFrame extends javax.swing.JFrame { 

    public TestFrame() { 
     initComponents(); 
    }   

    public static void main(String args[]) { 

     //initalize and show the frame 
     TestFrame frame= new TestFrame(); 
     frame.setVisible(true); 

     //creat buffer strategy 
     frame.createBufferStrategy(2); 
     BufferStrategy bufferStrategy = frame.getBufferStrategy(); 

     //loop through rendering loop 
     while(true) 
     { 
      //get the graphics context to draw on 
      Graphics2D drawGraphics=(Graphics2D) bufferStrategy.getDrawGraphics(); 
      frame.paint(drawGraphics); 

      Rectangle bounds=frame.drawingPanel.getBounds(); 

      //account for frame's insets 
      Insets insets=frame.getInsets(); 
      bounds.x+=insets.left; 
      bounds.y+=insets.top; 
      Border border = frame.drawingPanel.getBorder(); 

      //account for the Border's insets 
      insets=border.getBorderInsets(frame.drawingPanel); 
      bounds.x+=insets.left; 
      bounds.y+=insets.top; 
      bounds.width-=insets.left+insets.right; 
      bounds.height-=insets.top+insets.right; 

      //draw a test rectangle    
      drawGraphics.setColor(new Color(0,255,0,64)); 
      drawGraphics.fill(bounds); 

      //show rendering and then dispose 
      bufferStrategy.show(); 
      drawGraphics.dispose(); 
     } 
    } 
    private javax.swing.JPanel drawingPanel; 
    private javax.swing.JMenu editMenu; 
    private javax.swing.JMenu fileMenu; 
    private javax.swing.JMenuBar menuBar; 
} 

initComponents()內容:

private void initComponents() { 

     drawingPanel = new javax.swing.JPanel(); 
     menuBar = new javax.swing.JMenuBar(); 
     fileMenu = new javax.swing.JMenu(); 
     editMenu = new javax.swing.JMenu(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     drawingPanel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED)); 

     javax.swing.GroupLayout drawingPanelLayout = new javax.swing.GroupLayout(drawingPanel); 
     drawingPanel.setLayout(drawingPanelLayout); 
     drawingPanelLayout.setHorizontalGroup(
      drawingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 100, Short.MAX_VALUE) 
     ); 
     drawingPanelLayout.setVerticalGroup(
      drawingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 100, Short.MAX_VALUE) 
     ); 

     fileMenu.setText("File"); 
     menuBar.add(fileMenu); 

     editMenu.setText("Edit"); 
     menuBar.add(editMenu); 

     setJMenuBar(menuBar); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(284, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(162, Short.MAX_VALUE)) 
     ); 

     pack(); 
    } 

我能想到的另一種選擇是讓繪圖代碼設在jPanelpaint方法。

+0

您的渲染循環看起來非常可疑。它幾乎會耗盡你的資源。調用繪圖時調用重繪應該足夠了。可能你可能需要定時重畫一個Swing Timer。 – 2013-05-06 22:39:30

+0

我已經省略了更新代碼狀態的代碼,因爲我在正確渲染位置時遇到了問題。在渲染循環中,我更新了對象狀態,然後繪製它們。 – vandale 2013-05-06 23:41:31

+0

你有事情倒退。您的模型必須自行修改,然後通知視圖,以便重新繪製自己。在這裏你做相反的事情,你有你的觀點,更新模型,然後重新繪製自己。 'repaint()'可以被操作系統調用,但它應該主要是你的代碼來調用它。一段時間(真的)循環不斷重新繪製你的視圖是不是要走的路。 – 2013-05-07 08:18:04

回答

2

我能想到的另一種選擇是讓繪圖代碼設在jPanelpaint方法。

是的,但使用paintComponent

public class PhysicsPanel extends JPanel { 
// (or extend JComponent if you don't need to `add` anything) 

    @Override 
    public void paintComponent(Graphics g) { 
     // painting code 
    } 
} 

然後,只需添加一個PhysicsPanel到您的主框架;框架上的repaint也會重新繪製物理面板。

+1

這是標準建議,但在使用主動渲染時可能不適用,原始海報聲明他正在執行此操作。 – 2013-05-06 21:58:12

+0

我使用它來進行主動渲染,並且它工作正常(假設通過「主動渲染」你意味着一個「while循環」並在緩衝區策略上畫一個Canvas)。 – wchargin 2013-05-06 22:05:08

+0

我曾經在幾個地方見過不把繪畫代碼放在繪畫方法中,所以我認爲它也適用於其他繪畫方法。通過「主動渲染」,我的意思是說,我正在讓程序更新其狀態,然後繪製它,而不是等待操作系統發送重繪消息。 – vandale 2013-05-06 23:30:32