0

In java awt or swing when you want to change painting of some component you usually have to override the method paint(Graphics g) (in awt) or paintComponent(Graphics g) (in swing).
This is usually (maybe allways - I'm not sure) done when you are creating the component for example:

JPanel jPanel = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {

                    super.paintComponent(g);

                    Graphics2D g2d = (Graphics2D) g;
                    //... my implementation of paint, some transfromations, rotation, etc
                }   

            }; 

Imagine that you have container of components which could for example consists of some JLabels, some JTextFields, some image. Which will be all put on one component. By container I mean you have some list or map with ids or some similar structure in which are all components you will put on one JFrame.
The question is if I can change the painting method after creating with all of the components which are in this list in the moment when all of them are already created. For example I want do the rotation action (rotate), which is defined in Graphisc2D, with all of them.
So basicaly what I want is that I throught the list of componets I have and say: "All of you (components) which are in the list will be rotated by some angle". Is that possible? If yes how?

Edit:
This is my not correctly working solution:

  graphicalDisplayPanel = new JPanel() {
                    @Override
                    protected void paintComponent(Graphics g) {

                        super.paintComponent(g);


                        g2d = (Graphics2D) g;
                        g2d.rotate(Math.PI, anchorx, anchory);


                    }

                 @Override
                      public void paintChildren(Graphics g) {
                           super.paintChildren(g);
                           Graphics2D g2d2 = (Graphics2D) g;

                        g2d2.rotate(Math.PI, anchorx, anchory);

                      }

                };

    JFrame jFrame = JFrame();
    // ... setting dimension, position, visible etc for JFrame, it works correctly nonrotated

    jFrame.setContentPane(graphicalDisplayPanel);
user1097772
  • 3,499
  • 15
  • 59
  • 95
  • Trivially, yes, but see this [answer](http://stackoverflow.com/a/6333584/230513). – trashgod Dec 09 '15 at 15:29
  • @trashgod Thanks but a) if you read my question, I asked if its possible AFTER creation, but your example do it durring creation. b) why dont you call super.paintComponent(g); before the changes of g2d?? c) I did exactly this before but the problem is that it rotate it at the start, but if you change value of some component - for example the text which is displayed on it. It renders again non rotated over it ... – user1097772 Dec 09 '15 at 16:03
  • @trashgod please see edit of my question and my previous comment, you can see solution which is similar to yours and which I did before asking this question. But it has problems I mentioned. – user1097772 Dec 09 '15 at 16:15
  • Exactly; you can `rotate()` the graphics context to re-orient _pixels_, but AWT & Swing _components_ were designed to be used upright. – trashgod Dec 09 '15 at 16:36
  • For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Dec 10 '15 at 05:15

2 Answers2

0

I have not tested this, but it seems like it would work. A JComponent's paint() method calls:

paintComponent(co);
paintBorder(co);
paintChildren(co);

where co is a Graphics object. In theory you create an image, retrieve the graphics object and then pass that into paintChildren(). you will have to call paintComponent() and paintBorder() yourself, if you do this. Then, just rotate the image and draw it into your component. You may have to crop the image or resize your component accordingly for this to work. It might look something like this:

BufferedImage myImage;

@Override
public void paint(Graphics g){
    myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
    //using a transparent BufferedImage might not be efficient in your case
    Graphics myGraphics = myImage.getGraphics();
    super.paintComponent(g);
    super.paintBorder(g);
    super.paintChildren(myGraphics);
    //rotation code here
    //  ...
    //draw children onto your component
    g.drawImage(myImage, 0, 0,getWidth(), getHeight(), null);

}

I hope I didn't make any mistakes, please let me know if this works.

nemo
  • 153
  • 1
  • 10
  • What is is the sense of the image? I want create components around center of contentPane where they are placed, why should I use some image? – user1097772 Dec 11 '15 at 16:21
  • your question is a bit confusing. When you said you want to 'For example I want do the rotation action (rotate), which is defined in Graphisc2D, with all of them.', I thought you wanted to rotate all the objects inside your `contentPane`. [Edit] the reason for the image is so that you can rotate it. – nemo Dec 13 '15 at 12:40
  • Yes sure, you're right. But I probably just don't really get the part with the Image or I can't see it from the code, athought it could maybe there. I would make sense if I place all the components which I usually place on the contentPane onto your image and the image afterwards on the contentPane.To correctly understand the rotation - the center of rotation of all components is the center of content pane. Like if you take monitor and manualy rotate him. – user1097772 Dec 14 '15 at 08:32
  • I'm using an image so that I can get a graphics object that I can work with, like a buffer. You can also optimize your program with it, as you will only need to redraw the image every time something changes, and not every time a redraw happens. – nemo Dec 15 '15 at 18:27
  • Sry, I still don't get the the point what you want to do with image. You use it to get mygraphics which you use for paintChildren which I think should actually be just supper.paintChildren(g), then there is comment which should represent the rotation it would be just this 2 rows: g2d = (Graphics2D) g; g2d.rotate(Math.PI, anchorx, anchory); plus computing the center points anchorx, anchory, which is easy(widht/2.0, height/2.0) And at the end you draw image, but there is nothing on it, its empty image you only created instance do nothing with it. – user1097772 Dec 16 '15 at 09:03
  • OK, the way i saw it, you wanted to rotate the children of your object, and not the object itself. This way, you rotate the image containing your component's children and then you draw it on the screen. – nemo Dec 19 '15 at 11:24
0

So basicaly what I want is that I throught the list of componets I have and say: "All of you (components) which are in the list will be rotated by some angle".

If you want to rotate panel and therefore all the components on the panel as a single using then you need to do the custom painting in the paintComponent() method.

If you want to rotate, for example, individual images that each have a different angle of rotation then you can again do this in the paintComponent(...) method and change the angle for each component.

Or, in this second case you can use the Rotated Icon class. In this case the Icon is just added to a JLabel. Then you can change the degrees of rotation and repaint the label, so there is no custom painting (except in the Icon itself).

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Since nobody answer the question but the things which are only background information I made bold what is really the question. If i understand this correctly paint component is method which you have to override before creating the instnace . But because of complicated creating mechanism of all components in existing application I asked if this can be accomplished somehow else when you already have List where all the components are already created and you want to change their rotation. – user1097772 Dec 11 '15 at 08:25
  • Note: I think its not possible to override method of already existing object, so I can't do it in paint component this way. – user1097772 Dec 11 '15 at 08:26
  • 1
    @user1097772, the question has been answer. NO you can't rotate components after they have been added to a GUI unless you override a painting method. Or unless you want to create a "wrapper panel" panel so that you remove the existing panel from the GUI and this panel to your wrapper panel and then add the wrapper panel to the GUI. Again, this means you need to do custom painting in your wrapper panel. So you can't just take an existing GUI and rotate the components. – camickr Dec 11 '15 at 16:13
  • Well what about that wrapper panel? I could be solution, but it will not solve the paining of the components on the panel? I tryied it before, I also managed to rotate it even the components, but when the components were updated they repainted over it non rotated. So what should be in left top corner from my point of view was in right down corner "upside down". Because rotation of JPanel, which i set to conent pane somehow didn't affect the repaint after update components. Which i don't understand why. – user1097772 Dec 11 '15 at 16:28
  • @user1097772 We are going in circles. Post a [SSCCE](http://sscce.org/) that demonstrates what you are attempting to do. Frankly your requirement doesn't make any sense to me. Even if you rotate components they will not work since you won't be able to type into text fields or interact with any comonents using the mouse because the events will be generated for the wrong point. – camickr Dec 11 '15 at 16:32
  • I tryied, but when I do it everyone explain it in his way. The application is customer display of device. Application has 2 displays. One non rotated, where are events which can cause update of this display. The task is have it on one monitor not on two. Call first non rotated frame A and the one which should be rotated B. On your monitor will be on left half non rotated A and on the right rotated B. On B there are no actions which could make problems - it only for visualization of what is done in A. There are pictures, JLabels, other comp. only make layout for this components. – user1097772 Dec 11 '15 at 16:53
  • @user1097772, `it only for visualization of what is done in A` - then all I can suggest is to create an image of A and then add then use the `RotatedIcon` suggested earlier to rotate the entire image and add the icon to a label and add the label to the frame. Whenever something is A changes you would need to recreate the image. – camickr Dec 11 '15 at 17:29
  • So I would actually need to create image of B and rotate it like you suggested, because A and B visualize same data but differently (on B there are no buttons,etc.). So can I put whole contentPane off B on that icon? (How?). If yes i would have to recreate the image everytime when contentPane of B should change. – user1097772 Dec 14 '15 at 09:19