2012-02-04 45 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