2011-10-17 2 views
2

UI 용 Synth를 사용하는 프로젝트에서 일부 사용자 정의 버튼을 구현하려고합니다. 버튼은 신스 XML 설정 파일에서 스타일 설정을 사용해야합니다. 다른 상태 (MOUSE_OVER, PRESSED 등)에 따라 다른 글꼴 색상.스윙 - Synth가있는 사용자 지정 버튼

문제는 일부 버튼에 하위 구성 요소가 추가로 있어야한다는 것입니다. 일부는 하나 이상의 라벨이 필요합니다. 하위 구성 요소가 표준 버튼 하위 구성 요소와 동일한 스타일 설정을 선택하도록합니다.

JButton을 확장하고 paintComponent을 재정 의하여 일부 자식 구성 요소의 그리기 메서드를 호출 할 수 있어야한다고 생각합니다. 나는 그 접근 방법의 몇 가지 측면에 대해 조금 확신 할 수 없다. 어떤 매개 변수를 paintComponent에게 전달해야합니까? 그리고 하위 구성 요소가 올바른 Synth 스타일 설정 (특히 wrt. 상태)을 얻는 방법을 설명합니다.

제쳐두고 : 나는 JPanel을 확장하려고 시도했지만 그 방법으로 어려움을 겪고 있습니다 (여기를 참조하십시오 : JPanel states for Synth).

편집 : 그래서 버튼에 하위 구성 요소를 추가하고 올바르게 렌더링 할 수 있다는 것을 발견했습니다. 이 null을 반환하더라도 JButton.setLayout()을 호출하지 않으면 버튼에 OverlayLayout이 사용됩니다. JButton.setLayout(null)을 호출하면 OverlayLayout이 사용되는 것을 방지하므로 레이아웃을 처리하는 방법입니다.

자식 컨트롤의 스타일을 업데이트하는 몇 가지 다른 방법을 찾고 있습니다. 나중에 자식 컨트롤의 스타일을보고합니다.

+0

그림은 구성 요소의 UI 대리인에 의해 처리됩니다. 이전 [질문]에서 인용 한 @ mKorbel의 [answer] (http://stackoverflow.com/questions/5751311/creating-custom-button-in-java/5755124#5755124) (http://stackoverflow.com/ 질문/7768889/jpanel-states-for-synth/7769341 # 7769341). – trashgod

+0

나는 UI 위임자가 드로잉을 다루는 것을 알고 있지만, Synth UI 델리게이트를 확장하는 것은 기본적으로 불가능하다는 점을 감안할 때,이 고양이를 스킨하는 방법은 여러 가지가 있기를 바란다. – vaughandroid

답변

1

그래서, 경우에 그것은 다른 사람에게 쓸모가있어 여기에 내가 결국 걸린 접근 방식 : 나는 updateStyles을 구현하는 방법이 방법을 발견

class CustomButton extends JButton { 
    CustomButton() { 
     // ... normal button init 

     // Enable absolute positioning of sub-components. 
     setLayout(null); 

     updateStyles(); 

     getModel().addChangeListener(new ChangeListener() { 
      @Override 
      public void stateChanged(ChangeEvent e) { 
       updateStyles(); 
      } 
     }); 
    } 

    private void updateStyles() { 
     // See below for implementation. 
    } 

    private int getSynthComponentState() { 
     // This is basically a copy of SynthButtonUI.getComponentState(JComponent) 
     int state = SynthConstants.ENABLED; 
     if (!isEnabled()) { 
      state = SynthConstants.DISABLED; 
     } 

     if (model.isPressed()) { 
      if (model.isArmed()) { 
       state = SynthConstants.PRESSED; 
      } else { 
       state = SynthConstants.MOUSE_OVER; 
      } 
     } 
     if (model.isRollover()) { 
      state |= SynthConstants.MOUSE_OVER; 
     } 
     if (model.isSelected()) { 
      state |= SynthConstants.SELECTED; 
     } 
     if (isFocusOwner() && isFocusPainted()) { 
      state |= SynthConstants.FOCUSED; 
     } 
     if (isDefaultButton()) { 
      state |= SynthConstants.DEFAULT; 
     } 
     return state; 
    } 
} 

() 메소드 (A) 이름을 변경은 또는 (B) 버튼의 스타일 설정을 하위 구성 요소에 복사 할 수 있습니다. 각 다른 상태로 스타일 설정의 몇 가지 이상을 변경하는 경우

private void updateStyles() { 
    SynthStyle ss = SynthLookAndFeel.getStyle(this, Region.BUTTON); 
    SynthContext sc = new SynthContext(this, Region.BUTTON, ss, getSynthComponentState()); 

    for (Component c : getComponents()) { 
     c.setFont(ss.getFont(sc)); 
     c.setBackground(ss.getColor(sc, ColorType.BACKGROUND)); 
     c.setForeground(ss.getColor(sc, ColorType.FOREGROUND)); 
     // ... and so on if you have other style elements to be changed. 
    } 
} 

접근 (A)는 아마도 더 나은하지만 그것은 수, 다음과 같이 접근 (A)는 매우 간단합니다, 방법 (B)의 작동 다른 여러 가지 스타일에 대해 서로 다른 스타일을 사용하면 다루기 힘들어집니다. 두 가지 스타일 설정 만 변경하는 경우 (예를 들어 현재로서는 색상 만 신경 쓴 경우) 접근 방식 (B)이 가장 적합합니다.

trashgod에서 사용자 지정 UI 대리자 (확장 BasicButtonUI)를 구현하는 방법도 있지만 그 경로를 사용하면 많은 SynthButtonUI를 다시 구현해야 할 것이라고 생각합니다.

+0

+1 게시 코드 – mKorbel