2017-05-21 9 views
-1

私は、サイドプロジェクトの一部としてスイングに基づいて独自のカスタムGUIツールキットを作成しようとしています。私の問題はこれです:私は終了ボタンと最小化ボタンを使用して、最大化するフレームを作成したが、ウィンドウが正しい形式ではありません。ここにフレームクラスのコードを示します。カスタムフレームの再ペイントを正しく行うにはどうしたらいいですか?

package com.SMS.GUI; 

import java.awt.Color; 
import java.awt.Frame; 
import javax.swing.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseListener; 


/** 
* 
* @author Marc 
*/ 
final class SMSFrame extends JFrame implements MouseListener{ 

GUIButton minimizeButton, exitButton; 
JPanel titleBar; 

SMSFrame(int width, int height){ 
    setResizable(false); 
    setUndecorated(true); 
    setSize(width,height); 
    getContentPane().setBackground(Color.decode("#8e44ad")); 
    setVisible(true); 

    minimizeButton = new GUIButton((width-100),0,50,50,"#1abc9c"); 
    exitButton = new GUIButton((width-50), 0, 50, 50, "#d35400"); 
    titleBar = new JPanel(); 

    titleBar.setBackground(Color.decode("#2c3e50")); 
    titleBar.setBounds(0, 0, width, 50); 


    minimizeButton.addMouseListener(this); 
    exitButton.addMouseListener(this); 


    add(titleBar); 
    titleBar.add(exitButton); 
    titleBar.add(minimizeButton); 

} 


@Override 
public void mouseClicked(MouseEvent e) { 
} 

@Override 
public void mousePressed(MouseEvent e) { 
    if(e.getSource() == exitButton){ 
     exitButton.setBackground(Color.decode("#c0392b")); 
    } 

    if(e.getSource() == minimizeButton){ 
     minimizeButton.setBackground(Color.decode("#2ecc71")); 
    } 
} 

@Override 
public void mouseReleased(MouseEvent e) { 
    if(e.getSource() == exitButton){ 
     System.exit(0); 
    } 

    if(e.getSource() == minimizeButton){ 
     super.setState(JFrame.ICONIFIED); 
    } 
} 

@Override 
public void mouseEntered(MouseEvent e) { 
    if(e.getSource() == exitButton){ 
     exitButton.setBackground(Color.decode("#e74c3c")); 
    } 

    if(e.getSource() == minimizeButton){ 
     minimizeButton.setBackground(Color.decode("#16a085")); 
    } 
} 

@Override 
public void mouseExited(MouseEvent e) { 
    if(e.getSource() == exitButton){ 
     exitButton.setBackground(Color.decode("#d35400")); 
    } 

    if(e.getSource() == minimizeButton){ 
     minimizeButton.setBackground(Color.decode("#1abc9c")); 
    } 
} 
} 

これは、カスタムボタンのコードです(私はJPanelsを使用しました)。 パッケージcom.SMS.GUI;

import java.awt.Color; 
import javax.swing.JPanel; 


final class GUIButton extends JPanel{ 
     GUIButton(int x, int y, int width, int height, String hexidecimal_colour){ 
     setBackground(Color.decode(hexidecimal_colour)); 
     setBounds(x, y, width, height); 
    } 

     GUIButton(int width, int height, String hexidecimal_colour){ 
     setBackground(Color.decode(hexidecimal_colour)); 
     setSize(width, height); 
    } 
} 

これは、フレームが最小化する前にどのように見えるかです:

enter image description here

これは後に、それがどのように見えるかです:あなたはあなたをDeiconifyingているとき再描画や再検証しようとすることができ enter image description here

+2

オフトピックのヒント:「#1abc9c」は、16進整数リテラルである「0x1abc9c」に変更できます。文字列をデコードせずに 'new Color(0x1abc9c)'で 'Color'オブジェクトを構築するために使用することができます; – BackSlash

+0

@BackSlash、ありがとう、ありがとう。 –

答えて

3

ただし、最小化ボタンを使用して最大化すると、ウィンドウの形式が正しくありません。

コンポーネントをカスタマイズするには、Swingの動作を理解する必要があります。スイングはlayout managersと一緒に使用するように設計されています。 JFrameのコンテンツペインのデフォルトのレイアウトマネージャーはBorderLayoutです。 JPanelのデフォルトのレイアウトマネージャーはFlowLayoutです。

setSize()メソッドおよび/またはsetBounds()メソッドは、フレームが「再検証済み」になるまで機能します。フレームがサイズに復元されると、各コンポーネントのレイアウトマネージャが呼び出され、すべてのコンポーネントが望ましいサイズで表示されます。彼らはFlowLayoutが使用されているデフォルトのため、

titleBar = new JPanel(); 

ので、「titleBarの」上のボタンは、好みのサイズにリサイズされます。そしてFlowLayoutはボタンをパネルの中央に配置します。

この問題を解決するには、GuiButtonクラスのgetPreferredSize()メソッドをオーバーライドする必要があります。また、すべての場所関連コードを取り除く。位置/サイズを設定するのはレイアウトマネージャの責任です。

ボタンをパネルの右に揃えたいので、レイアウトマネージャを変更してright aligned FlowLayoutを使用する必要があります。レイアウトマネージャを作成するときに使用する適切なコンストラクタについては、FlowLayout APIを参照してください。

add(titleBar); 

これは、フレームが再検証されたときに、このパネルは、今BorderLayoutのルールに基づいて、フレーム全体をカバーする、BorderLayoutCENTERに「タイトルバー」が追加されます。今、タイトルバーのみのフレームの上部に表示されます

add(titleBar, BorderLayout.PAGE_START); 

:あなたが使用することができます。この問題を解決するには

これらの変更を理解するには、Layout ManagersのSwingチュートリアルを読む必要があります。このチュートリアルでは、BorderLayoutFlowLayoutの両方の実例があります。

また、コードの構造を改善するなど、単純なフレームの基本については、How to Make Framesのセクションを読むことをお勧めします。このコード例は、setVisible()が最後の文であるような文の実行順序を示しています。

+0

ありがとう、これは非常に役に立ちます –

+1

@HeronimusLex、それは役に立つ以上に、それは適切な解決策です。あなたが受け入れる答えは、あなたの設計上の問題のいずれにも対処せず、あなたの問題を解決するための強力な解決策にすぎません。 – camickr

+0

あなたはそうです。あなたの答えははるかに多くのコンテキストを持っており、単一の問題の迅速な解決策ではなく、将来のレイアウトに役立ちます。ありがとうございました。 –

0

窓。これを行うには、のWindowListenerを実装し、このメソッドを使用します。

@Override 
public void windowDeiconified(WindowEvent e) { 
    //back to normal you could use this.setState(JFrame.NORMAL); 
    //do stuff here. 
} 

があなたの代わりに super方法の this.setState(JFrame.ICONIFIED);を呼び出すことができるように this.addWindowListener(this);

はまた、あなたがたJFrameを拡張することを忘れないでください。 これは完全な解決策ではありませんが、コンポーネントペインティングの問題です。

+0

変更なし私は恐れています。ありがとう。 –

関連する問題