2013-12-23 66 views
1

一直在尝试通过各种布局/零点和其他方法转换乐趣,试图让我的背景图像完美地适合我的框架,而没有令人讨厌的空白,我迄今还未能清楚。每一次尝试都会导致更大的差距。如果布局设置为左侧,则图像不可避免地会填满左侧的空白,但会扩大右侧的空白,最后一次尝试通过将图像添加到框架直接填充它,但导致屏幕上的其他元素不再接收重绘调用Java框架和图像之间的背景差距

enter image description here

在我的游戏设置了一个JFrame的那一刻,创建其扩展JPanel我的游戏系统类,以及游戏系统类创建其处理要么开始屏幕或实际游戏画面元素内部类。在由系统创建的游戏容器类中,背景被绘制。

缩短按下码提取

主类:

public class Test extends JPanel { 

//////////////// 
////Variables // 
//////////////////////////// 
/**/private static Test test; 
/**/private static JFrame stage; 
/**/private static Container CurrentMenu; 
/**/private boolean isRunning = true; //used to state whether game is running 
//////////////////////////////////// 

//////////////// 
// initialize // 
//////////////// 
/**/public static void main(String[] args) { 
/**/stage = new JFrame("Touhou FBE");//creates game window 
/**/stage.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//sets up default handler for closing window 
/**/test = new Test();//creates an object of our game 
/**/stage.getContentPane().add(test);//add game object to frame 
/**/stage.pack(); 
/**/stage.setVisible(true);//sets frame to visible 
/**/stage.setResizable(false); 
/**/test.Game_loop(); 
/**/} 
//////////////////////////// 

///////////////// 
// constructor // 
///////////////// 
/**/public Test(){ 
/**//////////////////////////////// 
/**/// create starting game menu // 
/**////////////////////////////////   ////////////////// 
/**/CurrentMenu = new Container(this,stage);  // swap GameMenu with GameContainer to be able to see difference with painting 
/**/this.add(CurrentMenu);     ////////////////// 
/**/} 
/////////////////////// 


    //////////////////////////////////////////// 
    // Game loop which manages object updates // 
    //////////////////////////////////////////// 
    /**/public void Game_loop(){ 
    /**/while (isRunning) { 
    /**/test.repaint(); 
    /**/} 
    /**/} 
    ///////////////////////////////////////////////// 

    ///////////////////////////////// 
    // Rendering canvas for images // 
    ///////////////////////////////// 
    /**/public void paint(Graphics g) { 
    /**/super.paint(g); //Refresh Panel 
    /**/} 
    /////////////////////////////////////////////////////// 

容器类:

////////////////////////// 
// game container class // 
////////////////////////// 
/**/public class Container extends JPanel{ 
/**/  
/////////////// 
//Variables // 
/////////////// 
/**/public Test Game; 
/**/public JFrame stage; 
/**/private Image img; 

//////////////// 
//Constructor // 
//////////////// 
/**/public Container(Test game, JFrame Stage){ 
/**/Game = game; 
/**/stage = Stage; 
/**/img = (new ImageIcon("resources/background.png").getImage()); 
/**/Dimension size = new Dimension(700, 400); 
/**/setPreferredSize(size); 
/**/setMinimumSize(size); 
/**/setMaximumSize(size); 
/**/setLayout(null); 
/**/setSize(size); 
/**/} 
/**/  
//////////////////////////// 

////////////////// 
//Paint sprite // 
////////////////// 
/**/public void paintComponent(Graphics g) { 
/**///super.paint(g); 
/**/g.drawImage(img, 0,0, this); 
/**/} 
//////////////////////////////////// 
} 

在方案和实施例中使用的图像(重命名为背景) enter image description here http://img716.imageshack.us/img716/6410/seq6.png

目前我已经达到了如果必须的时候,我会留下差距,因为它不会影响整个游戏,但是它让我感到非常糟糕,并且每次尝试交换布局,消除hgap/vgap ,迫使图像的位置或后续教程导致没有真正的变化。帮助将不胜感激,并有助于确保我再也不会遇到这样的问题。

+0

1)为了更好地帮助越早,张贴[SSCCE](http://sscce.org/)。 2)获取图像的一种方法是通过热链接到[本答案](http://stackoverflow.com/a/19209651/418556)中看到的图像。 –

+0

我喜欢你用////和/ **/ –

+0

组织你的代码的方式我推测这两个类组成了一个SSCCE,因为它实际上是受影响的代码的裸骨,还要学习如何做出更有效的SSCCE。此外,我猜想与图像,这将有助于如果我链接原始背景图像是你问。 – ulthanex

回答

2

调用setResizable更改了框架的大小。

相反,尝试打电话setResizable,再pack,该setVisible

例如...

更新

继续的“填充”是由于TestJPanel延伸并且Container被添加到其中而造成的。

JPanel的默认布局管理器是FlowLayout,默认情况下,默认情况下会在容器周围添加5个像素。

根据您的需求,我要么改变Test布局管理器BorderLayout或者干脆直接添加Container到帧(它使用BorderLayout默认)

比如...

enter image description here

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Image; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class TestResize { 

    private JFrame stage; 
    private Container CurrentMenu; 
    private boolean isRunning = true; //used to state whether game is running 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new TestResize(); 
      } 
     }); 
    } 

    public TestResize() { 
     CurrentMenu = new Container(this, stage);  // swap GameMenu with GameContainer to be able to see difference with painting 
     stage = new JFrame("Touhou FBE");//creates game window 
     stage.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//sets up default handler for closing window 
     stage.add(CurrentMenu); 
     stage.setResizable(false); 
     stage.pack(); 
     stage.setVisible(true);//sets frame to visible 
     // This needs to be started in a separate thread 
//  test.Game_loop(); 
    } 

    public void Game_loop() { 
//  while (isRunning) { 
//   test.repaint(); 
//  } 
    } 

    public class Container extends JPanel { 

     public TestResize Game; 
     public JFrame stage; 
     private Image img; 

     public Container(TestResize game, JFrame Stage) { 
      Game = game; 
      stage = Stage; 
      img = (new ImageIcon("resources/background.png").getImage()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      Dimension size = img == null ? new Dimension(700, 400) : new Dimension(img.getWidth(this), img.getHeight(this)); 
      return size; 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.drawImage(img, 0, 0, this); 
      g.setColor(Color.RED); 
      g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);    
     } 
    } 
} 
+0

+1,您似乎是正确的。至少在我的几个测试运行不同的应用程序的情况下 –

+0

正如你在上面提到的,在这个问题中,通过改变setResizable方法的顺序,左/右和底部间隙现在被填充,但是上面的4-5px间隙是还在那儿。有一件事我通过使用getter发现,实际上图像是在(0,0)处绘制的,所以无论出于何种原因,JFrame上的实际类被分流了5px,这与布局有关? – ulthanex

+0

您错过了一部分代码(测试),因此无法确定。这可能是因为有边框或者测试的首选尺寸大于图像。我不知道你为什么重写paint,因为它没有做任何事情,你应该调用super.paintComponent来确保在绘制图形上下文之前它已经做好了准备...... – MadProgrammer