2016-09-18 15 views
0

私のウィンドウではJFrameundecorated(true)に設定し、上部に自分のカスタムヘッダーがあります(閉じるボタンと最小化ボタン付き)。私が抱いている唯一の問題は、この「カスタムヘッダー」をドラッグするとウィンドウを移動させることです。ヘッダー全体がJPanelにあり、北側のJFrameに追加されます(BorderLayout.NORTH)。私はこのJPanelMouseListenerMouseMotionListenerを追加しましたが、イベントを認識しません。私が仮定できる唯一のことは、レイアウトをどのようにして得たかということです。以下はヘッダーのコードとそれに沿ったビジュアルです。JPanelがフォーカスを失ってリスナーが発砲していない

CODE:

private void addHeader() 
{ 
    headPane = new JPanel(); 
    headPane.setLayout(new BoxLayout(headPane, BoxLayout.LINE_AXIS)); 
    buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2)); 
    buttonPane.setBackground(mouseLineColor); 
    headPane.setBackground(Color.GREEN); 

    Font buttonFont = new Font("", Font.PLAIN, 18); 
    minimize.setFocusable(false); 
    minimize.setPreferredSize(new Dimension(30, 20)); 
    minimize.setMargin(new Insets(0, 0, 0, 0)); 
    minimize.setOpaque(false); 
    minimize.setBorder(null); 
    minimize.setForeground(Color.WHITE); 
    minimize.setOpaque(true); 
    minimize.setFont(buttonFont); 
    minimize.setBackground(buttonColor); 

    quit.setFocusable(false); 
    quit.setPreferredSize(new Dimension(30, 20)); 
    quit.setMargin(new Insets(0, 0, 0, 0)); 
    quit.setOpaque(false); 
    quit.setBorder(null); 
    quit.setForeground(Color.WHITE); 
    quit.setOpaque(true); 
    quit.setFont(buttonFont); 
    quit.setBackground(buttonColor); 

    back.setFocusable(false); 
    back.setPreferredSize(new Dimension(30, 20)); 
    back.setMargin(new Insets(0, 0, 0, 0)); 
    back.setOpaque(false); 
    back.setBorder(null); 
    back.setForeground(Color.WHITE); 
    back.setOpaque(true); 
    back.setFont(buttonFont); 
    back.setBackground(buttonColor); 

    if(screen != GAME_MENU) 
     buttonPane.add(back); 
    else 
     buttonPane.remove(back); 

    buttonPane.add(minimize); 
    buttonPane.add(quit); 

    headTitle = new JLabel("Bouncy Ball Version " + VERSION); 
    headTitle.setBorder(new EmptyBorder(0, 5, 0, 0)); 
    headTitle.setFont(new Font("", Font.BOLD, 14)); 
    headTitle.setForeground(Color.BLACK); 
    headTitle.setBackground(Color.YELLOW); 
    headTitle.setOpaque(true); 
    headTitle.setFocusable(false); 
    headPane.setFocusable(false); 
    buttonPane.setFocusable(false); 

    buttonPane.setBackground(Color.RED); 

    headPane.add(headTitle); 
    headPane.add(Box.createHorizontalGlue()); 
    headPane.add(buttonPane); 

    if(callOnce) 
    { 
     minimize.addActionListener(this); 
     quit.addActionListener(this); 
     back.addActionListener(this); 

     minimize.addMouseListener(this); 
     quit.addMouseListener(this); 
     back.addMouseListener(this); 

     headPane.addMouseListener(this); 
     headPane.addMouseMotionListener(this); 

     callOnce = false; 
    } 

    headPane.setPreferredSize(new Dimension(headPane.getPreferredSize().width, 24)); 
    frame.add(headPane, BorderLayout.NORTH); 
} 

リスナー:

のmousePressed:

Object source = e.getSource(); 
if(source == headPane) 
{ 
    mouseX = e.getX(); 
    mouseY = e.getY(); 
    movingWindow = true; 
} 

MouseDragged:

Object source = e.getSource(); 
if(source == headPane) 
{ 
    if(movingWindow) 
    { 
     int x = e.getXOnScreen(); 
     int y = e.getYOnScreen(); 
     frame.setLocation(x - mouseX, y - mouseY); 
    } 
} 

enter image description here

また、私はheadPaneをクリックすると、JButton sが同様に動作しなくなることを追加します。なぜそれがこれをやっているのかわからない、あるいは答えが本当にシンプルで、ただ愚かであるが、私が試したことは何も働いていない。

私はかなりJavaに新しいので、事前に任意のヘルプに感謝します。

+2

1)すぐに役立つようにするには、コンパイル不可能なコードスニペットではなく、[MCVE]または[短く、自己完結型の正しい例](http://www.sscce.org/)を投稿してください。 2)* ..「お手伝いをしてくれてありがとうございました」*あなたが質問したら助けになるだろう! –

答えて

2

"callOnce"変数は必要ありません。フレームに追加されたフレームとコンポーネントは、クラスの作成時に1回作成する必要があります。 "addHeader()"メソッドを複数回呼び出す場合は、設計上の問題があることをお勧めします。

また、ActionListenersをボタンに2回追加しないでください。

私が抱いている唯一の問題は、この「カスタムヘッダー」をドラッグしたときにウィンドウを移動させることです。

任意のコンポーネントをドラッグできる汎用クラスについては、Moving Windowsを参照してください。通常は、パネル内のコンポーネントをドラッグします。

ただし、クラスには、ウィンドウに追加されたコンポーネントをドラッグしてデスクトップ上のウィンドウをドラッグできる機能もあります。

+0

Moving Windowsクラスは非常に便利で、私が必要としていたことに対して完璧に機能しました。とてもありがとうございます。ヘッダーそのものを追加することについては質問があります。私は "addHeader()"メソッドを複数回呼び出すのは、主に私が持っている戻るボタンのためです。別の画面に移動するたびに、「addHeader()」メソッドを呼び出して、戻るボタンがあるかどうかを判断します。これを行うより良い方法はありますか? – Ryan

+0

あなたが答えることができるかもしれないし、そうでないかもしれないもう一つのことは、Moving Windowsクラスを複数のモニターで動作させる方法ですか? – Ryan

+1

@Ryan、パネル全体を再作成する必要はありません。必要に応じて戻るボタンを有効/無効にすることができます。または、戻るボタンを表示/非表示にすることもできます。私は複数のモニターで遊んだことはありませんので、ComponentMoverを複数のモニターで動作させるには何が必要なのか分かりません。 – camickr

関連する問題