11

I wonder if it is possible to implement a GUI panel (possibly JPanel) that is of square shape but rotated 90 degrees. Obviously, there will be a top-level container which contains this panel, and visually the main panel is this rotated square panel within.

More specifically, I would divide a panel (called 'A') into 4 equal square sub-panels, and fill these sub-panels with JLabels, for which I am thinking to use GridLayout. And lastly, I would rotate 'A' 90 degrees to give what I want.

From my reading of other similar questions, it seems that you cannot rotate JPanel itself, but you can rotate what is contained within. Is this applicable to my case here? Would appreciate if someone could point out. Thanks.

skyork
  • 7,113
  • 18
  • 63
  • 103

4 Answers4

13

The critical thing seems to be painting the components after rotating the graphics context. Here's an example:

enter image description here

Addendum 1:As @Atreys comments, the rotated components are drawn, but interact poorly. If the components must remain usable, event coordinates should also be transformed. Compare this (considerably) more complex example that mirrors components.

Addendum 2: If you also need to transform the mouse coordinates, this example may be helpful.

Addendum 3: Alternatively, consider the drawString() examples examined here.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/questions/6333464 */
public class RotatePanel extends JPanel {

    public RotatePanel() {
        this.setPreferredSize(new Dimension(320, 240));
        this.add(new JLabel("Hello World!", JLabel.CENTER));
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        int w2 = getWidth() / 2;
        int h2 = getHeight() / 2;
        g2d.rotate(-Math.PI / 2, w2, h2);
        super.paintComponent(g);
    }

    private void display() {
        JFrame f = new JFrame("RotatePanel");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new RotatePanel().display();
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    neat trick :) I was curious how it handled objects you can click, so added a button to the label as well. It drew it rotated, but also non-rotated (sometimes). Also, the panel perceives any events registered to it in its non-rotated orientation – Atreys Jun 13 '11 at 17:58
  • @Atreys: Good point, although a solution is non-trivial. I've elaborated above. – trashgod Jun 13 '11 at 18:17
  • This is nice, but is this method general? For example, if I only rotate the 'A' panel for 45 degrees, would this make it appear as a diamond shape and everything within rotate 45 degrees as well (e.g. labels, sub-panels edges, etc)? thanks. – skyork Jun 14 '11 at 15:02
  • The rotation of the rendering is quite general, as seen [here](http://stackoverflow.com/questions/3405799/how-to-rotate-an-image-gradually-in-swing/3420651#3420651); but the components are no longer interactive. It's much like printing in landscape orientation, which is fine for labels. See also this [example](http://stackoverflow.com/questions/6238037/how-do-i-align-this-text-correctly/6238908#6238908). – trashgod Jun 14 '11 at 19:36
  • @trashgod Will this work proper when multiple components are in the panel? – Kanagavelu Sugumar May 04 '15 at 11:48
  • @KanagaveluSugumar: I've never tried; while illustrative, I would avoid this approach as a design strategy. – trashgod May 04 '15 at 17:32
  • Except now you need to translate the mouse events and the sizing hints as well ;) – MadProgrammer Apr 12 '17 at 22:51
  • 2
    @trashgod Or just use J(X)Layer, for [example](http://stackoverflow.com/questions/22976226/is-there-any-way-i-can-rotate-this-90-degrees/22976755#22976755) and [example](http://stackoverflow.com/questions/25252127/java-rotating-non-square-jpanel-component/25253453#25253453) ... but I'm lazy - pretty example though – MadProgrammer Apr 13 '17 at 00:21
3

Check out JXTransformer in the SwingHelper project over at java.net. This class acts as a component decorator that allows you to apply an arbitrary affine transform to a component.

jackrabbit
  • 5,525
  • 1
  • 27
  • 38
2

Yes, you would have to have the top-level container (JPanel or other container) be the item that rotates the contents. Really you aren't rotating the items, you are rotating to the painting of the items.

jzd
  • 23,473
  • 9
  • 54
  • 76
2

If all you need to do is rotate the text on a JLabel you could use a Rotated Icon, then you don't have to worry about rotating the panel.

camickr
  • 321,443
  • 19
  • 166
  • 288