2013-05-14 22 views
1

我必须说我尝试了一切,我不明白我的代码有什么问题。 在我的SIView类中,我创建了MainFrame,它使用指定的分辨率(假设为X,Y)来扩展JFrame。 然后,我创建了gamePanel,它的扩展名为JPanel,其分辨率与MainFrame相同,并将其添加到MainFrame。问题是面板的有效分辨率是两倍大(x * 2,y * 2)。这就像面板被拉伸了两倍。JPanel看起来比设置的分辨率大两倍

框架将只显示面板的四分之一(左上四分之一),或者用pack()或mannualy设置大小,除非我将它设置为分辨率的两倍,在这种情况下可以,但这不是一个正确的方法(在计算游戏中的位置时,我必须加倍所有或将它除以2以保持适当的比例)。我甚至尝试过不同的布局管理器,无需任何成功。

这里的主视图类的代码:

public class SIView implements Runnable { 

private final MainFrame mainFrame; 
private final GamePanel gamePanel; 

public SIView(BlockingQueue<SIEvent> eventQueue) { 
    this.eventsQueue = eventQueue; 
    mainFrame = new MainFrame(); 
    gamePanel = new GamePanel(); 

    gamePanel.setVisible(true); 
    mainFrame.getContentPane().add(gamePanel); 
    // mainFrame.pack(); 



@Override 
public void run() { 
    mainFrame.setVisible(true); 
} 

public void init() { 
    SwingUtilities.invokeLater(this); 

} 
    //some code not related 

} 

帧类:

public class MainFrame extends JFrame { 
/** 
* 
*/ 
private static final long serialVersionUID = 6513420589842315661L; 

public MainFrame() { 
    setTitle("Space Intruders"); 
    setSize(new Dimension(SIParams.RES_X, SIParams.RES_Y)); 
    setResizable(false); 
    setLayout(null); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 
} 

面板类:

public class GamePanel extends JPanel { 

/** 
* 
*/ 
private static final long serialVersionUID = 8112087715257989968L; 

private final PlayerShipView playerShip; 
private final ArrayList<SmallEnemyShipView> smallEnemyShip; 
private final ArrayList<LightMissleView> lightMissle; 

public GamePanel() { 
    setPreferredSize(new Dimension(SIParams.RES_X, SIParams.RES_Y)); 
    setMaximumSize(new Dimension(SIParams.RES_X, SIParams.RES_Y)); 
    setBounds(0, 0, SIParams.RES_X, SIParams.RES_Y); 
    setBackground(new Color(0, 0, 0)); 
    setLayout(new OverlayLayout(this)); 

    setDoubleBuffered(true); 
    // TODO 
    playerShip = new PlayerShipView(); 
    smallEnemyShip = new ArrayList<SmallEnemyShipView>(); 
    lightMissle = new ArrayList<LightMissleView>(); 
    this.add(playerShip); 

} 

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
} 

//some code not related 
} 
+3

1)为了更快得到更好的帮助,请发布[SSCCE](http://sscce.org/)。 2)Java GUI可能需要在多种平台上工作,使用不同的屏幕分辨率并使用不同的PLAF。因此,它们不利于组件的准确放置。对于可靠的GUI,改为使用布局管理器或它们的组合,以及用于空白的布局填充和边框来组织组件。 3)不要设置顶级容器的大小。而是布置内容并调用'pack()'。 – 2013-05-14 08:20:24

+0

旁白。那些言辞不含'?'。你有问题吗? – 2013-05-14 08:23:11

+0

要清除它,如果将参数中的硬编码数字(例如100,100和面板50 * 50)放在硬盘上,会发生什么情况?如果它仍然使参数增加一倍,那么面板将会是相同的尺寸,这是否会发生,或者它是否正确设置。如果是这样的话,SIParams可能会做一些奇怪的事情。 – Skillcoil 2013-05-14 08:23:31

回答

2

如果我使用LayoutManager并适当重写getPreferredSize()在代码似乎按预期工作:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

import org.jfree.ui.OverlayLayout; 

public class SIView implements Runnable { 

    public static interface SIParams { 

     int RES_X = 500; 
     int RES_Y = 400; 
    } 

    public static class GamePanel extends JPanel { 
     public GamePanel() { 
      setBackground(new Color(0, 0, 0)); 
      setLayout(new OverlayLayout()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(SIParams.RES_X, SIParams.RES_Y); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
     } 

     // some code not related 
    } 

    private JFrame mainFrame; 
    private GamePanel gamePanel; 

    @Override 
    public void run() { 
     mainFrame = createMainFrame(); 
     gamePanel = new GamePanel(); 
     mainFrame.getContentPane().add(gamePanel); 
     mainFrame.pack(); 
     mainFrame.setVisible(true); 
    } 

    private JFrame createMainFrame() { 
     JFrame frame = new JFrame(); 
     frame.setTitle("Space Intruders"); 
     frame.setResizable(false); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     return frame; 
    } 

    public void init() { 
     SwingUtilities.invokeLater(this); 

    } 

    // some code not related 

    public static void main(String[] args) { 
     new SIView().init(); 
    } 

} 

我也放弃了MainFrame类,因为它不需要在这种情况下延长JFrame

+0

不幸的是,效果是一样的,我仍然可以将我的船置于RES_Y和RES_X范围内的框架之下。我可能没有足够的解释。帧大小是完美的,它是超出帧边界的面板。是的,我相信这不是船运动的问题,因为我显示了它的位置,并且它保持在给定值内。 – Muniu 2013-05-14 14:28:38

+0

它的行为像面板上的像素表示不是1x1而是2x2。 – Muniu 2013-05-14 14:29:40

+0

@MichałMuniuMajczak_And是的,我相信这不是船运动的问题_我其实认为你的问题在于你没有向我们展示的东西。我真正确定的是,我上面提供的代码没有问题。考虑使用[SSCCE](http://sscce.org)更新您的代码。问题可能出现在你的'LayoutManager'或你的'paintComponent'中。根据您迄今提供的信息,没有人能够为您提供更多帮助。 – 2013-05-14 15:04:35

0

我刚刚解决了一切:D但我必须说我感到很蠢。问题在于绘制我的组件,在paintcomponent()方法中,我在相对位置上绘制矩形,同时相对更改组件位置。这给了2xtimes移动等等的效果,因为当组件移动时,矩形也移动了。我想我有很多要了解Swing;)抱歉,所有这些麻烦;)

PS。除了在所有事情之后使用pack()方法外,我不必更改Panel/Frame类中的任何内容。