2012-10-05 4 views
3

와 스윙 구성 요소에 유틸 클래스를 만드는 방법 나는의 Utils 클래스가되도록 :자바 스윙 - 제네릭

public static void setComboBoxDefaultWidth(JComboBox cb) 
{ 
    cb.setPrototypeDisplayValue("mmmmmmmmmmmmmmmmmmmmmmmmmm"); 
} 

문제는이 컴파일러 경고 결과이다 :

JComboBox의가있다 원시 타입. 제네릭 형식 JComboBox에 대한 참조는 매개 변수화해야합니다.

제네릭을 매개 변수화하는 방법을 모르므로 호출하는 메서드와 함수가 모두 작동합니다 (컴파일러 오류 없음). 내가 하나가 아니라 둘 다 어떤 이유로 든 ...

+1

당신은 "알 수없는"남아있을 것입니다 때문에 많은 추가로 얻을 수 없겠죠 공공 정적 무효 setComboBoxDefaultWidth'같은 (JComboBox에 CB)' – MadProgrammer

+0

@MadProgrammer를 사용할 수 있으므로 당신은 setPrototypeValue를 호출 할 수 없었다. –

+0

@GuillaumePolet 당신이 맞습니다 (물론),'setPrototypeDisplayValue'가''을 가지고 있다는 것을 깨닫지 못했습니다. – MadProgrammer

답변

0

JComboBox를 모든 유형의 일반으로 유지하려는 경우에는 사용할 수 없습니다.

1

당신의 JComboBox의 항상 문자열이 포함 된 경우를 해결할 수 있습니다, 구문은 다음과 같습니다

public static void setComboBoxDefaultWidth(JComboBox<String> cb) 
{ 
    cb.setPrototypeDisplayValue("mmmmmmmmmmmmmmmmmmmmmmmmmm"); 
} 
+0

잘못되었습니다! setPrototypeDisplayValue도 매개 변수화됩니다. '?' 와일드 카드를 사용하면 setPrototypeValue를 호출 할 수 없습니다. 이 메소드를 호출하려면 알려진 유형이어야합니다. –

4

사실은 JComboBox이 Java6 만에 일반적인 아니었다이다 디자인에 결함이 있었기 때문에 (단지 getItemAt()이 수동으로 캐스팅해야했던 Object 유형을 반환했기 때문에) 일반화되었습니다.

방법이 당신이 그것을 호출하는 특정 클래스의 특정 인스턴스를해야하며, 유형 콤보 상자 선언 하나에 해당해야한다는 것을 의미

public void setPrototypeDisplayValue(E prototypeDisplayValue) 

로 선언 :

public void setComboBoxDefaultWidth(JComboBox<String> cb) { 
    cb.setPrototypeDisplayValue("mmmmmmmmmmmmmmmmmmmmmmmmmm"); 
} 

String을 메서드에 전달하므로 JComboBoxString이 있어야하므로이 작업을 수행해야합니다.

위의 솔루션은 호출하려는 메서드에 제네릭 형식의 매개 변수가 필요한 경우 수행해야하는 작업입니다. 그렇지 않으면 당신은 그것을 지정할 수 없다. (얼마나 많은 표적을 넣지 않고) 당신은 와일드 카드를 사용해야 만한다. ? 존재한다 : 어떤 메소드가 어떤 종류의 generic 클래스인지 신경 쓰지 않는다면, JComboBox는 유형이 무엇인지에 대한 걱정없이 제네릭 형식이 있습니다

public static void setComboBoxDefaultWidth(JComboBox<?> cb) { 
    cb.setLightWeightPopupEnabled(true); 
} 

구문 <?>은 그대로 알 수없는 유형이 매개 변수가 참으로 알 수없는 유형 항목의 JComboBox을 의미합니다.

+1

잘못되었습니다! setPrototypeDisplayValue도 매개 변수화됩니다. '?' 와일드 카드를 사용하면 setPrototypeValue를 호출 할 수 없습니다. 이 메소드를 호출하려면 알려진 유형이어야합니다. –

+0

죄송합니다. setLightWeightPopupEnabled에 제네릭 매개 변수가 있다는 것을 실제로 눈치 채지 못했습니다. 나는 그것이 효과적인 GUI 레이아웃과 관련되어 있기 때문에 문자열을 필요로한다는 것을 믿었습니다. (그것에 대해 생각해보십시오. 실제로 E를 전달할 필요가 없습니다. 단지 프로토 타입이기 때문에 String이 충분할 것입니다). 이것은 실제로 특정 상황에서 더미 객체를 생성하도록 강요하므로 설계 방법이 마음에 들지 않습니다. – Jack

+0

UI 요소에 제네릭을 추가해야하는 이유는 틀림 없습니다. 대부분의 경우 실재 사례에 대해서는 쓸모가 없습니다. 프로토 타입 값에 관해서는, 그것은 그것이 설계된 방식이고 실제로 정상입니다. 당신은 레이블/문자열을 렌더링하는 것에 대해서만 생각하지만, 콤보 박스는 String뿐만 아니라 무엇이든 렌더링하는데 사용될 수 있습니다. 아이콘, 복잡한 구성 요소 등이 될 수 있습니다. 이러한 상황에서 String을 전달하는 것은 의미가 없습니다. 동일한 객체를 전달하면 렌더러를 다시 사용하고 디스플레이의 일관성을 보장 할 수 있습니다. 프로토 타입 값을 설정할 수도 없습니다. 그게 제가하는 일입니다. –

2

프로토 타입 표시 값은 JComboBox를 입력하는 것과 같은 유형이어야합니다.

JComboBox<E>이 주어지면 형식을 알고있는 경우에만 setPrototypeDisplayValue(E prototypeDisplayValue) 메서드를 호출 할 수 있습니다. 따라서 와일드 카드 (?)를 사용하는 것은 옵션이 아닙니다. 당신이 할 수

public static void setComboBoxDefaultWidth(JComboBox<String> cb) { 
    cb.setPrototypeDisplayValue("mmmmmmmmmmmmmmmmmmmmmmmmmm"); 
} 

또 다른 옵션이 될 것이다 :

public static <E> void setComboBoxDefaultWidth(JComboBox<E> cb, E prototypeValue) { 
    cb.setPrototypeDisplayValue(prototypeValue); 
} 

그러나 그것은 무의미 현재, 당신이 할 수있는 모든 것입니다.

+0

[있다 ... 또는 뭔가 놓치지 ??? ???] (http://stackoverflow.com/questions/11070688/wildcard-for-objectstring-in-java6) – mKorbel

+0

@mKorbel 나는 내가 해야할지 잘 모르겠다. 귀하의 의견과 제가 지적한 링크를 이해하십시오. 어쨌든, 당신이 잭의 대답을 시도하면, 그것이 효과가 없다는 것을 즉각 알게 될 것입니다. '?'사용 의미 : 주어진 유형 만 포함하는 JComboBox가 있지만 어떤 것이 있는지 전혀 알지 못합니다. 따라서 Integer, Boolean, String 등이 포함될 수 있습니다. 예를 들어 Integer를 포함하는 경우 setPrototypeValue ("mmmmmmmmmmmmm")를 호출하는 것이 잘못되었습니다. 결국 형식화 된 ListCellRenderer는 ClassCastException : "String을 Integer로 캐스트 할 수 없음"을 던질 수 있습니다. –

+0

스윙 JComponents에 대한 Generics의 구현이 올바르지 않다고 생각합니다. 모델에 대한 간단한 구현을 볼 수 있지만 나머지 (상속 및 중첩)는 다루지 않습니다 ... Sun API에 대해 복잡한 대답을 줄 수는 없습니다.), 비교하려고 시도하지 않기 때문에 JavaFX +1에서 ComboBox에 대한 API를 확인하여 나머지 답변을 여기에서 확장하십시오. – mKorbel