java试图了解javax的来龙去脉。摆动
所以我一直在努力掌握javax。荡秋千,我有点麻烦。我正在尝试实现“8拼图”,其中有8个瓷砖和一个开放点设置在一个3x3网格中,当点击开放点附近的瓷砖时,它会与开放点交换空间。我的结构由一个JFrame组成,其中包含一个JPanel,JPanel包含9个作为JComponents的tile,但是只有JPanel渲染,而且这些tile不见踪影。如果您能帮助解决这个问题,我们将不胜感激
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;
}
}
# 1 楼答案
使用JComponent是可以的,但您可能希望将其设置为不透明
还有
setSize(...)
。而是处理preferredSize
。最好重写getPreferredSize()
并返回适当的维度。我在紧要关头使用了^{paintComponent
编辑:我发现你的绘制方法不是真正的覆盖,所以这没关系,很抱歉我的误解李>paint
或paintComponent
打电话。而是调用repaint()
,让JVM为您调用绘制方法编辑:同上,因为这是我对你的代码的误解。在删除和替换JPanel中的组件之后,将希望调用'revalidate()and
repaint()'李>BorderLayout
李>为了便于编译,我将一系列类合并到一个文件中
我已经用
// !!
注释指出了关键的变化可能还有很多话要说,但这是我到目前为止看到的全部