2014-10-14 2 views
0

Надеюсь, вы можете помочь мне в решении проблемы в моей drawString.drawString в BufferedImage исчезает

Я немного рисую в классе Factory и возвращаю BufferedImage с String на нем.

public class Factory { 

    public BufferedImage create() { 
     TempPanel tempPanel = new TempPanel(new Dimension(100, 100)); 
     return tempPanel.createImage(); 
    } 

    private class TempPanel extends JPanel { 

     public TempPanel(Dimension d) { 
      this.setVisible(true); 
      this.setSize(d); 
     } 

     public BufferedImage createImage() { 
      BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT); 
      this.paintComponent(bi.createGraphics()); 
      return bi; 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponents(g); 
      // General setup 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      // Transparent Background 
      g2.setComposite(AlphaComposite.Clear); 
      g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height); 
      g2.setComposite(AlphaComposite.Src); 

      // Different settings for a certain graphical object 
      g2.setFont(new Font("TimesRoman", Font.PLAIN, 12); 

      // Actual drawing 
      g2.drawString("Test", 0, 0); 
     } 
    } 
} 

А потом у меня тоже есть JPanel, в котором это изображение должно быть отрисованы:

public class Label extends JPanel { 
    // ... 
    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     Factory factory = new Factory(); 
     BufferedImage img = factory.create(); 
     g2.drawImage(img, 0, 0, null); 
    } 
} 

Проблема IST, что текст появляется только тогда, когда я минимизировать и восстановить окно, но как только я начните перемещать мышь внутри окна, текст снова исчезнет. Когда я вызываю drawRect() вместо drawString(), все работает нормально ?!

Может кто-нибудь сказать мне, почему?

Спасибо!

+1

1 Убедитесь, что вы избавляетесь от любого 'Graphics' контекст, который вы делаете. 2. Почему вы используете «JPanel» и метод 'paintComponent' для отображения содержимого на« BufferedImage »? «JPanel» может делать выбор, когда он должен или не должен рисовать, основываясь на том, что он не отображается? – MadProgrammer

+0

'' Test "' не имеет нисходящих; см. это возможное [дубликат] (http://stackoverflow.com/q/2658554/230513). – trashgod

ответ

1

Есть целый ряд вещей, которые «странно» меня ...

Во-первых, вы создаете новый Graphics контекст, но вы не складировать. Это может быть оставляя ресурсы открытым и может фактически предотвратить содержимое из оказаны на некоторых операционных системах ...

Так вместо того, чтобы ...

BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT); 
this.paintComponent(bi.createGraphics()); 

Вы должны делать что-то больше, как ...

BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT); 
Graphics2D g2d = bi.createGraphics(); 
this.paintComponent(g2d); 
g2d.dispose(); 

Во-вторых, текст не отображается так же, как и большинство других элементов, то есть он не начинается с x/y и визуализирует вправо/вправо, в большинстве случаев он начинается с x/y и визуализирует, слегка, вверх/вправо. Фактическая координата, основываясь на Font сек значение FontMetricsgetAscent ...

Таким образом, вместо ...

  g2.setFont(new Font("TimesRoman", Font.PLAIN, 12)); 
      // Actual drawing 
      g2.drawString("Test", 0, 0); 

Вы должны делать что-то больше, как ...

  g2.setFont(new Font("TimesRoman", Font.PLAIN, 12)); 
      FontMetrics fm = g2.getFontMetrics(); 
      // Actual drawing 
      g2.drawString("Test", 0, fm.getAscent()); 

См. Working with Text APIs или более подробную информацию ...

В-третьих, JComponent и, кроме того, все, что простирается от него , это ImageObsever, это важно, так как не все, что окрашено, готово для отображения сразу, иногда требуется дальнейшая обработка, вместо того, чтобы иметь дело с этим раздражением, вы можете делегировать ответственность, поэтому вместо ...

g2.drawImage(img, 0, 0, null); 

Вы должны делать что-то больше, как ...

g2.drawImage(img, 0, 0, this); 

Это позволяет компоненту слушать нижележащего изображения и реагировать на любые изменения, которые могут произойти с данными изображения и обновлять себя.

Forthly ...

private class TempPanel extends JPanel { 

    public TempPanel(Dimension d) { 
     this.setVisible(true); 
     this.setSize(d); 
    } 

    public BufferedImage createImage() { 
     BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT); 
     this.paintComponent(bi.createGraphics()); 
     return bi; 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponents(g); 
     // General setup 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     // Transparent Background 
     g2.setComposite(AlphaComposite.Clear); 
     g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height); 
     g2.setComposite(AlphaComposite.Src); 

     // Different settings for a certain graphical object 
     g2.setFont(new Font("TimesRoman", Font.PLAIN, 12); 

     // Actual drawing 
     g2.drawString("Test", 0, 0); 
    } 
} 

ли долбанные меня ...Компоненты Swing предназначены для прикрепления к родному сверстнику, на который они визуализируются, они также оптимизированы, чтобы не рисовать, когда они не отображаются, это может отбросить ваш рендеринг ...

Infact, вы можете достичь то же самое, используя что-то вроде ...

public static class Factory { 

    private static Renderer renderer; 

    public BufferedImage create() { 

     if (renderer == null) { 
      renderer = new Renderer(new Dimension(100, 100)); 
     } 

     return renderer.createImage(); 
    } 

    private class Renderer { 

     private Dimension size; 

     public Renderer(Dimension size) { 
      this.size = size; 
     } 

     public BufferedImage createImage() { 
      BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TRANSLUCENT); 
      Graphics2D g2 = bi.createGraphics(); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      // Transparent Background 
      g2.setComposite(AlphaComposite.Clear); 
      g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height); 
      g2.setComposite(AlphaComposite.Src); 
      // Different settings for a certain graphical object 
      g2.setFont(new Font("TimesRoman", Font.PLAIN, 12)); 
      FontMetrics fm = g2.getFontMetrics(); 

      // Actual drawing 
      g2.drawString("Test", 0, fm.getAscent()); 
      g2.dispose(); 
      return bi; 
     } 

    } 
} 

что бы развестись фактическую картину от всего остального, и предоставить вам контроль над ним ...

+0

+1 для перевода 'getAscent()'. – trashgod

+0

@trashgod Да, как я не потратил несколько часов, пытаясь понять это, когда я только начал: P – MadProgrammer

+0

Спасибо за помощь. Я применил ваши предложения, но это не исправило мою проблему:/ – user2948795

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