2013-03-29 65 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