可以通过Java 2D API中的绘制管道技术来实现。
下面是一个例子:
//file: Iguana.java
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;public class Iguana extends JComponent {
  private Image image;
  private int theta;  public Iguana(  ) {
    theta = 0;
    addMouseListener(new MouseAdapter(  ) {
      public void mousePressed(MouseEvent me) {
        theta = (theta + 15) % 360;
        repaint(  );
      }
    });
  }  public void paint(Graphics g) {
    //theta = (theta + 15) % 360;
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
    int cx = getSize(  ).width / 2;
    int cy = getSize(  ).height / 2;
    g2.translate(cx, cy);
    g2.rotate(theta * Math.PI / 180);
    Shape oldClip = g2.getClip(  );
    g2.setClip(oldClip);
    g2.setFont(new Font("Times New Roman", Font.PLAIN, 64));
    g2.setPaint(new GradientPaint(-cx, 0, Color.red,
        cx, 0, Color.black, false));
    g2.drawString("Hello, 2D!", -cx * 3 / 4, cy / 4);
   }
  public static void main(String[] args) {
    JFrame f = new JFrame("Iguana");
    Container c = f.getContentPane(  );
    c.setLayout(new BorderLayout(  ));
    c.add(new Iguana(  ), BorderLayout.CENTER);
    f.setSize(300, 300);
    f.setLocation(100, 100);
    f.addWindowListener(new WindowAdapter(  ) {
      public void windowClosing(WindowEvent e) { System.exit(0); }
    });
    f.setVisible(true);
  }
}
当你在窗体上点鼠标时,Hello, 2D!将会在窗体内旋转;若想去掉鼠标事件,则去掉addMouseListener(new MouseAdapter(  ) {
      public void mousePressed(MouseEvent me) {
        theta = (theta + 15) % 360;
        repaint(  );
      }
    });
着一段程序,在public void paint(Graphics g)的第一句加上自己设置的倾斜角度,即可实现,这里的程序把theta = (theta + 15) % 360;注释掉了。

解决方案 »

  1.   

    Graphics2D g2 = (Graphics2D)g;
            g2.rotate(0.4);
            g2.drawString("AAAAAAAA", 100,100);
    一试便知!
      

  2.   

    多谢两位老兄,我已经试出了字符的旋转了.就用g2.rotate(theta*Math.PI/180);但我发现一个问题啊,字符的旋转不是以那个写字符时的坐标点为原点的旋转的啊:
    如:
    Graphics2D g2d = (Graphics2D)g;
    g2d.drawString("aaaaaaaaaaa",300,150);
    g2d.rotate(30*Math.PI/180);
    g2d.drawString("aaaaaaaaaaa",300,150);

    g2d.rotate(60*Math.PI/180);
    g2d.drawString("aaaaaaaaaaa",300,150);

    g2d.rotate(90*Math.PI/180);
    g2d.drawString("aaaaaaaaaaa",300,150);我上面一串代码后,写的字:aaaaaaaaaaaa根本不在一个位置了,有的在屏幕上已经看不到了啊?这该如何解决啊?
      

  3.   

    使用g2d.translate(cx, cy),把写字符时的坐标点x和y传给cx和cy!
      

  4.   

    还是不行,那几个aaaaaaa还是跑得满屏幕都是的.由文档看那个方法好象是将cx,cy当成系统的坐标原点吧,我在用了g2d.translate(cx, cy)后,再用g2d.drawString("aaaaaaaaa",0,0);也是一样,那几个aaaaaaaaaa不在一起
      

  5.   

    g2.translate(cx, cy)是将坐标原点平移到点(cx,cy),用来转换用户空间的,关键是你还没有得到aaaaaaa字符串的精确的起始坐标点,试试用Font类的相关函数来设置有关参数!
    下面我对我第一次提到的例子改进如下,可以实现你的要求:
    //file: Iguana.java
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.font.*;
    import javax.swing.*;public class Iguana extends JComponent {
      private Image image;
      private int theta;
      private float x,y;  public Iguana(  ) {
        theta = 0;
        addMouseListener(new MouseAdapter(  ) {
          public void mousePressed(MouseEvent me) {
            theta = (theta + 15) % 360;
            repaint(  );
          }
        });
      }  public void paint(Graphics g) {
        //theta = (theta + 15) % 360;
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
            int width = getSize(  ).width;
            int height = getSize(  ).height;
            Font font = new Font("Times New Roman", Font.PLAIN, 20);
            g2.setFont(font);
            g2.setFont(new Font("Times New Roman", Font.PLAIN, 20));
            FontRenderContext frc = g2.getFontRenderContext(  );
            LineMetrics metrics = font.getLineMetrics("Hello, 2D!", frc);
            float messageWidth =
             (float)font.getStringBounds("Hello, 2D!", frc).getWidth(  );
            float ascent = metrics.getAscent(  );
            float descent = metrics.getDescent(  );
            float cx = (width - messageWidth) / 2;
            float cy = (height + metrics.getHeight(  )) / 2 - descent;
            g2.setPaint(getBackground(  ));
            g2.fillRect(0, 0, width, height);
            g2.translate(100,100);
            g2.rotate(theta * Math.PI / 180);
            Shape oldClip = g2.getClip(  );
            g2.setClip(oldClip);
            g2.setPaint(new GradientPaint(-cx, 0, Color.red,cx, 0, Color.black, false));
            g2.drawString("Hello, 2D!", 0,0);
       }
      public static void main(String[] args) {
        JFrame f = new JFrame("Iguana");
        Container c = f.getContentPane(  );
        c.setLayout(new BorderLayout(  ));
        c.add(new Iguana(  ), BorderLayout.CENTER);
        f.setSize(300, 300);
        f.setLocation(100, 100);
        f.addWindowListener(new WindowAdapter(  ) {
          public void windowClosing(WindowEvent e) { System.exit(0); }
        });
        f.setVisible(true);
      }
    }
      

  6.   

    其实以上代码中的很多都可以不要,精简后的代码为:
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.font.*;
    import javax.swing.*;public class RotateText extends JComponent {
      private Image image;
      private int theta;
      private float x,y;
      public RotateText( ) {
        theta = 0;
        addMouseListener(new MouseAdapter(  ) {
          public void mousePressed(MouseEvent me) {
            theta = (theta + 15) % 360;
            repaint(  );
          }
        });
      }
      public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
            int width = getSize().width;
            int height = getSize().height;
            Font font = new Font("Times New Roman", Font.PLAIN, 20);
            g2.setFont(font);
            float cx = width/2;
            g2.setPaint(getBackground());
            g2.fillRect(0, 0, width, height);
            g2.translate(100,100);
            g2.rotate(theta * Math.PI / 180);
            Shape oldClip = g2.getClip();
            g2.setClip(oldClip);
            g2.setPaint(new GradientPaint(-cx, 0, Color.red,cx, 0, Color.black, false));
            g2.drawString("Hello, 2D!", 0,0);
       }
      public static void main(String[] args) {
        JFrame f = new JFrame("RotateText");
        Container c = f.getContentPane();
        c.setLayout(new BorderLayout());
        c.add(new RotateText(), BorderLayout.CENTER);
        f.setSize(300, 300);
        f.setLocation(100, 100);
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) { System.exit(0); }
        });
        f.setVisible(true);
      }
    }
      

  7.   

    非常感谢OExpress(浪子猫) ,仔细看了你给的代码后,写了很多的测试代码.很抱歉,我发现我昨天测试的代码是我自己弄错了,今天我试了很多次,原来其实并不需要用到Font包里面的那些类,它本身就可以旋转了.我的测试代码:
    g.drawString("Hell0,aa!",100,100);//没旋转之前,在(100,100)写一水平字符;
    g2d.translate(100,100);
    g2d.rotate(30* Math.PI / 180);//写与水平线30度字体
    g.drawString("Hell0,aa!",100,100);//g2d.rotate(60 * Math.PI / 180);
    g2d.drawString("Hello, 90909090909090", 0,0);//写出与水平线90度字符;就直接用上面的代码,则能保证三个字符的起点位置都一样了.都是在(100,100)开始了.我昨天用错了.现在新问题是:这个时候,如果我再要在(100,100)这点为起点画一条线,或者还在这里写字符的话,因为现在的坐标系统已经转换了,现在的(100,100)已经不是原来的(100,100)的位置,还有,方向也已经旋转变换了.在应用中,应该要一写完有角度的字,坐标系统要马上还原,因为后面还要进行很多的画图操作.我试着用以下方法还原:
    g2d.translate(-100,-100);//还原坐标原点;
    g2d.rotate(-90 * Math.PI / 180);//还原旋转角度,上面做了两次旋转,共转了90度.
    g.drawString("Hello0000000000000!", 100,100);//重新定回水平的,位置在(100,100);
    g.drawLine(100,100,250,100);//画水平线;这样处理了以后,被旋转的方向是又被旋转回来,后面的写的字符和画的线都已经是水平的了,可是坐标原点却没有回到原来的(0,0),我发现Y轴方向已经还原了,但X轴方向却比原来大了很多?不知何故?
      

  8.   

    其实我也意识到与Font类无关,在第二个RotateText类中我去除了这些!
    利用你的代码:
    g2d.translate(-100,-100);//还原坐标原点;
    g2d.rotate(-90 * Math.PI / 180);//还原旋转角度,上面做了两次旋转,共转了90度.
    g.drawString("Hello0000000000000!", 100,100);//重新定回水平的,位置在(100,100);
    g.drawLine(100,100,250,100);//画水平线;
    我的确测试出Y轴方向已经还原了,但X轴方向却比原来大了很多,但是你把你吧旋转变换防在平移变换之前,X和Y轴就都还原了!如下:
    g2d.rotate(-90 * Math.PI / 180);//还原旋转角度,上面做了两次旋转,共转了90度
    g2d.translate(-100,-100);//还原坐标原点;
    g.drawString("Hello0000000000000!", 100,100);//重新定回水平的,位置在(100,100);
    g.drawLine(100,100,250,100);//画水平线;
    我想可能是由于着两个变换是有一定的顺序的!!
      

  9.   

    唉,确实是要先把角度旋转回来,再将坐标原点移回来才行.既能这样,我开始都试了移坐标点时XY都*了个cos()sin()不知为何也不行.原来JAVA里面可以有坐标体系旋转的啊,开始我做了一个给一条已知两个坐标点连成一线段,然后给这一线段加个箭头,箭头的方向随线的方向走,我还拼命计算箭头的坐标,早知用一下改变坐标体系多简单啊.非常感谢各位老兄,尤其是 OExpress(浪子猫)
      

  10.   

    老兄,突然发现问题:
    我的应用是用在APPLET里的,而且不能装JRE的。所以只能用在MS的JDK1.1下。
    在JDK1.1里没有Graphics2D这个类啊。这该如何是好啊??
    我想过把这个类打包打在我的APPLET里面去,可graphics2d这个类全是些抽象的方法,打包进去也没有用啊??