2010-06-15 2 views
1

제 질문은 스윙 프로그래밍과 관련이 있습니다. 부모 패널 (구성 요소 a)에서 제거하고 구성 요소 a의 부모 (구성 요소 b) 중 하나에 추가하여 구성 요소 (구성 요소 x)를 확대하고 싶습니다. 그 전에는 b의 모든 구성 요소에서 setVisible (false)을 호출합니다. 그 후에 나는 이것을 b에서 제거하고 a를 추가하여 이것을 다시 만들고 싶습니다.이동 후 구성 요소의 크기를 조정할 수 없습니다.

이후 모든 구성 요소의 크기를 조정할 수 없습니다.

왜 그럴까요?

쉬운 예 : 그 후

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTabbedPane; 

public class SwingTest { 

    private static ViewPanel layer1; 
    private static JFrame frame; 
    private static JTabbedPane tabbedPane; 
    private static ViewPanel root; 

    public static void main(String[] args) { 
     frame = new JFrame(); 
     frame.setLayout(new BorderLayout()); 
     frame.setMinimumSize(new Dimension(800, 600)); 

     root = new ViewPanel(); 
     root.setBackground(Color.blue); 
     root.setPreferredSize(new Dimension(400, 600)); 
     root.setLayout(new BorderLayout()); 
     root.add(new JLabel("blue area")); 

     layer1 = new ViewPanel(); 
     layer1.setBackground(Color.red); 
     layer1.setPreferredSize(new Dimension(400, 600)); 
     layer1.setLayout(new BorderLayout()); 

     tabbedPane = new JTabbedPane(); 
     tabbedPane.add("A", new JLabel("A label")); 
     tabbedPane.setPreferredSize(new Dimension(400, 600)); 

     layer1.add(tabbedPane); 

     root.add(layer1); 
     frame.add(root, BorderLayout.NORTH); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 

     Thread t = new Thread() { 

      @Override 
      public void run() { 
       try { 
        Thread.sleep(8000); 
        System.out.println("start"); 
        for (Component c : root.getComponents()) { 
         c.setVisible(false); 
        } 
        layer1.remove(tabbedPane); 
        root.add(tabbedPane); 

        Thread.sleep(8000); 

        root.remove(tabbedPane); 
        layer1.add(tabbedPane); 

        for (Component c : root.getComponents()) { 
         c.setVisible(true); 
         c.repaint(); 
        } 
       } catch (InterruptedException e) { 
        //... 
       } 
      } 
     }; 
     t.start(); 
    } 
} 
+0

서식있는 코드; 잘못된 경우 되돌려주십시오. 'ViewPanel'가 없습니다. – trashgod

답변

1

모든 구성 요소는 더 이상 크기를 조정할 수 없습니다.

나는 LayoutManager의 선택이 효과를 가리는 것으로 생각합니다. 일반적으로 event dispatch thread에 GUI를 구축하는 것이 좋습니다. sleep()을 사용하여 해당 스레드를 차단하는 것은 좋지 않습니다. 이 대체 예제에서는 javax.swing.Timer을 사용하여 타이머의 actionPerformed() 메서드에서 주기적으로 내용을 변경합니다.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTabbedPane; 
import javax.swing.Timer; 

public class SwingTest implements ActionListener, Runnable { 

    private JFrame frame; 
    private ViewPanel root; 
    private ViewPanel layer1; 
    private JTabbedPane tabbedPane; 
    private Timer t = new Timer(1000, this); 
    private boolean remove = true; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new SwingTest()); 
    } 

    private static class ViewPanel extends JPanel { 

     public ViewPanel(Color color) { // default FlowLayout 
      this.setPreferredSize(new Dimension(400, 500)); 
      this.setBackground(color); 
     } 
    } 

    @Override 
    public void run() { 
     frame = new JFrame(); // default BorderLayout 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setPreferredSize(new Dimension(600, 600)); 
     root = new ViewPanel(Color.blue); 
     root.add(new JLabel("Blue area")); 
     layer1 = new ViewPanel(Color.red); 
     tabbedPane = new JTabbedPane(); 
     tabbedPane.add("A", new JLabel("A label", JLabel.CENTER)); 
     tabbedPane.setPreferredSize(root.getPreferredSize()); 
     layer1.add(tabbedPane); 
     root.add(layer1); 
     root.add(new JLabel("Blue area")); 
     frame.add(root, BorderLayout.CENTER); 
     frame.pack(); 
     frame.setVisible(true); 
     t.start(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (remove) { 
      for (Component c : root.getComponents()) { 
       c.setVisible(false); 
      } 
      layer1.remove(tabbedPane); 
     } else { 
      layer1.add(tabbedPane); 
      for (Component c : root.getComponents()) { 
       c.setVisible(true); 
      } 
     } 
     remove = !remove; 
    } 
} 
+0

물론이 변경을 수행하는 스레드는 사용자 상호 작용을 대체합니다 (탭을 두 번 클릭). 그럼에도 불구하고 타이머를 사용하는 것이 좋습니다. 누락 된 ViewPanel 클래스를 JPanel로 대체 할 수 있다는 점을 잊어 버렸습니다. – DME