2013-03-29 2 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 축 좌표를 다시 칠합니다. 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 축 코드가 너보다 더 환상적이기 때문입니다.

또한이 기능을 사용하면 별도의 패널에 그림을 그리기 때문에 모든 페인트 오프셋이 이제 0에 도달하기 때문에 액세스 시간을 더 쉽게 페인팅 할 수 있습니다. 코드가 3 개 패널을 보유 할의 BorderLayout을 사용하여 당신에 따라 달라집니다,하지만 난 개념을 보여주기 위해 사용자 정의 레이아웃 매니저를 쓰는 것 같은 느낌하지 않았기 때문에

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(); 
      } 
     }); 
    } 
} 

이 아직 완벽한 해결책이 아니다.

+0

:-)하지만 -1000이지만이 개념을 보여주기 위해 맞춤 레이아웃 관리자를 작성하는 기분이 들지 않았습니다. – mKorbel