这基于 this example,并使用 JXLayer以您希望的方式物理旋转标签组件.
它还可以让您免于自己进行任何自定义绘画.
我使用了类似的技术来旋转JTabbedPane选项卡,使它们垂直向下运行JTabbedPane
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 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);
}
}
}
除其他事项外,这涉及鼠标事件的奇怪性和组件的首选大小.
不幸的是,网络上不再提供执行转换所需的代码(Piet的示例)
我已将JXLayer(版本3)和Piet的示例的所有源代码放入单个zip中,我建议,如果您有兴趣,可以抓取副本并将其存储在安全的地方.