2012-09-14 37 views
1

我正在製作一個程序,該圖像具有滾動顯示的圖像,並且我無法弄清楚如果按下按鈕時如何更新圖像(例如:將綠色橢圓添加到圖像)。它已經將圖像繪製到JScrollPane中,您可以滾動,但是當您單擊某個按鈕時,它不會刷新圖像。 (在代碼中有詳細介紹) 下面是代碼:Java JScrollPane更新圖像

public class PegMaster extends JPanel implements ActionListener { 

    //Note: not complete code 
    public PegBox[] pegbox = new PegBox[9]; 

    public static Dimension size = new Dimension(520, 500); 

    public BufferedImage canvas; 
    public Graphics2D g2d; 
    public JScrollPane scroller; 
    JPanel panel; 
    private Canvas window; 

    JScrollPane pictureScrollPane; 

    public PegMaster() { 
     JButton button = new JButton("test"); 
     button.addActionListener(this); 
     add(button); 

     canvas = new BufferedImage((int)size.getWidth()-30, 75 * GUESSES, BufferedImage.TYPE_INT_RGB); 
     g2d = canvas.createGraphics(); 
     for(int i = 0;i<=pegbox.length-1;i++) { 
      pegbox[i] = new PegBox(i, g2d); 
     } 
     window = new Canvas(new ImageIcon(toImage(canvas)), 1); 
     //Class Canvas is a Scrollable JLabel to draw to (the image) 
     pictureScrollPane = new JScrollPane(window); 
     pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10, (int)size.getHeight()-20)); 
     pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black)); 
     add(pictureScrollPane); 

     //adds the scrollpane, but can't update the image in it 
    } 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createGUI(); 
       //just adds the scrollpane 
      } 
     }); 
    } 

    public void paint(Graphics g) { 
     super.paint(g); 

     for(int i = 0;i<=pegbox.length-1;i++) { 
      //pegbox[i] = new PegBox(i); 
      pegbox[i].draw(g2d); 
     } 
     try { 
      Thread.sleep(20); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     //tried re-making the scrollpane, didn't work. 
     //window = new Canvas(new ImageIcon(toImage(canvas)), 1); 
     //pictureScrollPane = new JScrollPane(window); 
     //pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10 (int)size.getHeight()-20)); 
     //pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black)); 
     //tried imageupdate: pictureScrollPane.imageUpdate(canvas, 0, 0, 0 (int)size.getWidth()-10, (int)size.getHeight()-20); 
     //remove(pictureScrollPane); 
     //tried this: pictureScrollPane.revalidate(); 
     repaint(); 
    } 
} 
+0

另外,請參閱[本答案](http://stackoverflow.com/a/12216139/418556),它使用圖像作爲繪圖表面。 –

+0

我刪除了大部分不相關的代碼,而Canvas不是java.awt.canvas,它是我自己的代碼Canvas.java,它擴展了JLabel並實現了Scrollable – M4trixSh4d0w

回答

3

試試這個類,它顯示一個圖像。這可以被添加到JScrollPane

public class ImagePanel extends JPanel { 

    public Image img; 

    public ImagePanel(Image img){ 
     this.img = img; 
    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.drawImage(img, 0, 0, this); 
    } 

} 

現在加上這個類的JScrollPane。要更新它,只需更改圖像參考並在組件上調用repaint()方法

+0

它已經顯示一個圖像,只是我需要更新圖像 – M4trixSh4d0w

+0

謝謝。這個對我有用 :) – M4trixSh4d0w

6

首先,不使用Canvas這是一個重量級分量,它只會導致你從長遠來看問題,請使用JComponentJPanel

其次,請勿覆蓋paint,請改用paintComponentpaint做了很多工作,包括繪製邊界和子組件等東西。如果您使用paintComponent,因爲它位於繪製層次結構中的適當層上,因此您最好這樣做。

第三,在事件調度線程中從不調用類似Thread.sleep的東西。這會導致事件隊列暫停並停止響應事件,使您的程序看起來像停滯。

第四,在繪製方法中不要致電repaintinvalidate,revalidate或任何可能導致重繪請求發生的方法)。你只需要最大化你的CPU,你將被迫終止這個過程。第五,你沒有提供actionPerformed方法,這可能是所有動作(和問題)都在的地方。我想你需要撥打window.repaint()和可能window.invalidate()(倒序),但由於您沒有提供使用此代碼,這只是猜測...

+1

1+用於挖掘所有這些。偉大的建議! –

+0

+1,但他表示'canvas'是他的'JLabel'的實例,因此不是'重量級'的組件。 –

+0

謝謝,但\我說「不完整的代碼」我省略了actionlistener,並且我製作了自己的Canvas.java,擴展了JLabel並實現了Scrollable – M4trixSh4d0w

0

上述解決方案未解決我的目的,因此我研究並找到了this。 請按照整個例子的鏈接。如果鏈接發生變化,我添加了代碼以供參考。

public class ScrollablePicture extends JLabel 
          implements Scrollable, 
             MouseMotionListener { 

private int maxUnitIncrement = 1; 
private boolean missingPicture = false; 

public ScrollablePicture(ImageIcon i, int m) { 
    super(i); 
    if (i == null) { 
     missingPicture = true; 
     setText("No picture found."); 
     setHorizontalAlignment(CENTER); 
     setOpaque(true); 
     setBackground(Color.white); 
    } 
    maxUnitIncrement = m; 

    //Let the user scroll by dragging to outside the window. 
    setAutoscrolls(true); //enable synthetic drag events 
    addMouseMotionListener(this); //handle mouse drags 
} 

//Methods required by the MouseMotionListener interface: 
public void mouseMoved(MouseEvent e) { } 
public void mouseDragged(MouseEvent e) { 
    //The user is dragging us, so scroll! 
    Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); 
    scrollRectToVisible(r); 
} 

public Dimension getPreferredSize() { 
    if (missingPicture) { 
     return new Dimension(320, 480); 
    } else { 
     return super.getPreferredSize(); 
    } 
} 

public Dimension getPreferredScrollableViewportSize() { 
    return getPreferredSize(); 
} 

public int getScrollableUnitIncrement(Rectangle visibleRect, 
             int orientation, 
             int direction) { 
    //Get the current position. 
    int currentPosition = 0; 
    if (orientation == SwingConstants.HORIZONTAL) { 
     currentPosition = visibleRect.x; 
    } else { 
     currentPosition = visibleRect.y; 
    } 

    //Return the number of pixels between currentPosition 
    //and the nearest tick mark in the indicated direction. 
    if (direction < 0) { 
     int newPosition = currentPosition - 
         (currentPosition/maxUnitIncrement) 
          * maxUnitIncrement; 
     return (newPosition == 0) ? maxUnitIncrement : newPosition; 
    } else { 
     return ((currentPosition/maxUnitIncrement) + 1) 
       * maxUnitIncrement 
       - currentPosition; 
    } 
} 

public int getScrollableBlockIncrement(Rectangle visibleRect, 
             int orientation, 
             int direction) { 
    if (orientation == SwingConstants.HORIZONTAL) { 
     return visibleRect.width - maxUnitIncrement; 
    } else { 
     return visibleRect.height - maxUnitIncrement; 
    } 
} 

public boolean getScrollableTracksViewportWidth() { 
    return false; 
} 

public boolean getScrollableTracksViewportHeight() { 
    return false; 
} 

public void setMaxUnitIncrement(int pixels) { 
    maxUnitIncrement = pixels; 
}