1

I'm trying to display 100 strings with the given JTextField once I press the draw button, and then be able to rotate them all 90 degrees when I press the rotate button. However, when I rotate, some of the strings from earlier still appear. But then the whole panel clears once the strings are pointing downward. Why is this?

import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class RotateAndDraw extends JFrame implements ActionListener{
    // Declare all member variables
    private JFrame window;
    private JButton drawButton;
    private JButton rotateButton;
    JTextField userInput = new JTextField("Enter text here");
    private static JPanel p3 = new JPanel(); // Drawing surface
    private static Graphics g = p3.getGraphics(); // Graphics context

    private static int[] xArray = new int[100];
    private static int[] yArray = new int[100];
    private static int[] fontArray = new int[100];
    private static float[] colorArray = new float[100];

    private static int rotateCount = 0;
    private static int theta;
    public RotateAndDraw(){
        // Declare all components
        window = new JFrame("Rotate and Draw");
        drawButton = new JButton("Draw");
        rotateButton = new JButton("Rotate");
        drawButton.addActionListener(this);
        rotateButton.addActionListener(this);
        JPanel drawingSurface = new JPanel();
        JLabel userInputLabel = new JLabel("Text:         ");

        // Create some containers
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(3, 1));

        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 2));
        p1.add(drawButton);
        p1.add(rotateButton);

        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(1, 3));
        userInputLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        p2.add(userInputLabel);
        p2.add(userInput);
        JLabel nullLabel = new JLabel("");
        p2.add(nullLabel);

        p3.setBackground(Color.BLACK);

        content.add(p1);
        content.add(p2);
        content.add(p3);

        window.add(content);
    }

    public void run(){
        window.setLocation(100, 100);
        window.setSize(10000, 10000);
        window.setDefaultCloseOperation(EXIT_ON_CLOSE);
        window.setVisible(true);
    }

    private void paintComponent(Graphics g){
        // TODO Auto-generated method stub
        super.paintComponents(g);

   }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        super.paintComponents(g);
        Graphics2D g2 = ( Graphics2D )g;

        String message = userInput.getText();

        Font font1, font2, font3, font4, font5;  // The five fonts.
        font1 = new Font("Serif", Font.BOLD, 14);
        font2 = new Font("SansSerif", Font.BOLD + Font.ITALIC, 24);
        font3 = new Font("Monospaced", Font.PLAIN, 30);
        font4 = new Font("Dialog", Font.PLAIN, 36);
        font5 = new Font("Serif", Font.ITALIC, 48);

        if(e.getSource() == drawButton){
            g = p3.getGraphics();
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, p3.getWidth(), p3.getHeight());

            rotateCount = 0;

            int width = p3.getWidth();
            int height = p3.getHeight();

            for (int i = 0; i < 100; i++) {
                int fontNum = (int)(5*Math.random()) + 1;
                fontArray[i] = fontNum;
                switch (fontNum) {
                case 1:
                    g.setFont(font1);
                    break;
                case 2:
                    g.setFont(font2);
                    break;
                case 3:
                    g.setFont(font3);
                    break;
                case 4:
                    g.setFont(font4);
                    break;
                case 5:
                    g.setFont(font5);
                    break;
                } // end switch


                float hue = (float)Math.random();
                colorArray[i] = hue;
                g.setColor( Color.getHSBColor(hue, 1.0F, 1.0F) );


                int x,y;
                x = (int)(Math.random()*(width));
                y = (int)(Math.random()*(height));
                xArray[i] = x;
                yArray[i] = y;

                // Draw the message.
                g.drawString(message,x,y);
            } // end for
        }// end if
        if(e.getSource() == rotateButton){
            super.paintComponents(g2);
            g2.setColor(Color.BLACK);
            g2.fillRect(0, 0, p3.getWidth(), p3.getHeight());

            rotateCount++;
            if(rotateCount == 4){
                rotateCount = 0;
            }

            switch(rotateCount){
            case 0:
                theta = 0;
                break;
            case 1:
                theta = 90;
                break;
            case 2:
                theta = 180;
                break;
            case 3:
                theta = 270;
                break;
            }

            for(int i = 0; i < 100; i++){
                switch(fontArray[i]){
                case 1:
                    g2.setFont(font1);
                    break;
                case 2:
                    g2.setFont(font2);
                    break;
                case 3:
                    g2.setFont(font3);
                    break;
                case 4:
                    g2.setFont(font4);
                    break;
                case 5:
                    g2.setFont(font5);
                    break;
                } // end switch 

            g2.setColor( Color.getHSBColor(colorArray[i], 1.0F, 1.0F) );

            AffineTransform at = new AffineTransform(); 
            at.rotate(Math.toRadians(theta), xArray[i], yArray[i]);
            g2.setTransform(at); 
            g2.drawString(message, xArray[i], yArray[i]);
            g2.transform(new AffineTransform());
            }// end for
        }
    }
}
E. Kaufman
  • 129
  • 2
  • 11

1 Answers1

0

Well it's been harder than I expected but I think I got it to work :-)

The first problem was you were performing graphical operations (drawing and transforming) in actionPerformed. You must do those things in paintComponent because that is the method that is executed automatically by the graphic environment whenever it needs to paint the component.

Then I had to mess around with transformations a little bit. I think the problem was you were calling g2.setTransform(at) to apply a new coordinate transform. I read on the docs you shouldn't: "setTransform method is intended only for restoring the original Graphics2D transform after rendering"

Here is what i came out with. Hope it helps.

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

class Tag {

    private int     x;
    private int     y;
    private int     font;
    private float   color;
    private String  message;

    public Tag(String message, int x, int y, int font, float color) {
        this.message = message;
        this.x = x;
        this.y = y;
        this.font = font;
        this.color = color;
    }

    public String getMessage() {
        return message;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getFont() {
        return font;
    }

    public float getColor() {
        return color;
    }
}

class Board extends JPanel {

    private Font[]  font    = new Font[5];
    private Tag[]   tags;
    private int     theta;

    public Board() {
        font[0] = new Font("Serif", Font.BOLD, 14);
        font[1] = new Font("SansSerif", Font.BOLD + Font.ITALIC, 24);
        font[2] = new Font("Monospaced", Font.PLAIN, 30);
        font[3] = new Font("Dialog", Font.PLAIN, 36);
        font[4] = new Font("Serif", Font.ITALIC, 48);
    }

    public void setTags(Tag[] tags) {
        this.tags = tags;
    }

    public void updateBoard(int theta) {
        this.theta = theta;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLACK);
        g2.fillRect(0, 0, getWidth(), getHeight());
        if (tags != null) {
            AffineTransform at = new AffineTransform();
            for (Tag tag : tags) {
                g2.setFont(font[tag.getFont()]);

                g2.setColor(Color.getHSBColor(tag.getColor(), 1.0F, 1.0F));

                at = new AffineTransform();
                at.translate(tag.getX(), tag.getY());
                g2.transform(at);

                at = new AffineTransform();
                at.rotate(Math.toRadians(theta));
                g2.transform(at);

                g2.drawString(tag.getMessage(), 0, 0);

                at = new AffineTransform();
                at.rotate(-Math.toRadians(theta));
                g2.transform(at);

                at = new AffineTransform();
                at.translate(-tag.getX(), -tag.getY());
                g2.transform(at);
            }// end for
        }
    }

}

public class RotateAndDraw extends JFrame implements ActionListener {

    // Declare all member variables
    private JFrame  window;
    private JButton drawButton;
    private JButton rotateButton;
    JTextField      userInput   = new JTextField("Enter text here");
    private Board   board       = new Board();  // Drawing surface

    private int     rotateCount = 0;

    public RotateAndDraw() {
        // Declare all components
        window = new JFrame("Rotate and Draw");
        drawButton = new JButton("Draw");
        rotateButton = new JButton("Rotate");
        drawButton.addActionListener(this);
        rotateButton.addActionListener(this);
        JLabel userInputLabel = new JLabel("Text:         ");

        // Create some containers
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(3, 1));

        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 2));
        p1.add(drawButton);
        p1.add(rotateButton);

        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(1, 3));
        userInputLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        p2.add(userInputLabel);
        p2.add(userInput);
        JLabel nullLabel = new JLabel("");
        p2.add(nullLabel);

        board.setBackground(Color.BLACK);

        content.add(p1);
        content.add(p2);
        content.add(board);

        window.add(content);
    }

    public void run() {
        window.setLocation(100, 100);
        window.setSize(400, 400);
        window.setDefaultCloseOperation(EXIT_ON_CLOSE);
        window.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String message = userInput.getText();

        if (e.getSource() == drawButton) {
            rotateCount = 0;
            int width = board.getWidth();
            int height = board.getHeight();

            Tag[] tags = new Tag[100];

            for (int i = 0; i < tags.length; i++) {
                int fontNum = (int) (5 * Math.random());
                float hue = (float) Math.random();
                int x = (int) (Math.random() * width);
                int y = (int) (Math.random() * height);

                tags[i] = new Tag(message, x, y, fontNum, hue);
            } // end for
            board.setTags(tags);
        }// end if
        if (e.getSource() == rotateButton) {
            rotateCount = (rotateCount + 1) % 4;
        }
        board.updateBoard(90 * rotateCount);
        board.repaint();
    }

    public static void main(String[] args) {
        RotateAndDraw rad = new RotateAndDraw();
        rad.run();
    }

}
Dario
  • 548
  • 1
  • 7
  • 14