2015-04-28 89 views
4

主要問題是我想用一些標籤繪製圖形。對於繪圖,我使用以下類:使用Swing繪圖文本

public class Canvas extends JPanel { 

    // Lot of other methods 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 

     // Other code 

     g2.setColor(Style.LIGHT_GREY); 
     g2.fillOval(node.getPosition().x, node.getPosition().y, Style.SHAPE_SIZE, Style.SHAPE_SIZE); 

     g2.setColor(Style.DARK_GREY); 
     g2.setStroke(new BasicStroke(1.5f)); 
     g2.drawOval(node.getPosition().x, node.getPosition().y, Style.SHAPE_SIZE, Style.SHAPE_SIZE); 

     //Draw token 
     g2.setColor(Style.DARK_GREY); 
     g2.setFont(new Font("Monospaced", Font.PLAIN, 12)); 
     String token = ((Place)node).getTokens().toString(); 
     g2.drawString(token, 
       (int) (node.getNodeCenterPosition().x - 3.5*token.length()), node.getNodeCenterPosition().y + CHAR_HEIGHT); 

     //Draw label 
     g2.drawString("P1", node.getPosition().x-8, node.getPosition().y-8); 

     // More code 
    } 

} 

不知道座標,它們都設置正確。怪異的行爲開始與這裏的drawString之最後:

//Draw label 
g2.drawString("P1", node.getPosition().x-8, node.getPosition().y-8); 

以前所有的代碼被渲染一次paintComponent被稱爲但是這一個。雖然如果我再次觸發paintComponent(從外部調用canvas.repaint())它會顯示出來。

這裏是帆布的第一重繪後的狀態:

No label

這裏是帆布的狀態的第二重繪後:

With label

補充說明:如果我將標籤放在光盤的右側,它會在第一次重繪時正常顯示:

g2.drawString("P1", node.getPosition().x+50, node.getPosition().y+30); 

Label on the right side

代碼的位置使得在行爲沒有區別。如果我註釋掉所有的代碼,但是標籤或者我把標籤繪製放在函數的頂部,它沒有任何區別。

那麼,我怎麼能讓這個標籤在我第一次打電話重繪時渲染?

編輯:這裏是這使得窗口中的代碼:

public class MainWindow extends JFrame { 

    private MainWindow() { 
     super(); 

     setVisible(true); 
     setResizable(false); 
     setSize(1280, 750); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLayout(new BorderLayout()); 

     this.setJMenuBar(MainMenu.getInstance());  
     add(Canvas.getInstance(), BorderLayout.CENTER);  
     add(ToolBar.getInstance(), BorderLayout.PAGE_START);   
     add(LeftPanel.getInstance(), BorderLayout.LINE_START); 
    } 

} 

和代碼在畫布構造器:

private Canvas() { 
    super(); 
    this.setFocusable(true); 
    this.setBackground(Style.BACKGROUND); 

    this.popupNewNode = new JPopupMenu(); 
    this.popupNewNode.setFocusable(false); 

    this.newPlace = new JMenuItem("New Place"); 
    this.newTransition = new JMenuItem("New Transition"); 

    this.popupNewNode.add(newPlace); 
    this.popupNewNode.add(newTransition); 
} 

畫布和其他一些成分是單身,但我想這不應該是一個問題,因爲只有一個窗口存在一個畫布上。

+1

告訴你如何把'Canvas'在父容器。 – alex2410

+1

使用'FontMetrics'確定文本的長度和高度 – MadProgrammer

+1

您是否有任何可以使[_Graphics上下文在第一個paint_上未對齊](http://stackoverflow.com/q/23507422/261156)? –

回答

0

這是很難知道沒有一個完全可運行的例子,但是,你不應該對文本的大小來做出假設,而是應該使用FontMetrics

FontMetrics fm = g.getFontMetrics(); 
int width = fm.stringWidth("P1"); 
int height = fm.getHeight(); 
g.drawString("P1", node.getPosition().x - width, (node.getPosition().y - height) + fm.getAscent()); 

Working with Text APIs細看更多細節。

另一個問題可能是,如果您以前翻譯Graphics語境,不必先複製或逆轉翻譯

+1

@mKorbel因爲沒有足夠的空間發表評論... – MadProgrammer