2015-04-28 4 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 
    } 

} 

Не обращайте внимания на координаты, все они настроены и правильны. Странное поведение начинается с последнего шнурком здесь:

//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

Положение кода не делает никакой разницы в поведении. Если я прокомментирую весь код, но ярлык, или я нарисую ярлык в верхней части функции, это не имеет никакого значения.

Итак, как я могу сделать эту метку визуализированной в первый раз, когда я переписываю?

EDIT: Вот код, который делает окно:

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 Context несогласованным при первой 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

Смежные вопросы