2012-02-04 54 views
1

所以我一直在試圖獲得javax.swing的句柄,並且遇到了一些麻煩。我試圖執行'8拼圖',其中8個拼圖和1個3x3格子的開放地點,當點擊旁邊的一塊拼圖時,它會與空曠地點交易空間。我的結構由一個JFrame組成,它包含一個JPanel,JPanel包含9個tile作爲JComponents,但只有JPanel呈現,並且無法找到tile。任何有關這個問題的幫助將不勝感激。試圖學習javax.swing的來龍去脈

import javax.swing.*; 



    public class MainFrame{ 

     public static void main(String[] args){ 
      JFrame frame = new JFrame("8 Puzzle"); 
      frame.setVisible(true); 
      frame.setSize(600, 600); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      PieceManager pm = new PieceManager(); 
      frame.add(pm); 

     } 
    } 

    import java.awt.Color; 
    import java.awt.GridLayout; 
    import java.awt.event.MouseEvent; 
    import java.awt.event.MouseListener; 
    import java.util.ArrayList; 
    import java.util.Arrays; 
    import java.util.Collections; 
    import java.util.Random; 

    import javax.swing.*; 

二等

public class PieceManager extends JPanel{ 

     int[] possmoves; 
     GameTile[] pieces; 
     int openSpot; 

     public PieceManager(){ 
      this.setSize(600,600); 
      this.setBackground(new Color(255,255,255)); 
      this.setLayout(new GridLayout(3,3)); 
      pieces = new GameTile[9]; 
      this.init(); 
      this.addMouseListener(new ClickAction()); 
     } 

     public void init(){ 
      ArrayList<Integer> nums = new ArrayList<Integer>(); 
      Random rand = new Random(); 
      for(int i=0;i<9;i++){ 
       nums.add(i); 
      } 
      for(int i=0,j=8;i<8;i++,j--){ 
       int p = rand.nextInt(j); 
       GameTile x = new GameTile(i,nums.remove(p)); 
       pieces[i]=x; 
       nums.removeAll(Collections.singleton(null)); 
      } 
      GameTile z = new GameTile(8,nums.get(0)); 
      pieces[8]=z; 
      possmoves = new int[4]; 
      boolean found = false; 
      for(int i=0;i<9||found;i++){ 
       if(pieces[i].getID()==0){ 
        openSpot = pieces[i].getPos(); 
       } 
      } 
      setOpenSpot(); 
      paint(); 
     } 

     public void paint(){ 
      this.removeAll(); 
      for(int i=0;i<9;i++){ 
       this.add(pieces[i]); 
       pieces[i].setVisible(true); 
      } 
     } 

     public void setOpenSpot(){ 
      Arrays.fill(possmoves,-1); 
      if(openSpot==0){ 
       possmoves[0]=1; 
       possmoves[1]=3; 
      } else if(openSpot==1){ 
       possmoves[0]=0; 
       possmoves[1]=2; 
       possmoves[3]=4; 
      } else if(openSpot==2){ 
       possmoves[0]=1; 
       possmoves[1]=5; 
      } else if(openSpot==3){ 
       possmoves[0]=0; 
       possmoves[1]=4; 
       possmoves[2]=6; 
      } else if(openSpot==4){ 
       possmoves[0]=1; 
       possmoves[1]=3; 
       possmoves[2]=5; 
       possmoves[3]=7; 
      } else if(openSpot==5){ 
       possmoves[0]=2; 
       possmoves[1]=4; 
       possmoves[3]=8; 
      } else if(openSpot==6){ 
       possmoves[0]=3; 
       possmoves[1]=7; 
      } else if(openSpot==7){ 
       possmoves[0]=6; 
       possmoves[1]=4; 
       possmoves[2]=8; 
      } else if(openSpot==8){ 
       possmoves[0]=5; 
       possmoves[1]=7; 
      } 

     } 

     public void checkCorrect(){ 

     } 

     public class ClickAction implements MouseListener{ 


      @Override 
      public void mouseClicked(MouseEvent e) { 

       int x = e.getX(); 
       int y = e.getY(); 
       int pX=(int)Math.floor(x/200); 
       int pY=(int)Math.floor(y/200); 
       int piecepressed=(pY*3)+pX; 
       boolean moveable = false; 
       int toBeMoved = -1; 
       for(int i=0;i<4;i++){ 
        if(piecepressed==possmoves[i]){ 
         moveable=true; 
         toBeMoved=possmoves[i]; 
        } 
       } 
       if(moveable){ 
        GameTile saved=pieces[openSpot]; 
        pieces[openSpot]=pieces[toBeMoved]; 
        pieces[toBeMoved]=saved; 
        openSpot=toBeMoved; 
        setOpenSpot(); 
        paint(); 
        checkCorrect(); 
       } 
      } 

      @Override 
      public void mouseEntered(MouseEvent arg0) { 
     // TODO Auto-generated method stub 
    } 

      @Override 
      public void mouseExited(MouseEvent arg0) { 
       // TODO Auto-generated method stub 
     } 

      @Override 
      public void mousePressed(MouseEvent arg0) { 
       // TODO Auto-generated method stub 
      } 

      @Override 
       public void mouseReleased(MouseEvent arg0) { 
       // TODO Auto-generated method stub 

      } 
     } 
    } 

瓷磚類(第三次和最後)

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

    public class GameTile extends JComponent{ 

private int id; 
private int position; 

public GameTile(int id, int initpos){ 
    if(id==0){ 
     this.id=id; 
     this.position=initpos; 
    } else{ 
     this.id=id; 
     this.position = initpos; 
     String label = Integer.toString(id); 
     setSize(200,200); 
     setBackground(new Color(0,0,0)); 
     Label l = new Label(label,Label.CENTER); 
     this.add(l); 
     l.setVisible(true); 
    } 
} 

public void setPos(int position){ 
    this.position=position; 
} 

public int getPos(){ 
    return position; 
} 

public int getID(){ 
    return id; 
} 
    } 
+0

您的'GameTile'應該可以從'JPanel'繼承,而不是'JComponent'。我認爲'JComponent'子類必須做他們自己的繪圖。 – millimoose 2012-02-04 22:17:15

+0

@Inerdial:所有JComponents(包括JPanel)「自己完成繪圖」。我不確定你對此推薦的理由或理由。你能否詳細說明一下? – 2012-02-04 22:58:01

+0

@HovercraftFullOfEels我不確定是否將子組件添加到「JComponent」將使JComponent繪製它們。也就是說,如果一個'JComponent'可以用作通用容器小部件 - 我的印象就是'JPanel'。 (實際上,這可能是非常錯誤的。) – millimoose 2012-02-04 22:59:57

回答

5

使用一個JComponent的是好的,但你可能想將其設置爲不透明。

而且

  • 不要用Swing組件混合AWT(即標籤)。
  • 不要setSize(...)。相反處理preferredSize。最好覆蓋getPreferredSize()並返回適當的維度。我已經使用過setPreferredSize(...),但面臨着kleopatra的憤怒。
  • 不要重寫JComponent或其任何子組件(包含JPanel)paint方法,但沒有充分的理由(您沒有)。而是覆蓋paintComponent編輯:我看到你的繪畫方法不是真正的覆蓋,所以這是好的 - 抱歉我的部分誤解。
  • 您幾乎可以從不直接致電paintpaintComponent。相反,您可以撥打repaint()並讓JVM爲您調用繪畫方法。 編輯:同上,因爲這是我對你的代碼的誤解。您將想要在刪除並替換您的JPanel中的組件後調用'revalidate()and repaint()`。
  • 你可以看到你的JComponents是存在的,如果你給他們的邊界佔了。
  • 編輯2:如果您希望將組件添加到它們中,您將需要爲您的JComponents提供一個佈局,以便輕鬆放置和可視化。在這個例子中,我給了我一個BorderLayout

我已經將一堆類合併爲一個文件,以方便編譯。
我已經通過// !!評論指出了重要更改。

import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collections; 
import java.util.Random; 

import javax.swing.*; 

public class MainFrame { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("8 Puzzle"); 
     frame.setVisible(true); 
     frame.setSize(600, 600); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     PieceManager pm = new PieceManager(); 
     frame.add(pm); 

    } 
} 

class PieceManager extends JPanel { 

    int[] possmoves; 
    GameTile[] pieces; 
    int openSpot; 

    public PieceManager() { 
     this.setSize(600, 600); 
     this.setBackground(new Color(255, 255, 255)); 
     this.setLayout(new GridLayout(3, 3)); 
     pieces = new GameTile[9]; 
     this.init(); 
     this.addMouseListener(new ClickAction()); 
    } 

    public void init() { 
     ArrayList<Integer> nums = new ArrayList<Integer>(); 
     Random rand = new Random(); 
     for (int i = 0; i < 9; i++) { 
     nums.add(i); 
     } 
     for (int i = 0, j = 8; i < 8; i++, j--) { 
     int p = rand.nextInt(j); 
     GameTile x = new GameTile(i, nums.remove(p)); 
     pieces[i] = x; 
     nums.removeAll(Collections.singleton(null)); 
     } 
     GameTile z = new GameTile(8, nums.get(0)); 
     pieces[8] = z; 
     possmoves = new int[4]; 
     boolean found = false; 
     for (int i = 0; i < 9 || found; i++) { 
     if (pieces[i].getID() == 0) { 
      openSpot = pieces[i].getPos(); 
     } 
     } 
     setOpenSpot(); 
     paint(); 
    } 

    public void paint() { 
     this.removeAll(); 
     for (int i = 0; i < 9; i++) { 
     this.add(pieces[i]); 
     pieces[i].setVisible(true); 
     } 
     revalidate(); // !! 
     repaint(); // !! 
    } 

    public void setOpenSpot() { 
     Arrays.fill(possmoves, -1); 
     if (openSpot == 0) { 
     possmoves[0] = 1; 
     possmoves[1] = 3; 
     } else if (openSpot == 1) { 
     possmoves[0] = 0; 
     possmoves[1] = 2; 
     possmoves[3] = 4; 
     } else if (openSpot == 2) { 
     possmoves[0] = 1; 
     possmoves[1] = 5; 
     } else if (openSpot == 3) { 
     possmoves[0] = 0; 
     possmoves[1] = 4; 
     possmoves[2] = 6; 
     } else if (openSpot == 4) { 
     possmoves[0] = 1; 
     possmoves[1] = 3; 
     possmoves[2] = 5; 
     possmoves[3] = 7; 
     } else if (openSpot == 5) { 
     possmoves[0] = 2; 
     possmoves[1] = 4; 
     possmoves[3] = 8; 
     } else if (openSpot == 6) { 
     possmoves[0] = 3; 
     possmoves[1] = 7; 
     } else if (openSpot == 7) { 
     possmoves[0] = 6; 
     possmoves[1] = 4; 
     possmoves[2] = 8; 
     } else if (openSpot == 8) { 
     possmoves[0] = 5; 
     possmoves[1] = 7; 
     } 

    } 

    public void checkCorrect() { 

    } 

    public class ClickAction implements MouseListener { 

     @Override 
     public void mouseClicked(MouseEvent e) { 

     int x = e.getX(); 
     int y = e.getY(); 
     int pX = (int) Math.floor(x/200); 
     int pY = (int) Math.floor(y/200); 
     int piecepressed = (pY * 3) + pX; 
     boolean moveable = false; 
     int toBeMoved = -1; 
     for (int i = 0; i < 4; i++) { 
      if (piecepressed == possmoves[i]) { 
       moveable = true; 
       toBeMoved = possmoves[i]; 
      } 
     } 
     if (moveable) { 
      GameTile saved = pieces[openSpot]; 
      pieces[openSpot] = pieces[toBeMoved]; 
      pieces[toBeMoved] = saved; 
      openSpot = toBeMoved; 
      setOpenSpot(); 
      paint(); 
      checkCorrect(); 
     } 
     } 

     @Override 
     public void mouseEntered(MouseEvent arg0) { 

     } 

     @Override 
     public void mouseExited(MouseEvent arg0) { 

     } 

     @Override 
     public void mousePressed(MouseEvent arg0) { 

     } 

     @Override 
     public void mouseReleased(MouseEvent arg0) { 

     } 
    } 
} 

class GameTile extends JComponent { 

    private int id; 
    private int position; 

    public GameTile(int id, int initpos) { 
     setBorder(BorderFactory.createTitledBorder("" + id)); // !! 
     setLayout(new BorderLayout()); // !! so the added JLabel will show 
     if (id == 0) { 
     this.id = id; 
     this.position = initpos; 
     } else { 
     this.id = id; 
     this.position = initpos; 
     String label = Integer.toString(id); 
     // !! setSize(200, 200); 
     setOpaque(true); // !! 
     setPreferredSize(new Dimension(200, 200)); // !! 
     setBackground(new Color(0, 0, 0)); 
     // !! Label l = new Label(label, Label.CENTER); 
     JLabel l = new JLabel(label, SwingConstants.CENTER); // !! 
     this.add(l); 
     l.setVisible(true); 
     } 
    } 

    public void setPos(int position) { 
     this.position = position; 
    } 

    public int getPos() { 
     return position; 
    } 

    public int getID() { 
     return id; 
    } 
} 

可能還有很多要說的,但這是迄今爲止我所見過的。

+0

我的尊敬+1 – mKorbel 2012-02-05 00:09:23

+0

+1同時考慮'ClickAction擴展MouseAdapter'。 – trashgod 2012-02-05 00:55:13

+1

僅供參考:如果沒有'invokeLater()',這會在我的平臺上大約四次空白。 – trashgod 2012-02-05 01:02:30