2011-12-20 144 views
3

下面的代碼繪製了一些簡單的x-y數據,但它有兩個問題,我不知道如何解決。x-y座標軸和標籤的旋轉文本

首先,它繪製了一些數據點的負值,這意味着在x軸下向南延伸的線。由於數據點是隨機選擇的,因此您可能需要稍微調整一下框架的大小,以查看以顯示此錯誤的方式繪製的新隨機數。所有的數據值都是正值,所以我希望所有的偏差都能在藍色底部標記線以上向北投影,並且我需要確保沒有偏差向南延伸到藍色底部標記線以下。

其次,y軸標籤在屏幕上佔用太多空間。它需要旋轉-90度。但是,我所看到的所有示例都涉及使用graphics2d對象旋轉整個面板。我不想旋轉整個面板。相反,我只是想旋轉y軸標籤的文字。

任何人都可以告訴我如何更改下面的代碼來解決這兩個具體問題?

的代碼在以下兩個文件:

GUI.java

import java.awt.*; 
import javax.swing.*; 

class GUI{ 

GUI() { 
    // Create a new JFrame container. 
    JFrame jfrm = new JFrame("X-Y Plot"); 
    // Specify FlowLayout for the layout manager. 
    jfrm.getContentPane().setLayout(new FlowLayout()); 
    int frameHeight = 400; 
    int frameWidth = 300; 
    // Give the frame an initial size. 
    jfrm.setSize(frameWidth, frameHeight); 

    // Terminate the program when the user closes the application. 
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    // Create a text-based label. 
    JVertLabel myVLabel = new JVertLabel("y-axis label"); 
    int width = myVLabel.WIDTH; 

    PaintPanel myPP = new PaintPanel(frameWidth-width-50-20,frameHeight-70); 
    jfrm.add(myPP); 

    jfrm.add(myVLabel);// Add the label to the frame. 

    // Display the frame. 
    jfrm.setVisible(true); 
} 

public static void main(String args[]) { 
    // Create the frame on the event dispatching thread. 
    SwingUtilities.invokeLater(new Runnable() {public void run(){new GUI();}}); 
} 

    public class JVertLabel extends JComponent { 

     private String text; 

     public JVertLabel(String s) { 
      text = s; 
     }//constructor 

     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.rotate(Math.toRadians(-90)); 
      g2d.drawString(text, 0, 0); 
     } 
    } 
} 

PaintPanel.java

import java.awt.*; 
import javax.swing.*; 
import java.util.*; 

class PaintPanel extends JPanel { 

    Insets ins; // holds the panel's insets 
    Random rand; // used to generate random numbers 

    PaintPanel(int w, int h) { 
     setOpaque(true);// Ensure that panel is opaque. 
     setPreferredSize(new Dimension(w, h));// Set preferred dimension as specfied. 
     rand = new Random(); 
    } 

    protected void paintComponent(Graphics g) {// Override paintComponent() method. 
     super.paintComponent(g);// Always call superclass method first. 
     int height = getHeight();// Get height of component. 
     int width = getWidth();// Get width of component. 
     ins = getInsets();// Get the insets. 
     // Get dimensions of text 
     Graphics2D g2d = (Graphics2D) g; 
     Font font = new Font("Serif", Font.PLAIN, 12); 
     FontMetrics fontMetrics = g2d.getFontMetrics(); 
     String xString = ("x-axis label"); 
     int xStrWidth = fontMetrics.stringWidth(xString); 
     int xStrHeight = fontMetrics.getHeight(); 
     String yString = "y-axis-label"; 
     int yStrWidth = fontMetrics.stringWidth(yString); 
     int yStrHeight = fontMetrics.getHeight(); 
     int leftStartPlotWindow = ins.left + 5 + yStrWidth; 
     int hPad = 3; 

     // Fill panel by plotting random data in a bar graph. 
     for (int i = leftStartPlotWindow + hPad; i <= width - leftStartPlotWindow - hPad + yStrWidth + 1; i += 4) { 
      int h = Math.abs(rand.nextInt(height - ins.bottom));//Get rand# betw/0 and max height of drawing area. 
      // If generated value w/in or too close to border, change it to just outside border. 
      if (h <= ins.top) { 
       h = ins.top + 1; 
      } 
      g.drawLine(i, Math.abs(height - ins.bottom - xStrHeight - 5), i, h);// Draw a line that represents data. 
     } 
     g.setColor(Color.blue); 
     g.drawRect(leftStartPlotWindow, ins.bottom + 2, width - leftStartPlotWindow - ins.right - hPad, height - xStrHeight - 6); 
     g.setColor(Color.red); 
     g.drawRect(ins.left, ins.bottom, width - ins.left - 1, height - ins.bottom - 1); 
     g.drawString(xString, (width/2) - (xStrWidth/2), height - ins.bottom - 6); 
     g.drawString(yString, ins.left, height/2); 
    } 
} 
+0

+1 [sscce](http://sscce.org/)。 – trashgod 2011-12-20 03:53:43

回答

3

所有數據值都將是積極的,所以我希望所有的撓度項目向北上述藍底標記線,我需要確保沒有變形向南延伸的下方底部的藍色標記線。

您需要計算隨機高度,以便所有值都適合可用空間。所以計算會是這樣的:

int randomHeight = panelHeight - offset.top - offset.bottom - heightForTheXAxisText; 

然後,你不必擔心負值或面板邊界外的延伸線的頂部。

我所見過的所有例子都涉及到使用graphics2d對象旋轉整個面板。我不想旋轉整個面板。相反,我只是想旋轉y軸標籤的文字。

圖形集的旋轉反對,繪製文本,然後恢復圖形的旋轉對象返回0。

或者,您從圖形對象的當前創建一個新的Graphcis對象,然後應用旋轉,繪製文本,然後處理臨時圖形對象。

+0

+1正確回答我的問題。 – CodeMed 2011-12-20 05:34:59

2

JFreeChart默認地址這兩個問題,在本example所示。

在你的榜樣,

  1. 你必須努力使其之前創建的數據模型。然後,您可以掃描它以確定range軸的極限。 List<Double>可能是一個合適的選擇。

  2. 您可以通過更改圖形上下文的AffineTransform來旋轉範圍標籤,如RotateText所示。

+0

+1試圖幫助。我沒有將JFreeChart用於許可原因。但我確實閱讀過您發送的文章。謝謝。 – CodeMed 2011-12-20 05:35:58