Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AffineTransform seeming to ignore component bounds

I have the following:

public class ParametricEQView extends JPanel implements PluginView {
    private static final int BAND_WIDTH = 3;
    private static final int THROW_HEIGHT = 64;

    private static final int WIDTH = 128*BAND_WIDTH + 2*MARGIN;
    private static final int HEIGHT = 2*THROW_HEIGHT + 2*MARGIN;
    private static final int MID_HEIGHT = THROW_HEIGHT + MARGIN;

    private final ParametricEQ _peq;

    public ParametricEQView(ParametricEQ peq) {
        super();
        _peq = peq;

        SwingUtils.freezeSize(this, WIDTH, HEIGHT);
        setToolTipText("Parametric Equalizer");
    }

    @Override
    public void paint(Graphics g) {
        final Graphics2D g2d = (Graphics2D) g;
        final int max = findMax();

        g.setColor(BACKGROUND);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        g.setColor(DATA);
        final double scalingFactor = -((double) THROW_HEIGHT) / max;
        final double[] fineLevels = _peq.getFineLevels();
        int x = MARGIN;
        int h;
        final int[] xPoints = new int[128];
        final int[] yPoints = new int[128];
        for (int i = 0; i < 128; ++i) {
            h = (int) (fineLevels[i] * scalingFactor);
            xPoints[i] = x;
            yPoints[i] = MID_HEIGHT + h;
            x += BAND_WIDTH;
        }
        g.drawPolyline(xPoints, yPoints, 128);

        g.setColor(AXES);
        g.drawLine(MARGIN, MARGIN, MARGIN, HEIGHT-MARGIN);
        g.drawLine(MARGIN, MID_HEIGHT, WIDTH-MARGIN, MID_HEIGHT);

        g.setFont(AXIS_FONT);
        final FontMetrics metrics = g.getFontMetrics();
        int width = (int) metrics.getStringBounds(AXIS_LABEL_INPUT_MIDINUM, g).getWidth();
        g.drawString(AXIS_LABEL_INPUT_MIDINUM, WIDTH-MARGIN-width, HEIGHT-3);

        final AffineTransform atx = new AffineTransform();
        atx.setToRotation(-Math.PI/2, 0, HEIGHT);
        g2d.setTransform(atx);
        final String topLabel = "+" + max;
        width = (int) metrics.getStringBounds(topLabel, g).getWidth();
        g2d.drawString(topLabel, HEIGHT-MARGIN-width, HEIGHT+10);

        width = (int) metrics.getStringBounds(AXIS_LABEL_OUTPUT_VELOCITY, g).getWidth();
        g2d.drawString(AXIS_LABEL_OUTPUT_VELOCITY, MID_HEIGHT-(width/2), HEIGHT+10);

        g2d.drawString("-" + max, MARGIN, HEIGHT+10);
    }

    private int findMax() {
        int max = 3;
        for (int i = 0; i < 128; ++i)
            max = Math.max(max, (int) Math.ceil(Math.abs(_peq.getFineLevels()[i])));
        return max;
    }
}

This is what it looks like: With bounds at 0,0
The ParametricEQView is the component with the white background filling most of the window. In this image its coordinates are (0,0) in the containing frame and everything is great. However, if I resize the window so that the ParametricEQView moves over a bit (it has a fixed size and is set to be centered in its available space), the rotated text stays relative to the (0,0) of the frame instead of the component:

Starting to moveFully off the component


Everything else draws relative to the panel, it's just the rotated text that doesn't. What am I doing wrong?

like image 426
MattPutnam Avatar asked Dec 24 '13 15:12

MattPutnam


1 Answers

When you call g2d.setTransform(atx); you override the transform currently set in the Graphics object, i.e. the translation between the panel and its parent frame. That's why the text is drawn in the frame referential, and not in the panel referential.

The correct code would be to get the current transform and modify it or directly call Graphics2D.rotate(double).

like image 159
Guillaume Avatar answered Sep 22 '22 20:09

Guillaume