2016-07-25 3 views
1

私はSwingでGUIを書いています。私はGridBagLayoutを使って複数のJLabelsをグリッドに表示しています(基本的にはチェスボードのようです)。 JLabelの代わりにJLabelの代わりにJLabelから得られた自己ラベルクラスを使用すると、GridBagLayoutはすべてのラベルをJPanelの左上隅に積み重ねます。GridBagLayoutは、Jlabelのカスタムサブクラスを使用するときにラベルをスタックします

私のサブクラスTileLabelが間違っているか、レイアウトと制約を正しく使用していません。私はそのような最小のサブクラスで何が問題になるかを見ることができないので、最後のものと思います。

これは(Lはラベルを表します)、それはJLabelを使用してどのように見えるかです:

(MenuBar) 
L L L L L L L L L 
L L L L L L L L L 
L L L L L L L L L 

これは、(Sが積み重ねられたすべてのラベルを表している)、それはTileLabelを使用してどのように見えるかです:

(MenuBar) 
S 

これは、 JLabelの簡単なサブクラス:

import javax.swing.JLabel; 

public class TileLabel extends JLabel { 
    private static final long serialVersionUID = 6718776819945522562L; 
    private int x; 
    private int y; 

    public TileLabel(int x, int y) { 
     super(); 
     this.x = x; 
     this.y = y; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 
} 

これはGUIクラスですs。レイアウト問題につながるカスタムラベルを使用した3行をマークしました。

import java.awt.Color; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 

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

public class MainGUI extends JPanel { 
    private static final long serialVersionUID = -8750891542665009043L; 
    private JFrame frame; 
    private MainMenuBar menuBar; 
    private TileLabel[][] labelGrid; // <-- LINE 1 
    private GridBagConstraints constraints; 
    private int gridWidth; 
    private int gridHeight; 

    // Basic constructor. 
    public MainGUI(int frameWidth, int frameHeight) { 
     super(new GridBagLayout()); 
     constraints = new GridBagConstraints(); 
     buildFrame(frameWidth, frameHeight); 
     buildLabelGrid(frameWidth, frameHeight); 
    } 

    // Builds the frame. 
    private void buildFrame(int frameWidth, int frameHeight) { 
     menuBar = new MainMenuBar(); 
     frame = new JFrame("Carcasonne"); 
     frame.getContentPane().add(this); 
     frame.setJMenuBar(menuBar); 
     frame.setResizable(false); 
     frame.setVisible(true); 
     frame.setSize(frameWidth, frameHeight); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBackground(new Color(165, 200, 245)); 
    } 

    // Creates the grid of labels. 
    private void buildLabelGrid(int frameWidth, int frameHeight) { 
     gridWidth = frameWidth/100; 
     gridHeight = frameHeight/100; 
     labelGrid = new TileLabel[gridWidth][gridHeight]; // <-- LINE 2 
     for (int x = 0; x < gridWidth; x++) { 
      for (int y = 0; y < gridHeight; y++) { 
       labelGrid[x][y] = new TileLabel(x, y); // <-- LINE 3 
       constraints.gridx = x; 
       constraints.gridy = y; 
       add(labelGrid[x][y], constraints); // add label with constraints 
      } 
     } 
    } 

    // sets the icon of a specific label 
    public void paint(Tile tile, int x, int y) { 
     if (x >= 0 && x < gridWidth && y >= 0 && y < gridHeight) { 
      labelGrid[x][y].setIcon(tile.getImage()); 
     } else { 
      throw new IllegalArgumentException("Invalid label grid position (" + x + ", " + y + ")"); 
     } 
    } 

    // Just to test this GUI: 
    public static void main(String[] args) { 
     MainGUI gui = new MainGUI(1280, 768); 
     Tile tile = TileFactory.createTile(TileType.Road); 
     for (int x = 0; x < 12; x++) { 
      for (int y = 0; y < 7; y++) { 
       gui.paint(tile, x, x); 
      } 
     } 
    } 
} 

問題はどこですか?

+1

*「基本的にチェスボードが好きです」*使用するレイアウトやコンポーネントのヒントについては、[堅牢でサイズ変更可能なスイングチェスのGUIの作成(http://stackoverflow.com/q/21142686/418556)各グリッド・スクエアの 'JLabel'の代わりに' JButton'など)。 –

答えて

1

Override

誤ってJComponent#getX() and JComponent#getY()をオーバーライドしています。このメソッドから返される値は、ではなく、で、レイアウトが内部で設定できる値と一致します(setBounds程度の呼び出しを介して)。これはレイアウトを混乱させる。

(確かに、私は本当にこれが理由ですが、それは可能性があり、そしてそれは一般的に問題であるかどうかチェックをしませんでした!)

+0

それが問題でした。私はIDEでゲッターを生成し、私がこれらのメソッドをオーバーライドしていることを認識しませんでした。助けてくれてありがとう。 – ConveniencePatterns

3

あなたに修正するためのかなりの数のものがありますカスタムラベルで

  1. あなたのメソッド定義:

    public class TileLabel extends JLabel { 
    
        // @Override !!!! 
        public int getX() { 
         return x; 
        } 
    
        // @Override !!!! 
        public int getY() { 
         return y; 
        } 
    } 
    
    コードが、あなたの問題は3つの事に由来します

    JComponentgetX()getY()をオーバーライドしています。これは座標を返すことに責任があります。これはレイアウトを完全に駄目にする。

    paintメソッドに注意してください。同じ名前のメソッドがスーパークラスに存在しますが、引数が異なるためこのケースで保存されます。

  2. ループでタイプミスがあります。gui.paint(tile, x, x)gui.paint(tile, x, y)である必要があります。

  3. メソッドを呼び出す順序が間違っています。最初に、フレームを作成して表示した後、ラベルが付いたパネルを追加して内容を変更し、ラベル内のテキストを変更します。これを逆にする必要があります。

私の提言:

  • は、あなたのpaint方法は、あなたのTileLabelクラスのメンバにすることを確認します。もっと理にかなっている。
  • ラベルがわからない限り、ラベルの作成中にアイコンを設定します。できない場合は、スペース要件を再計算する必要があります。
  • レイアウトを画面のサイズや解像度に応じて決して使用しないでください。それは脆弱なGUIを作る(コメントに書かれているように)。正しいサイズを計算するには、フレームにpack()を使用します。
+0

それは問題でした。ヘルプと追加のヒントをありがとう。 – ConveniencePatterns

+0

@ConveniencePatternsまあ、あなたは1つ以上持っていた:)ところで、あなたのGUIは私のために働いていないサイズが大きすぎると私の画面をオーバーフローするため。私のお勧めを参照してください、そして、私はいくつかのコードを投稿することができます。 – user1803551

+0

それは本当です。問題2は、スタックオーバーフローのコードを短縮したときに発生しました。問題3は間違いなく私が直面する設計ミスです。固定サイズなのでオーバーフローしているのですか? GUIのサイズを動的にすることはTODOリストにあります。 – ConveniencePatterns

関連する問題