2017-05-21 8 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 사용). package 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

+2

주제 외 팁 :' "# 1abc9c"'는 16 진수 정수 리터럴 인 '0x1abc9c'로 변경할 수 있습니다. 그런 다음 문자열을 디코딩하지 않고'new Color (0x1abc9c)'를 사용하여'Color' 객체를 생성 할 수 있습니다;) – BackSlash

+0

@BackSlash, 감사합니다. –

답변

3

그러나 최소화 단추를 사용하고 다시 최대화하면 창 형식이 올바르지 않습니다.

구성 요소를 사용자 정의하려는 경우 실제로 Swing의 작동 방식을 이해해야합니다. 스윙은 layout managers과 함께 사용하도록 설계되었습니다. JFrame의 컨텐츠 영역에 대한 기본 레이아웃 매니저는 BorderLayout입니다. JPanel의 기본 레이아웃 관리자는 FlowLayout입니다.

setSize() 및/또는 setBounds() 메서드는 프레임이 "revalidated"될 때까지만 작동합니다. 프레임이 크기로 복원되면 각 구성 요소의 레이아웃 관리자가 호출되고 모든 구성 요소가 원하는 크기로 표시됩니다. 그들이 FlowLayout를 사용하는 기본부터

titleBar = new JPanel(); 

그래서, "제목 표시 줄"의 버튼은 원하는 크기로 조정하세요. 그리고 FlowLayout은 패널 중앙에 버튼을 배치합니다.

이 문제를 해결하려면 getPreferredSize() 메서드를 GuiButton 클래스로 재정의해야합니다. 또한 모든 위치 관련 코드를 제거하십시오. 위치/크기를 설정하는 것은 레이아웃 관리자가 결정합니다.

단추를 패널의 오른쪽에 맞추려면 레이아웃 관리자를 변경하여 right aligned FlowLayout을 사용해야합니다. 레이아웃 관리자를 만들 때 사용할 적절한 생성자에 대해서는 FlowLayout API를 읽으십시오.

add(titleBar); 

이것은 BorderLayoutCENTER에 "타이틀 바를"추가되므로 프레임 재 검증 될 때,이 패널은 이제 BorderLayout의 규칙에 기초하여 전체 프레임을 커버한다.

사용할 수있는이 문제를 해결하려면 다음

add(titleBar, BorderLayout.PAGE_START); 

지금 제목 표시 줄 만 프레임의 상단에 나타납니다.

이러한 변경 사항을 이해하려면 Layout Managers의 스윙 튜토리얼을 읽어야합니다. 이 자습서에는 BorderLayoutFlowLayout의 작동 예가 있습니다.

더 나은 구조의 코드를 포함하여 간단한 프레임 기본 사항은 How to Make Frames 섹션을 읽어 보시기 바랍니다. 예제 코드는 setVisible()이 마지막 문장이되도록 명령문 실행 순서를 보여줍니다.

+0

감사합니다. 매우 도움이됩니다. –

+1

@HeronimusLex, 도움이되는 것 이상으로 적절한 해결책입니다. 여러분이 받아 들인 답은 디자인 문제를 해결하지 못하고 문제를 해결할 때만 쓸만한 해결책입니다. – camickr

+0

당신 말이 맞아요. 귀하의 대답은 훨씬 더 많은 맥락을 가지고 있으며, 한 가지 문제에 대한 빠른 해결책이 아닌, 미래의 레이아웃에 도움이 될 것입니다. 고맙습니다. –

0

당신은 다시 칠하거나 당신을 Deiconifying 때 재 검증을 시도 할 수 있습니다 :

enter image description here

이것은 후 모습입니다 창문. 이렇게하려면있는 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

변경 사항 없음 나는 두려워합니다. 감사. –