2016-10-01 18 views
0

私はJava GUIを使用して遊んでいますが、その理由を理解できないエラーが発生しました。Java GUIのフラッド・フィル・エラー

私のプログラムは、(ラインの内側の色を充填)洪水充填の周りに基づいていますが、私は埋めるためにしようとすると、私はこのエラーを取得します

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError 
at java.util.Hashtable.get(Unknown Source) 
at javax.swing.UIDefaults.getFromHashtable(Unknown Source) 
at javax.swing.UIDefaults.get(Unknown Source) 
at javax.swing.MultiUIDefaults.get(Unknown Source) 
at javax.swing.UIDefaults.getColor(Unknown Source) 
at javax.swing.UIManager.getColor(Unknown Source) 
at javax.swing.LookAndFeel.installColors(Unknown Source) 
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source) 
at javax.swing.plaf.basic.BasicLabelUI.installDefaults(Unknown Source) 
at javax.swing.plaf.basic.BasicLabelUI.installUI(Unknown Source) 
at javax.swing.JComponent.setUI(Unknown Source) 
at javax.swing.JLabel.setUI(Unknown Source) 
at javax.swing.JLabel.updateUI(Unknown Source) 
at javax.swing.JLabel.<init>(Unknown Source) 
at javax.swing.JLabel.<init>(Unknown Source) 
at MapPanel.refreshImage(MapPanel.java:167) 
at MapPanel.setImage(MapPanel.java:162) 
at MapPanel.floodFill(MapPanel.java:224) 

[これらの1の繰り返しはかなり]

at MapPanel.floodFill(MapPanel.java:231) 
at MapPanel.floodFill(MapPanel.java:230) 

[ライン230及び231のためのコード]

floodFill(newImage, mark, row - 1, col, srcColor, tgtColor); 
floodFill(newImage, mark, row + 1, col, srcColor, tgtColor); 

画像は色で更新されるすべてではありませんが...

enter image description here

は、私はしばらくの間、この上で立ち往生されていますし、任意のヘルプは行います、あなたは私が言うことをしようとしているものを理解してほしいですありがとう。

コード

// Mouse Listener 
public class MouseCapture implements MouseListener 
{ 
    @Override 
    public void mouseEntered(MouseEvent e) { 
    } 
    @Override 
    public void mouseExited(MouseEvent e) { 
    } 
    @Override 
    public void mousePressed(MouseEvent e) { 
    } 
    @Override 
    public void mouseReleased(MouseEvent e) { 
    } 
    @Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse clicked"); 
     System.out.println(e.getX() + "," + e.getY()); 

     boolean[][] mark = new boolean[image.getHeight()][image.getWidth()]; 

     for (int row = e.getY() + 23; row < image.getHeight(); row++) { 
      for (int col = e.getX() - 200; col < image.getWidth(); col++) { 
       floodFill(image, mark, row, col, Color.WHITE, getColor()); 
      } 
     } 

     image.setRGB(e.getX(), e.getY() + 23, Color.BLACK.getRGB()); 
     refreshImage(); 

    } 
} 

private void floodFill(BufferedImage newImage, boolean[][] mark, int row, int col, Color srcColor, Color tgtColor) 
{ 
    // make sure row and col are inside the image 
    if (row < 0) return; 
    if (col < 0) return; 
    if (row >= newImage.getHeight()) return; 
    if (col >= newImage.getWidth()) return; 

    // make sure this pixel hasn't been visited yet 
    if (mark[row][col]) return; 

    // make sure this pixel is the right color to fill 
    if (!(newImage.getRGB(col, row) == (srcColor.getRGB()))) return; 

    // fill pixel with target color and mark it as visited 
    image.setRGB(col, row, tgtColor.getRGB()); 
    mark[row][col] = true; 

    // set drawn image 
    setImage(newImage); 

    // recursively fill surrounding pixels 
    // (this is equivelant to depth-first search) 
    floodFill(newImage, mark, row - 1, col, srcColor, tgtColor); 
    floodFill(newImage, mark, row + 1, col, srcColor, tgtColor); 
    floodFill(newImage, mark, row, col - 1, srcColor, tgtColor); 
    floodFill(newImage, mark, row, col + 1, srcColor, tgtColor); 
} 
+0

私の解決策を試しましたか?乾杯! –

+0

@Wojciech Kaziorの素晴らしい例は、明日私の心が揚げられ、睡眠が必要なので明日に私のプログラムに追加されます(コードダーは睡眠が必要です:D) ありがとう! –

答えて

1

ペイントしようとするポリゴンは、このアルゴリズムの再帰的なバージョンのために大きすぎることを意味し、「塗りつぶし」を使用しているときは、stackOverflowErrorを取得する場合。キューまたはスタック実装のバージョンを使用してみてください。

import java.util.*; 

public class Main { 

    public static class Position { 
     private int y; 
     private int x; 

     public Position(int y, int x) { 
      this.y = y; 
      this.x = x; 
     } 

     public int getY() { 
      return y; 
     } 

     public int getX() { 
      return x; 
     } 
    } 

    public static void floodFill(Position position, int oldColor, int newColor, int[][] image) { 

     Queue<Position> queue = new LinkedList<Position>(); 
     queue.add(position); 

     while (queue.size() > 0) { 
      Position newPosition = queue.poll(); 

      if (newPosition.getY() >= 0 && newPosition.getY() < image.length // check bounds 
        && newPosition.getX() >= 0 && newPosition.getX() < image[0].length // check bounds 
        && image[newPosition.getY()][newPosition.getX()] == oldColor) { 

       image[newPosition.getY()][newPosition.getX()] = newColor; 

       queue.add(new Position(newPosition.getY(), newPosition.getX() - 1)); 
       queue.add(new Position(newPosition.getY(), newPosition.getX() + 1)); 
       queue.add(new Position(newPosition.getY() - 1, newPosition.getX())); 
       queue.add(new Position(newPosition.getY() + 1, newPosition.getX())); 
      } 
     } 
    } 

    public static void main(String[] args) { 

     int[][] array = new int[20][40]; // 20 rows, 40 columns 

     for (int y = 0; y < array.length; y++) { // iterate through rows 
      for (int x = 0; x < array[0].length; x++) // iterate through cols 
       System.out.print(array[y][x]); 
      System.out.println(); 
     } 

     floodFill(new Position(5, 5), 0, 1, array); 

     for (int y = 0; y < array.length; y++) { // iterate through rows 
      for (int x = 0; x < array[0].length; x++) // iterate through cols 
       System.out.print(array[y][x]); 
      System.out.println(); 
     } 
    } 
} 

この機能が動作することをテストできます。キューに追加しながら位置を確認することもできますが、コードは透明性が低くなります。