2014-10-16 61 views
0

我即將編程一個小版本的「龐」。但我的JPanels已經有問題了。 Shields的大小從100變爲非常奇怪的10。並且沒有方法改變它的大小! 盾牌也跳到JPanel的中間位置。他們不期望這樣做。在這篇文章的兩個截圖中可以看到。 (Puu.sh)JPanel位置和大小變化怪異

對不起,如果我只是錯過了明顯的東西,但正如我所說,我正在接受培訓。

主要有PSVM()

public class Main { 

public static void main(String[] args) { 
    new Field(); 
} 

} 

場(幀與它的遊戲)

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JFrame; 

public class Field extends JFrame { 

private Room room = new Room(); 

public Field() { 

    this.setSize((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth()/1.5), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight()/1.5)); 
    this.setLayout(null); 
    this.setLocation((int) ((Toolkit.getDefaultToolkit().getScreenSize().getWidth() - (Toolkit.getDefaultToolkit().getScreenSize().getWidth()/1.5))/2), (int) ((Toolkit.getDefaultToolkit().getScreenSize().getHeight() - (Toolkit.getDefaultToolkit().getScreenSize().getHeight()/1.5))/2)); 
    this.getContentPane().setBackground(Color.GRAY); 
    this.setResizable(true); 
    this.setEnabled(true); 
    this.setMinimumSize(new Dimension(1000, 455)); 
    if (getHeight() < 455) { 
     this.setSize(getWidth(), 455); 
    } else if (getWidth() < 1000) { 
     this.setSize(1000, getHeight()); 
    } 

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


    this.add(room); 

    this.setVisible(true); 
    addMouseListener(this); 

    this.addComponentListener(new ComponentAdapter() { 
     public void componentResized(ComponentEvent evt) { 
      room.updateLocation(getSize()); 
     } 
    }); 


} 

} 

import javax.swing.*; 
import java.awt.*; 
public class Room extends JPanel { 


private Shield shieldL = new Shield(0); // LEFT side 
private Shield shieldR = new Shield(1); // RIGHT side 

public Room() { 

    this.setBackground(new Color(122, 197, 205)); 

    this.add(shieldL); 
    this.add(shieldR); 
} 

public void updateLocation(Dimension d) { 
    this.setSize((int) d.getWidth(), (int) (d.getHeight() - (d.getHeight()/5))); 
    this.setLocation(0, (int) (d.getHeight()/10)); 
    shieldL.updateLocation(getSize()); 
    shieldR.updateLocation(getSize()); 
    this.setVisible(true); 

} 
} 

import javax.swing.*; 
import java.awt.*; 

public class Shield extends JPanel { 

private int side = 0; 

public Shield(int s) { //0 = Left | 1 = Right 

    side = s; 
    this.setSize(10, 100); 
    this.setBackground(Color.white); 

} 

public void updateLocation(Dimension d) { //Bug found here 
    System.out.println(getSize());   //Bug seems not to be created here? 
    int xPos; 
    if (side == 0) { 
     xPos = (int) (d.getWidth()/8); 
    } else { 
     xPos = (int) (d.getWidth()/8 * 7 - this.getWidth()/2); 
    } 
    this.setLocation(xPos, (int) (d.getHeight()/2 - (getHeight()/2))); 
    this.setVisible(true); 
} 

} 

他們最終像這樣:,在randome framesize changings切換位置。

http://puu.sh/ceyE0/ef15ee1748.png

http://puu.sh/ceyFN/122174db48.png

謝謝! 朱利安:)

+0

當您發佈的代碼不能爲我們編譯時,我們如何才能找到問題?請發佈[MCVE](http://stackoverflow.com/help/mcve)(並確保它是*最小和可編譯的*)。 – user1803551 2014-10-16 15:38:41

+0

整個代碼:https://gist.github.com/anonymous/1ee36b3ef2da779e2f76 – 2014-10-16 15:41:50

+0

你忽略了我的評論,請再次閱讀,請包括鏈接,如果不清楚,然後問。針對SO的問題預計會有一些標準。 – user1803551 2014-10-16 15:45:09

回答

0

Shield,行

setSize(10, 100); 

改變

setPreferredSize(new Dimension(10, 100)); 

不要使用setSize方法,它們內部調用。

編輯:

嘗試僅僅這2類:

public class Field extends JFrame { 

    private Room room = new Room(); 

    public Field() { 

     //Mock panel 
     JPanel filler = new JPanel(); 
     filler.setOpaque(false); 

     getContentPane().setBackground(Color.GRAY); 
     getContentPane().add(filler, BorderLayout.PAGE_START); 
     getContentPane().add(room); 

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setMinimumSize(new Dimension(1000, 455)); 
     setLocationRelativeTo(null); 
     pack(); 
     room.init(); 
     setVisible(true); 
    } 
} 

public class Room extends JPanel { 

    private static int leftWidth = 100; 
    private static int leftHeight = 100; 
    private static int leftX; 
    private static int leftY; 

    private static int rightWidth = 100; 
    private static int rightHeight = 100; 
    private static int rightX; 
    private static int rightY; 

    public Room() { 

     setBackground(new Color(122, 197, 205)); 
    } 

    void init() { 

     leftX = getWidth()/8; 
     leftY = getHeight()/2 - leftHeight/2; 
     rightX = getWidth() * 7/8; 
     rightY = getHeight()/2 - rightHeight/2; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 

     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.WHITE); 
     g2d.fillRect(leftX, leftY, leftWidth, leftHeight); 
     g2d.fillRect(rightX, rightY, rightWidth, rightHeight); 
    } 
} 
+0

'Room'的'init()'中的'getWidth()'獲得了Frame的寬度,對吧?但是它在哪裏得到參考? #neverusedinit #googletellsmecomplicatedstuff – 2014-10-16 17:53:19

+0

@JulianE。由於呼叫來自'Room'內部,因此它獲得'room'的寬度。 – user1803551 2014-10-16 17:56:19

+0

好的,所以這個方法是預定義的並且總是給出那個引用? – 2014-10-16 17:59:07

0

你的問題是,你不明白布局管理器以及它們如何治療或使用的setSize,有必要對setPreferredSize ,setMinimumSize和setMaximumSize方法。

對於您的面板類,setSize不起作用,因爲當您創建JPanel時,它使用FlowLayout作爲默認佈局管理器,並且佈局管理器忽略由setSize方法指定的大小。您必須以某種組合(至少一個)組合使用其他人。您可以使用setSize的唯一方法是默認情況下不分配佈局管理器的組件或通過調用setLayout(null)的組件。這被稱爲絕對定位。這是你必須指定每個組件的位置和大小的地方。

搜索Java Swing教程並搜索「如何使用佈局管理器」。如果您使用的是Swing,那麼您理解這一概念是有說服力的,因爲不同的佈局管理器遵守不同的大小和定位規則。例如,流佈局和網格佈局的行爲非常不同。

當然,絕對定位是一種痛苦,但它是您提供絕對控制Swing組件尺寸和位置的方法。但理解佈局管理器並正確使用佈局管理器可以爲您節省大量時間來創建GUI。

*****更新信息***** 調整框架大小的問題是由於您的面板使用了FlowLayout。該佈局管理器允許重新佈置面板中的組件。有幾種方法可以解決這個問題。一種是使用佈局管理器,在調整大小時保留組件的寬高比。例如,GridLayout將組件分解爲網格。如果你想到棋盤,它是一個8x8的網格。如果你使面板成爲一個完美的正方形,那麼所有的網格將是相同大小的正方形。調整面板大小時,面板的縱橫比(不一定是內部組件)將保持不變。另一種方式,也許你在學習如何正確使用佈局管理器時是最好的選擇,是防止重新調整框架大小。

+0

好的,那麼我會嘗試和評論,如果我沒有找到解決方案 – 2014-10-16 16:52:05

+0

只要記住,只有使用setSize方法,如果您使用絕對定位。確保這種情況的最佳方式是(即,您不確定哪些組件設置了默認佈局管理器)是在每個組件類上調用setLayout(null)。並且,還了解pack();方法起作用。如果組件的邊界設置不正確,它將無法按預期工作。 – hfontanez 2014-10-16 17:27:37