Java Swing的drawString显示了一个echo

时间:2012-10-29 16:28:58

标签: java swing graphics2d drawstring

我不确定我做错了什么......

我想让一个JComponent显示一个包含自定义字体,自定义颜色(包括渐变背景)等的字符串。它工作正常,但我在组件的左上角看到了字符串的底部。下面的代码简化了很多组件,以便集中精力解决问题...

InfoPanel.java

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.Rectangle2D;

import javax.swing.*;

/**
 * Panel showing information.
 */
@SuppressWarnings("serial")
class InfoPanel extends JComponent
{
  private String m_information;
  private Font m_font;
  private Color m_colorForeground;
  private Color m_colorBackground;

  protected float heightFactor;
  protected int m_alignment = SwingConstants.CENTER;

  InfoPanel(String info, Font font, Color colorFore, Color colorBackground)
  {
    m_information = info;
    m_font = font;
    m_colorForeground = colorFore;

    if (colorFore == null)
    {
      m_colorForeground = Color.BLACK;
    }
    if (colorBackground == null)
    {
      m_colorBackground = Color.GRAY;
    }
    else
    {
      m_colorBackground = colorBackground;
    }
    setOpaque(true);
  }

  @Override
  protected void paintComponent(Graphics g)
  {
    final Graphics2D g2d = (Graphics2D) g.create();
    g2d.setFont(m_font);

    g2d.setColor(m_colorBackground);
    Dimension d = getSize();
    g2d.fillRect(0, 0, d.width, d.height);
    g2d.setColor(m_colorForeground);

    // Get the text bounds
    FontRenderContext fontContext = g2d.getFontRenderContext();
    TextLayout layout = new TextLayout(m_information, m_font, fontContext);
    layout.draw(g2d, 0, 0);
    Rectangle2D bounds = layout.getBounds();

    int posX = 10;
    int width = (int) bounds.getWidth();
    int height = (int) bounds.getHeight();
    if (m_alignment == SwingConstants.CENTER)
    {
      posX = (d.width - width) / 2;
    }
    else if (m_alignment == SwingConstants.RIGHT)
    {
      posX = d.width - width - posX;
    }
    // Center vertically
    FontMetrics fm = g2d.getFontMetrics();
    int posY = d.height / 2 + height / 2 - fm.getDescent();

    g2d.drawString(m_information, posX, posY);
    // Only drawString shows this problem!
    g2d.drawLine( posX, posY + 5, posX + width, posY + 5 );

    g2d.dispose();
  }
}

TestInfoPanel.java

import java.awt.*;

import javax.swing.*;

public class TestInfoPanel
{
  private JPanel m_panel;

  TestInfoPanel()
  {
  }

  private JScrollPane getContent()
  {
    m_panel = new JPanel(new GridLayout(0, 1));
    m_panel.add(new InfoPanel("A Title jqpgy_@,;!§",
        new Font("Arial", Font.PLAIN, 24),
        Color.RED, Color.LIGHT_GRAY));
    m_panel.add(new InfoPanel("A Sub-Title jqpgy_@,;!§",
        new Font("Tahoma", Font.PLAIN, 18),
        Color.BLUE, Color.YELLOW));
    m_panel.add(new JPanel());
    return new JScrollPane(m_panel);
  }

  public static void main(String[] args)
  {
    final TestInfoPanel tm = new TestInfoPanel();
    SwingUtilities.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle(tm.getClass().getName());
        f.setContentPane(tm.getContent());
        f.setSize(800, 400);
        f.setLocation(200, 200);
        f.setVisible(true);
      }
    });
  }
}

这是我看到的: Graphics Bug: echo of text 在Windows 7上进行了测试,见于Java 5,6,7。

1 个答案:

答案 0 :(得分:3)

似乎layout.draw在左上角绘制文字,然后使用g2d.drawString再次绘制文字。您可以删除g2d.drawString并将正确的位置直接传递给layout.draw

layout.draw(g2d, posX, posY);

(或删除layout并仅使用g2d.drawString;似乎也可以使用。)