(Java) JPANEL에서 Jlabel이 나타나거나 사라지는 경우 resize에서만 사라집니다.

StackOverflow https://stackoverflow.com/questions/942883

문제

저는 Java에서 일하고 있으며 JFrame에 JPANEL이 있습니다. 그 jpanel에서, 나는 무엇보다도, 나는 내가 나타나고 마음대로 사라지고 싶은 Jlabel을 가지고있다. 나는 가시성을 true/false로 설정하고 JFrame 및 JPANEL에서 추가 및 제거하려고 시도했으며 온라인을 살펴 보면서 Validate () ing and Revalidate () in ad infinitum을 시도했습니다. 이 문제를 해결하기 위해 무엇을 할 수 있습니까?

도움이 되었습니까?

해결책

일반적으로 setVisible 방법은 스윙 구성 요소를 표시하거나 숨겨지게하기에 충분합니다.

그것이 작동하는지 확인하기 위해 다음을 시도했습니다.

public class Visibility {
  private void makeGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JLabel l = new JLabel("Hello");
    final JButton b = new JButton("Hide Label");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        l.setVisible(false);
      }
    });

    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(l, BorderLayout.CENTER);
    f.getContentPane().add(b, BorderLayout.SOUTH);
    f.setSize(200, 200);
    f.setLocation(200, 200);
    f.validate();
    f.setVisible(true);
  }

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

위의 프로그램은 JButton.

스레딩 문제 일 수 있습니까?

내 다음 의심은 아마도 a였습니다 Thread 그것은 아닙니다 이벤트 디스패치 스레드 (EDT) 즉시 디스플레이에 영향을 미치지 않을 수 있으므로 초기화 후 다음을 추가했습니다. JLabel 그리고 JButton.

Thread t = new Thread(new Runnable() {
  public void run() {
    while (true) {
      b.setVisible(!b.isVisible());

      try {
        Thread.sleep(100);
      } catch (InterruptedException e) { /* Handle exception /* }
    }
  }
});

t.start();

새로운 Thread 달리기, 그것은 토글의 가시성을 변경했습니다. JLabel 100ms마다, 이것은 또한 문제없이 작동했습니다.

스윙 구성 요소를 호출합니다 이벤트 디스패치 스레드 (EDT) 스윙이 스레드 안전하지 않기 때문에 나쁜 것입니다. 나는 그것이 효과가 있다는 것에 약간 놀랐습니다 그것이 작동한다는 사실은 단지 우연 일 수 있습니다.

다시 칠하십시오 JPanel?

만약 JLabel의 가시성은 크기 조정에만 영향을 받고있을 것입니다. 아마도 JLabel 때에 만 그려지고 있습니다 JPanel 다시 칠하고 있습니다.

시도해야 할 한 가지는 전화하는 것입니다 JPanel'에스 repaint 가시성이 있는지 확인하는 방법 JLabel 바뀔 것이다.

그러나이 방법은 상황에 대한 반창고 인 것 같습니다. 주된 원인이 EDT의 실이 GUI를 변경하려고 시도하는 경우. (메모처럼 repaint 메소드는 스레드 안전이므로 Off-EDT 스레드에서 호출 할 수 있지만 의존합니다. repaint 솔루션보다 해결 방법입니다.)

사용해보십시오 SwingUtilities.invokeLater

마지막으로, 아마도 내가 시도 할 것은 SwingUtilities.invokeLater GUI에 영향을 미치려면 EDT와 분리 된 스레드에서 호출 될 수 있으며 (및 호출 해야하는지) 방법.

그래서, 이전 Thread 예제는 다음과 같이 작성해야합니다.

Thread t = new Thread(new Runnable() {
  public void run() {
    while (true) {
      try {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            b.setVisible(!b.isVisible());
          }
        });
      } catch (Exception e1) { /* Handle exception */ }

      try  {
        Thread.sleep(100);
      } catch (InterruptedException e) { /* Handle exception */ }
    }
  }
});

t.start();

GUI 로의 변경이 실제로 별도의 스레드에서 발생하는 경우 읽기를 권장합니다. 수업 : 스윙의 동시성 ~에서 Java 튜토리얼 스윙을 사용하여 잘 행동하는 멀티 스레드 코드를 작성하는 방법에 대한 자세한 정보를 찾기 위해.

다른 팁

setVisible () 또는 제거하는 것이 정상적으로 작동해야합니다.하지만 이벤트 디스패치 스레드에서 수행하고 있는지 확인하십시오. 해당 스레드에서 블록을 실행하기위한 Eventqueue에는 유틸리티 방법이 있습니다.

http://helpdesk.objects.com.au/java/how-do-i-update-my-gui-from-any-any-thread

구성 요소를 다시 배치 해야하는 경우 부모 jpanel에서 Revalidate ()를 호출해야합니다.

문제를 보여주는 예를 게시 할 수 있다면 문제를 살펴볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top