2013-03-29 66 views
0

我需要在x-y軸座標系統中繪製Google和yahoo訪問時間。現在我繪製了x-y軸座標系。重繪JPanel的一部分

public void paintComponent(Graphics gl) { 
    Graphics2D g = (Graphics2D) gl; 
    g.setColor(new Color(222, 222, 222)); 
    g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
    g.setColor(new Color(0, 0, 0)); 
    int x=15; 
    int y=15; 
    g.drawString("20", 0, 10); 
    for(int i=1;i<=20;i++) { 
     g.drawLine(x, y+(35*(i-1)), x, y+(35*i)); 
     g.drawString(""+(20-i), 0, y+(35*i)); 
    } 
    for(int i=1;i<=10;i++) { 
     g.drawLine(x+(70*(i-1)),715, x+(70*i), 715); 
     g.drawString(""+i, x+(70*i),730); 
    } 
} 

現在我需要動態地重新繪製這個訪問時間的值X-Y座標系。但我知道,當我調用重繪()。它將再次重繪()X-Y座標。 如何重新繪製訪問時間的值,而無需再次重新繪製X-Y座標?

回答

5

將GUI顯示的穩定背景部分放入BufferedImage中,然後在paintComponent(...)方法中繪製該部分。

例如,

// Warning: code has not been run nor compiled and may contain errors. 
public class MyGui extends JPanel { 
    public static final int BI_WIDTH = //..... ? the width of the image 
    public static final int BI_HEIGHT = // .....? the height of the image 
    private BufferedImage bImg; 

    public MyGui() { 
    bImg = makeImage(); 
    // ... other code 
    } 

    public BufferedImage makeImage() { 
    BufferedImage bImg = new BufferedImage(BI_WIDTH, BI_HEIGHT, 
     BufferedImage.TYPE_INT_ARGB); 
    Graphics2D g2 = bImg.createGraphics(); 

    // ... do your background drawing here, the display that doesn't change 

    g2.dispose(); 
    return bImg; 
    } 

    public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    if (bImg != null) { 
     g.drawImage(bImg, 0, 0, this); 
    } 
    // ... draw the changing parts of your display 
    } 

    // note, if your image is going to fill up your JPanel, then it's 
    // also a good idea to override the getPreferredSize() method to make sure 
    // that the JPanel's size is correct and matches that of the image: 
    @Override 
    public Dimension getPreferredSize() { 
    return new Dimension(BI_WIDTH, BI_HEIGHT); 
    } 

編輯:代碼說明和關於getPreferredSize()

1

我如何重繪的訪問時間價值沒有重繪X-Y座標再評論?

爲什麼重要的是重新繪製X/Y軸?如果你擔心表現不會有什麼明顯的差異。

我知道這不是你問的問題,但這是一個將X/Y軸作爲獨立組件繪製的解決方案。然後,您可以獨立繪製訪問時間。它可能看起來更復雜一點,但是這是因爲X/Y軸代碼比你更有趣。

此外,這可能使繪畫的訪問時間更容易,因爲所有繪畫偏移現在都是零,因爲您正在單獨的面板上繪畫。

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

public class Axis extends JComponent 
{ 
    public static final int HORIZONTAL = 0; 
    public static final int VERTICAL = 1; 

    private int orientation; 
    private int ticks; 
    private int tickIncrement; 
    private int tickSize = 7; 

    public Axis(int orientation, int ticks, int tickIncrement) 
    { 
     this.orientation = orientation; 
     this.ticks = ticks; 
     this.tickIncrement = tickIncrement; 

     setFont(new Font("SansSerif", Font.PLAIN, 10)); 
    } 

    public Dimension getPreferredSize() 
    { 
     FontMetrics fontMetrics = getFontMetrics(getFont()); 
     int tickDimension = ticks * tickIncrement; 

     if (orientation == HORIZONTAL) 
     { 
      int height = (fontMetrics.getHeight() * 2) - fontMetrics.getAscent() + (tickSize * 2); 
      return new Dimension(tickDimension + getVerticalAxisWidth(), height); 
     } 
     else 
     { 
      int digits = String.valueOf(ticks).length(); 
      int textWidth = fontMetrics.charWidth('0') * digits; 
      int width = textWidth + (tickSize * 2) + 10; 
      return new Dimension(width, tickDimension); 
     } 
    } 

    protected void paintComponent(Graphics g) 
    { 
     // Paint background 

     g.setColor(getBackground()); 
     g.fillRect(0, 0, getWidth(), getHeight()); 

     // Paint graph axis 

     g.setFont(getFont()); 
     g.setColor(getForeground()); 

     if (orientation == HORIZONTAL) 
      paintHorizontalAxis(g); 
     else 
      paintVerticalAxis(g); 
    } 

    private void paintHorizontalAxis(Graphics g) 
    { 
     FontMetrics fontMetrics = getFontMetrics(g.getFont()); 
     int label = 1; 
     int offset = tickIncrement; 
     int width = getWidth(); 
     int adjustmentX = getVerticalAxisWidth() - 1; 
     int textOffset = tickSize + fontMetrics.getHeight(); 

     while (offset <= width) 
     { 
      int hOffset = adjustmentX + offset; 
      g.drawLine(adjustmentX, 0, width, 0); 
      g.drawLine(hOffset, 0, hOffset, tickSize); 
      String text = "" + label; 
      int textAdjustment = (fontMetrics.stringWidth(text) - 1)/2; 
      g.drawString(text, hOffset - textAdjustment, textOffset); 

      offset += tickIncrement; 
      label++; 
     } 
    } 

    private int getVerticalAxisWidth() 
    { 
     Container parent = (Container)getParent(); 

     if (parent == null) 
      return 0; 

     LayoutManager manager = parent.getLayout(); 

     if (manager instanceof BorderLayout) 
     { 
      BorderLayout layout = (BorderLayout)manager; 

      Component south = layout.getLayoutComponent(BorderLayout.SOUTH); 
      Component west = layout.getLayoutComponent(BorderLayout.WEST); 

      if (this.equals(south) 
      && west instanceof Axis) 
      { 
       return west.getPreferredSize().width; 
      } 
     } 

     return 0; 
    } 

    private void paintVerticalAxis(Graphics g) 
    { 
     FontMetrics fontMetrics = getFontMetrics(g.getFont()); 
     int label = 1; 
     int offset = tickIncrement; 
     int x = getWidth() - 1; 
     int height = getHeight(); 
     int textOffset = fontMetrics.getHeight() - fontMetrics.getAscent() + 1; 

     while (offset <= height) 
     { 
      int vOffset = height - offset; 
      g.drawLine(x, 0, x, height); 
      g.drawLine(x, vOffset, x - tickSize, vOffset); 
      String text = "" + label; 
      int textAdjustment = fontMetrics.stringWidth(text) + tickSize + 5; 
      g.drawString(text, x - textAdjustment, vOffset + textOffset); 

      offset += tickIncrement; 
      label++; 
     } 
    } 

    private static void createAndShowUI() 
    { 
     JPanel graph = new JPanel(new BorderLayout()); 

     Axis vertical = new Axis(Axis.VERTICAL, 8, 50); 
     vertical.setBackground(Color.ORANGE); 
     graph.add(vertical, BorderLayout.WEST); 

     Axis horizontal = new Axis(Axis.HORIZONTAL, 12, 50); 
     horizontal.setBackground(Color.ORANGE); 
     graph.add(horizontal, BorderLayout.SOUTH); 

     // Do you custom painting on this panel 

     JPanel center = new JPanel(); 
     center.setBackground(Color.YELLOW); 
     graph.add(center); 

     JFrame frame = new JFrame("SSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JScrollPane(graph)); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

這仍然不是一個完美的解決方案,因爲該代碼使用的BorderLayout舉行3個面板取決於你,但我不喜歡寫一個自定義佈局管理器展示的概念。

+0

:-),但是-1000,但我不想寫一個自定義佈局管理器來演示這個概念 – mKorbel