3

Swing を使用して Java で GUI を作成しています。現在、左右の端にウィジェットホルダー(黒いバー)がある「モジュール」(黄色のブロック)を作成しようとしています。各ホルダーには、垂直に並べて表示したい小さなブロックがいくつか保持されます。ここに写真があります:

例のモジュール: ここに画像の説明を入力

ウィジェットホルダーに沿ってマゼンタ/シアンブロックを均等に配置できるようにしたい.

Swing のチュートリアルをいくつか見て、ウィジェット ホルダーのレイアウトを GridLayout と BoxLayout として実装しようとしましたが、どちらもうまくいきませんでした。ここでは 1 列の GridLayout を選択するのが自然なようですが、グリッドを適切に使用する小さなテスト プログラムを作成したにもかかわらず、それを機能させることができないようです。

レイアウト マネージャーが単純な例では機能するのに、この少し複雑なプログラムでは機能しないという事実に、私は戸惑いました。

私のプログラムでは、

  • モジュールはJPanelです
  • ウィジェットホルダー/黒いバーもJPanelです
  • ウィジェット自体 (シアン/マゼンタ ブロック) は現在 JPanel ですが、JLabels と JButtons としても試してみました。マウスイベントをリッスンし、領域と色を持たせたいだけです。

余談ですが、ウィジェットホルダーを左右に配置するためのモジュール自体のレイアウトにも問題がありました。水平の BoxLayout (ホルダー、水平の接着剤、ホルダー) を使用してみましたが、別のときに BorderLayout (いずれかのホルダーに EAST/WEST を使用) を使用してみましたが、何をしてもホルダーは動きませんでした。したくなかったので、 setBounds() を使用してそれらを配置しました。

モジュール クラス (ウィジェット ホルダーは inputLine と outputLine です):

public class Module extends JPanel
{
private static final int MOD_WIDTH  = 86;
private static final int MOD_HEIGHT = 60;

private int screenX, screenY, myX, myY;

private boolean moving = false;

// figure out the layout !
private JPanel inputLine, outputLine;

public Module()
{
    //super(new BorderLayout());

    initPanel();
    initWidgets();
    initMouse();

    setLayout(null);

    list();
}

private final void initPanel()
{
    this.setSize(new Dimension(MOD_WIDTH, MOD_HEIGHT));
    this.setBackground(Color.ORANGE);
}

private void initWidgets()
{
    inputLine   = new JPanel(new GridLayout(0, 1, 5, 5));
    outputLine  = new JPanel(new GridLayout(0, 1, 5, 5));

    inputLine.setBounds (0, 0, 18, 60);
    outputLine.setBounds(68, 0, 18, 60);

    this.add(inputLine);
    this.add(outputLine);

    /* adding IOWidgets to test */
    inputLine.add(new InputWidget());
    inputLine.add(new InputWidget());
    inputLine.add(new InputWidget());

    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());
    outputLine.add(new OutputWidget());

    inputLine.setBackground(Color.BLACK);
    outputLine.setBackground(Color.BLACK);
}


以下は、両方のタイプのウィジェット (input[magenta]、output[cyan]) が派生する抽象 IOWidget クラスです。後で機能が追加されます。

public abstract class IOWidget extends JLabel
{   

    private static final int EDGE_SIZE = 8;

    public IOWidget()
    {
        this.setSize(new Dimension(EDGE_SIZE, EDGE_SIZE));
    }
}


これが InputWidget クラスです。現時点では、追加の機能を追加するまでは OutputWidget と同じなので、これだけを投稿します。

public class InputWidget extends IOWidget
{
    public InputWidget()
    {
        this.setBackground(Color.MAGENTA);
    }
}


私のアプリケーションでは、モジュールはより大きな JPanel に追加されます。モジュールのレイアウトが別の JComponent への追加方法とは無関係であることを願っているので、残りのコードは省略します。

実行時のプログラムは次のようになります。

ここに画像の説明を入力

完全を期すために、単一のモジュールで list を呼び出した場合の出力を次に示します。

rhopkins.honors.Dataflow.Module[,0,0,86x60,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
 javax.swing.JPanel[,0,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
 javax.swing.JPanel[,68,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]
  rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]]

私が間違っていることを知りたいです。また、私は Swing と GUI 開発全般に不慣れであることを認識しているため、スタイル/慣習/その他についての批判は大歓迎です。

4

1 に答える 1

4

nullレイアウトを使用しないでください。

メインパネルはおそらくBorderLayoutである必要があります。メインパネルの西と東にウィジェットホルダーを追加できます。

ウィジェットパネルは、垂直のBoxLayoutを使用できる必要があります。パネルに追加するすべてのウィジェットの前後に接着剤を追加する必要があります。BoxLayoutはコンポーネントのサイズを尊重するため、すべて同じ値を返すには、getPreferredSize()、getMinimumSize()、およびgetMaximumSize()メソッドをオーバーライドする必要があります。このように、パネル内の余分なスペースは、追加する接着剤の間で均等に分割する必要があります。

于 2013-03-14T18:08:29.383 に答える