How to output a String on multiple lines using Graphics

后端 未结 5 2005
清酒与你
清酒与你 2020-12-28 09:39

My Program overrides public void paint(Graphics g, int x, int y); in order to draw some stings using g.drawString(someString, x+10, y+30);

5条回答
  •  攒了一身酷
    2020-12-28 10:07

    Thanks to Epaga's hint and a couple of examples on the Net (not so obvious to find! I used mainly Break a Line for text layout), I could make a component to display wrapped text. It is incomplete, but at least it shows the intended effect.

    class TextContainer extends JPanel
    {
        private int m_width;
        private int m_height;
        private String m_text;
        private AttributedCharacterIterator m_iterator;
        private int m_start;
        private int m_end;
    
        public TextContainer(String text, int width, int height)
        {
            m_text = text;
            m_width = width;
            m_height = height;
    
            AttributedString styledText = new AttributedString(text);
            m_iterator = styledText.getIterator();
            m_start = m_iterator.getBeginIndex();
            m_end = m_iterator.getEndIndex();
        }
    
        public String getText()
        {
            return m_text;
        }
    
        public Dimension getPreferredSize()
        {
            return new Dimension(m_width, m_height);
        }
    
        public void paint(Graphics g)
        {
            super.paintComponent(g);
    
            Graphics2D g2 = (Graphics2D) g;
            FontRenderContext frc = g2.getFontRenderContext();
    
            LineBreakMeasurer measurer = new LineBreakMeasurer(m_iterator, frc);
            measurer.setPosition(m_start);
    
            float x = 0, y = 0;
            while (measurer.getPosition() < m_end)
            {
                TextLayout layout = measurer.nextLayout(m_width);
    
                y += layout.getAscent();
                float dx = layout.isLeftToRight() ?
                        0 : m_width - layout.getAdvance();
    
                layout.draw(g2, x + dx, y);
                y += layout.getDescent() + layout.getLeading();
            }
        }
    }
    

    Just for fun, I made it fitting a circle (alas, no justification, it seems):

    public void paint(Graphics g)
    {
        super.paintComponent(g);
    
        Graphics2D g2 = (Graphics2D) g;
        FontRenderContext frc = g2.getFontRenderContext();
    
        LineBreakMeasurer measurer = new LineBreakMeasurer(m_iterator, frc);
        measurer.setPosition(m_start);
    
        float y = 0;
        while (measurer.getPosition() < m_end)
        {
            double ix = Math.sqrt((m_width / 2 - y) * y);
            float x = m_width / 2.0F - (float) ix;
            int width = (int) ix * 2;
    
            TextLayout layout = measurer.nextLayout(width);
    
            y += layout.getAscent();
            float dx = layout.isLeftToRight() ?
                    0 : width - layout.getAdvance();
    
            layout.draw(g2, x + dx, y);
            y += layout.getDescent() + layout.getLeading();
        }
    }
    

    I am not too sure about dx computation, though.

提交回复
热议问题