2

何が間違っているのかわかりません...

カスタム フォント、カスタム カラー (グラデーション背景を含む) などを含む文字列を表示する 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);
      }
    });
  }
}

これが私が見ているものです: グラフィックのバグ: テキストのエコー Windows 7でテスト済み、Java 5、6、7で見られます。

4

1 に答える 1

3

layout.draw左上隅にテキストを描画し、 を使用して再度描画するようですg2d.drawString。を削除して、代わりg2d.drawStringに適切な位置を直接渡すことができlayout.drawます。

layout.draw(g2d, posX, posY);

(または、削除layoutしてのみ使用するg2d.drawString; 同様に機能するようです。)

于 2012-10-29T16:44:15.930 に答える