尝试了解 javax.swing 的来龙去脉

发布于 2025-01-03 07:01:38 字数 5970 浏览 4 评论 0原文

所以我一直在尝试获取 javax.swing 的句柄,但遇到了一些麻烦。我正在尝试实现“8 拼图”,其中有 8 个图块和一个在 3x3 网格中设置的空位,当单击空位附近的图块时,它会与空位交换空间。我的结构由一个 JFrame 组成,其中包含一个 JPanel,JPanel 包含 9 个图块作为 JComponent,但是只有 JPanel 呈现,并且图块无处可找到。任何有关此问题的帮助将不胜感激。

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

So I've been trying to get the handle of javax.swing and am having some trouble. I am attempting to implement the '8 puzzle', where there are 8 tiles and one open spot set up in a 3x3 grid, when a tile adjacent to the open spot is clicked it trades spaces with the open spot. My structure consists of a JFrame, which contains a JPanel, and the JPanel contains the 9 tiles as JComponents, however only the JPanel renders, and the tiles are nowhere to be found. Any help with this problem would be greatly appreciated.

    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.*;

Second class

    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

            }   
        }
   }

Tile Class (3rd and final)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦在深巷 2025-01-10 07:01:38

使用 JComponent 很好,但您可能希望将其设置为不透明。

另外,

  • 不要将 AWT(即 Label)与 Swing 组件混合使用。
  • 不要setSize(...)。而是处理 preferredSize。最好重写 getPreferredSize() 并返回适当的维度。我在紧要关头使用过 setPreferredSize(...) ,但冒着惹怒克利奥帕特拉的风险。
  • 如果没有充分的理由(您没有),请勿重写 JComponent 或其任何子级(包括 JPanel)的绘制方法。而是覆盖paintComponent编辑:我发现您的绘制方法不是真正的覆盖,所以这没关系 - 对于我的误解表示抱歉。
  • 您几乎从不直接调用paintpaintComponent。相反,您可以调用 repaint() 并让 JVM 为您调用绘制方法。 编辑:同上,因为这是我对您的代码的误解。在删除和替换 JPanel 中的组件后,您想要调用“revalidate()repaint()”。
  • 如果您给它们边框,您可以看到您的 JComponent 存在并已被考虑。
  • 编辑 2:如果您希望轻松放置和可视化添加到 JComponent 中的组件,则需要为 JComponent 提供布局。在此示例中,我给了我一个 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;
   }
}

可能还有很多话要说,但这就是迄今为止我所看到的。

Use of a JComponent is fine, but you'll probably want to set it to be opaque.

Also

  • Don't mix AWT (i.e., Label) with Swing components.
  • Don't setSize(...). Instead deal with preferredSize. Best to override getPreferredSize() and return an appropriate Dimension. I've used setPreferredSize(...) in a pinch, but at the risk of the wrath of kleopatra.
  • Don't override a JComponent or any of its children's (JPanel included) paint method without good reason (you don't have one). Instead override paintComponent. Edit: I see that your paint method is not a true override, so this is OK -- sorry for the misunderstanding on my part.
  • You almost never call paint or paintComponent directly. Instead you call repaint() and let the JVM call the painting methods for you. Edit: ditto for this as this was my misunderstanding of your code. You will want to call 'revalidate()andrepaint()` after removing and replacing components in your JPanel.
  • You can see that your JComponents are present and accounted for if you give them borders.
  • Edit 2: You will need to give your JComponents a layout if you want to have components added to them easily placed and visualized. In this example I gave mine a BorderLayout.

I've combined a bunch of classes into one file for ease with compilation.
I've indicated key changes with // !! comments.

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

There's probably a lot more to say, but this is all I've seen so far.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文