1

This is my current code:

package Calendar;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Clock extends JLabel {
    private String pattern;
    private Timer timer;

public Clock(String pattern){
    this.pattern = pattern;
    createTimer();
    timer.start();
}

public Clock(){
    pattern = "hh:mm:ss a";
    createTimer();
    timer.start();
}

private void createTimer(){
    timer = new Timer(0, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            setText(new SimpleDateFormat(pattern).format(new Date()));
        }
    });
}

public static void main(String[] args){
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel contentPane = new JPanel();
    frame.setContentPane(contentPane);
    Clock digitalClock = new Clock();
    contentPane.add(digitalClock);
    frame.setVisible(true);
}
}

and I cannot for the life of me figure out how to get this rotated. I looked on several other forums but there was no body else with this issue.

As far as I can tell there is no way to rotate either a JPanel or JFrame so am I out of luck?

This is what it looks like right now:

Digital Clock

And I would like to get it so the text is rotated 90 degrees. basically vertical.

EDIT: SOLUTION:

    package Calendar;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JLabel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.geom.*;

public class Clock extends JLabel {

    private String pattern;
    private Timer timer;

    public Clock ()
    {
        super();
        pattern = "hh:mm:ss a";
        createTimer();
        timer.start();
    }

    public Clock(String pattern)
    {
        super (pattern);
        this.pattern = pattern;
        createTimer();
        timer.start();
    }

    private void createTimer(){
        timer = new Timer(0, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                setText(new SimpleDateFormat(pattern).format(new Date()));
            }
        });
    }

    public void paint (Graphics g)
    {
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D) g;
            AffineTransform flipTrans = new AffineTransform();
            double widthD = (double) getWidth();
            flipTrans.setToRotation(-Math.PI / 2.0, getWidth() / 2.0, getHeight() / 2.0);
            g2.setTransform(flipTrans);
            super.paint(g);
        } else {
            super.paint(g);
        }
    }
}
Pure
  • 35
  • 5
  • Get what to rotate? You can rotate components [like this](http://stackoverflow.com/questions/14324460/rotating-a-jtextfield-vertically/14328881#14328881) or graphics [like this](http://stackoverflow.com/questions/15779877/rotate-bufferedimage-inside-jpanel/15780090#15780090) – MadProgrammer Apr 10 '14 at 00:07
  • This is just a simple digital clock that displays the time in a JFrame in a JPanel. Right now the text is horizontal and I would like to rotate it 90 degrees. – Pure Apr 10 '14 at 00:10
  • Have a look at http://stackoverflow.com/questions/8563037/how-to-rotate-swing-text - this is kind of a duplicate. – Dawood ibn Kareem Apr 10 '14 at 00:21
  • @DavidWallace Given the example code, I would say [that this](http://stackoverflow.com/questions/14324460/rotating-a-jtextfield-vertically/14328881#14328881) is more of a duplicate...just saying ;) – MadProgrammer Apr 10 '14 at 01:02
  • Sorry about this being a duplicate. Didn't realize this would be labeled as rotating swing text – Pure Apr 10 '14 at 01:14

1 Answers1

2

This is based on this example and makes use of JXLayer to physically rotate the label component the way you want it.

It also saves you from having to do any custom painting of your own.

I've used a similar technique to rotate JTabbedPane tabs so they run vertically down the side of the JTabbedPane

Clock

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.jxlayer.JXLayer;
import org.pbjar.jxlayer.demo.TransformUtils;
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;

public class RotateClock {

    public static void main(String[] args) {
        new RotateClock();
    }

    public RotateClock() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ExamplePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ExamplePane extends JPanel {

        private JSlider slider;
        private Clock clock;
        private DefaultTransformModel transformModel;

        public ExamplePane() {

            setLayout(new BorderLayout());

            slider = new JSlider(0, 360);
            slider.setValue(0);
            slider.setSnapToTicks(true);
            slider.setPaintTicks(true);
            slider.setMajorTickSpacing(10);
            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    transformModel.setRotation(Math.toRadians(slider.getValue()));

                }
            });

            clock = new Clock();

            transformModel = new DefaultTransformModel();
            transformModel.setRotation(Math.toRadians(0));
            transformModel.setScaleToPreferredSize(true);
            JXLayer<JComponent> rotatePane = TransformUtils.createTransformJXLayer(clock, transformModel);

            add(slider, BorderLayout.NORTH);
            add(rotatePane);

        }
    }

    public class Clock extends JLabel {

        private String pattern;
        private Timer timer;

        public Clock(String pattern) {
            this.pattern = pattern;
            setText(new SimpleDateFormat(pattern).format(new Date()));
            createTimer();
            timer.start();
        }

        public Clock() {
            this("hh:mm:ss a");
        }

        private void createTimer() {
            timer = new Timer(0, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    setText(new SimpleDateFormat(pattern).format(new Date()));
                }
            });
            timer.setInitialDelay(0);
        }
    }

}

This deals with, amongst other things, oddities with mouse events and the preferred size of the component.

Unfortunately, the code required to perform the transformation (Piet's examples) is no longer available on the net

I've put all the source code of JXLayer (version 3) and Piet's examples into a single zip and I would suggest, if you are interested, you grab a copy and store it some where safe.

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366