2015-01-17 1 views
0

NetBeans로 Java 프로그래밍을하고 있습니다. 나는 이상한 문제가있다. 클래스 마우스 리스너에서캐스트 구성 요소 [] -> JButton

JButton[] b= (JButton[])Main.p1.getComponents(); 

IDE가 표시되지 않습니다 .. 나는 패널의 getComponents을, 그리고 내가 한 배열하는 JButton (오순절 캐스트) 정도면 (?) 넣어 구성 요소의 배열을 반환 오류. 예를 들면 다음과 같습니다.

b[0].setBackground(Color.yellow); 

출력에 오류가 있습니다.

하지만

JButton b= (JButton) Main.p1.getComponents()[0]; 

b.setBackground(...); 

을 그리고 모든 작동하지만 내가 왜 이해하지 않는 경우. 누군가 제발 설명해 줄 수 있니?

2015-01-18

답장을 보내 주셔서 감사합니다. 변경 배경의 색상뿐만 아니라 오디 닛 (Ordinates)에 대해서도 패널 구성 요소를 가져오고 싶습니다. 같은 시간에 모든 것을 비교할 배열의 모든 단추가 필요합니다. 왜 '단추'의 '구성 요소'를 변환 할 수 있습니까? 패널 램 메모리에있는 버튼에 대한 포인터를 가지고 .. Patryk Dobrowolski 내가 이것을 시도,의에게 감사 :

Button[] button = new Button[Main.p1.getComponents().length]; for (int i = 0; i < Main.p1.getComponents().length; i++) { button[i] = (Button) Main.p1.getComponents()[i]; }

그러나 출력 내가이 오류가 (내가 클래스 버튼의 JButton를 확장 사용) :

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JLabel cannot be cast to Button 

왜 JLabel?

Hovercraft Full of Eels, 고맙습니다. 답변을 드리겠습니다. 배열을 만들고 모든 Button 포인터를 삽입 할 수 있습니다. 하지만 내가 말했듯이 : JPannel에는 배열 포인터가 있는데 .. 내가 그것을 사용할 수있다. 왜 안돼? 대단히 감사합니다! 첫 번째 경우에서 알레산드로 Amedei

+0

[코드 형식] (http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks)를 입력하십시오. – MightyPork

+0

더 많은 코드가 도움이 될 것이며 실제 오류 메시지도 도움이 될 것입니다. 나는 당신이'getComponents()'를 사용하는 것에 대해 걱정하고 프로그램 디자인이 향상 될 수 있는지 궁금해한다. 또한 JButton에 MouseListener를 추가하지 않기를 바랍니다. –

답변

2

, 당신은 컴파일러에 누워있다. 사실 정말 Component의 배열 인 경우

JButton[] b= (JButton[])Main.p1.getComponents(); 

을 명시함으로써 당신은, 당신이 JButton의 배열임을 알고있는 컴파일러를 말하고있다. 따라서 컴파일 타임 오류는 없지만 런타임에 오류가 발생합니다.

다른 경우에는 작동합니다. 이후 Component과 작업하려는 컴파일러에 JButton이라는 사실이 적용됩니다.

+3

@ 원래 포스터 (Alessandro Amedei) :이 대답은 올바른 대답이지만, 다시 한번 여러분의 프로그램의 GUI "view"코드의 구성 요소 구조를 핵심 부분으로 사용하고 있다는 우려를 되풀이합니다 프로그램 논리의 구조 인 "모델"부분을 이해해야합니다. 이는 여러 가지 이유로 위험한 일입니다. 나는 당신의 견해를 모델에 묶는 훨씬 더 객체 지향적 인 방법이 있다고 확신한다. –

1

JComponent의 배열이 JButton의 배열과 같지 않기 때문입니다.

JButton[] buttons = new JButton[components.length]; 
for (int i = 0; i < components.length; i++) { 
    buttons[i] = (JButton) components[i]; 
} 
0

난 당신이 성분의 배열을 반복하여 선택하는 JButton를 추출하기 위해 노력함으로써 당신을 내놓고 있는지 걱정 : 당신은 당신이 마지막으로 버튼의 배열을 얻으려면 루프에서 하나 하나를 캐스팅해야 GUI 구성 요소 구조에 대한 프로그램 논리는 매우 취약한 방법입니다. 구성 요소를 변경하거나 JButton을 보유하고있는 컨테이너를 다른 컨테이너 (즉, 다른 JPanel)에 중첩 시키려면이 수신기와 모든 유사한 수신기를 업데이트해야합니다. 그러면 코드가 매우 약해집니다.

보다 나은 해결책은 리스너를 필요로하는 개별 구성 요소에 추가하는 것입니다. 예를 들어, JButton의 배경을 마우스로 움직이면 JButton의 배경을 노란색으로 변경하려면 각 JButton에 ChangeListener를 추가하고 ChangeEvent의 getSource() 메서드를 통해 관련 버튼을 추출한 다음 버튼의 모델을 테스트하여 롤오버 상태입니다. 예 :

import java.awt.Color; 
import java.awt.GridLayout; 
import javax.swing.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

@SuppressWarnings("serial") 
public class SetButtonBackground extends JPanel { 

    public static final Color ROLLOVER_COLOR = Color.yellow; 

    public SetButtonBackground() { 
     int rows = 5; 
     int cols = rows; 
     setLayout(new GridLayout(rows, cols, 5, 5)); 

     ButtonChangeListener btnChngListener = new ButtonChangeListener(); 
     for (int i = 0; i < rows * cols; i++) { 
     String text = "Button " + (i + 1); 
     JButton button = new JButton(text); 
     button.addChangeListener(btnChngListener); 
     add(button); 
     } 
    } 

    private class ButtonChangeListener implements ChangeListener { 
     @Override 
     public void stateChanged(ChangeEvent e) { 
     JButton btn = (JButton) e.getSource(); 
     ButtonModel model = btn.getModel(); 
     if (model.isRollover()) { 
      if (!btn.getBackground().equals(ROLLOVER_COLOR)) { 
       btn.setBackground(ROLLOVER_COLOR); 
      } 
     } else if (btn.getBackground().equals(ROLLOVER_COLOR)) { 
      btn.setBackground(null); // change back to default state 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     SetButtonBackground mainPanel = new SetButtonBackground(); 

     JFrame frame = new JFrame("Set Button Background"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
}