2016-08-08 11 views
0

내 프로그램의 검사기 패널과 같은 것을 만들므로 런타임에 일부 변수를 쉽게 변경할 수 있습니다. 날 귀찮게하는 inspector screenshotInspector와 유사한 것을 생성하는 동안 JScrollPane 및 GridBagLayout 문제가 발생했습니다.

이 몇 가지 있습니다 나는 여전히 제대로 작동 할 수 없습니다 :

당신이 코드를 넣고 실행

,이 같은 것을 볼 수있다.

  1. 항목이 중앙에 세로로 정렬되어 있습니다 ... 북쪽에 앵커를 설정하려고했지만 동일한 상태로 유지됩니다. 아래 예제 코드에서이 문제를 해결할 수있는 한 줄이 주석 처리되어 있습니다. inspector.finish()이 해결책은 나에게 다소 해커처럼 보입니다. 이것은 빈 JPanel을 패널의 마지막 항목으로 추가하여 아래쪽 영역을 확장하고 구성 요소를 밀어 올리려면 일종의 수직 접착제 역할을합니다. 이 솔루션을 사용하면 런타임에 나중에 더 많은 항목을 관리자에 추가 할 수 없으므로이 방법이 마음에 들지 않습니다.
  2. 인스펙터에 항목을 더 추가하는 경우 (인스펙터를 테스트 데이터로 채우는 n 변수를 변경하여이 작업을 수행 할 수 있음) 스크롤 막대가 나타나지 않고 모든 하위 항목이 화면 밖으로 나오더라도 모두 JScrollPane 내부에 랩핑되었습니다.이 문제를 해결하기 위해 몇 가지 해킹을 시도했지만 제대로 작동하지 않습니다. 그 중 하나는 JPanel의 preferredSize를 하드 코딩 된 치수로 설정하는 것이었지만 패널의 정확한 크기를 알지 못하기 때문에 이것을 좋아하지 않습니다.
  3. 회 전자 단추 중 일부를 누른 다음 콤보 상자 ("choose me"로 표기 됨)를 누르면 단추 뒤의 옵션 뒤에 옵션이 숨겨집니다. 이것은 z-ordering 문제와 비슷합니다. 어쩌면 스윙의 버그 일 수도 있습니다.
  4. 창을 더 작은 크기로 세로 방향으로 조정하면 상단의 항목이 같은 크기를 유지하는 대신 축소됩니다. 항상 일정한 높이로 설정할 수있는 옵션이 있습니까?

잘못된 레이아웃 관리자를 사용하고 있을지 모르지만 선택할 다른 하나를 모르겠습니다. 간단한 그리드 레이아웃에 대해 생각해 보았습니다.하지만이 방법을 사용하면 하나의 항목으로 일부 행을, 다른 항목에 여러 항목을 사용하여 행의 전체 너비 "용량"을 항상 사용하게 할 수 없습니다.

예제 코드 :

import java.awt.*; 
import javax.swing.*; 

public class Test { 

    // Setup test scenario 
    public Test() { 

     // Create window 
     JFrame f = new JFrame(); 
     f.setLayout(new BorderLayout()); 
     f.setSize(800, 600); 
     f.setTitle("Inspector"); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     // Create panel which will be used for the inspector 
     JPanel p = new JPanel(); 
     p.setPreferredSize(new Dimension(200, 0)); 

     // Encapsulate it to the scroll panel so it can grow vertically 
     JScrollPane sp = new JScrollPane(); 
     sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     sp.setViewportView(p); 

     // Create the inspector inside panel p 
     Inspector inspector = new Inspector(p); 

     // Fill the inspector with some test data 
     int n = 3; 
     for (int i = 0; i < n; ++i) { 
      inspector.addTitle("Title"); 
      inspector.addButton("push me"); 
      inspector.addCheckBox("check me"); 
      inspector.addSpinner("Spin me"); 
      inspector.addTextField("Edit me", "here"); 
      inspector.addComboBox("Choose one", new String[]{"A", "B", "C"}); 
      inspector.addSeparator(); 
     } 
     //inspector.finish(); 

     // The inspector will be on the right side of the window 
     f.getContentPane().add(sp, BorderLayout.LINE_END); 

     // Show the window 
     f.setVisible(true); 
    } 

    // Main method 
    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 

    // Inspector class itself 
    private class Inspector { 

     private final JPanel panel; 
     private final GridBagConstraints constraints; 
     private int itemsCount = 0; 

     public Inspector(JPanel p) { 
      panel = p; 
      panel.setLayout(new GridBagLayout()); 

      constraints = new GridBagConstraints(); 
      constraints.fill = GridBagConstraints.HORIZONTAL; 
      constraints.weightx = 0.5; 
     } 

     // Adds component which will span across whole row 
     private void addComponent(Component component) { 
      constraints.gridx = 0; 
      constraints.gridwidth = 2; 
      constraints.gridy = itemsCount; 

      panel.add(component, constraints); 

      itemsCount++; 
     } 

     // Adds descriptive label on the left and component on the right side of the row 
     private void addNamedComponent(String description, Component component) { 
      constraints.gridx = 0; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 1; 
      panel.add(new JLabel(description), constraints); 

      constraints.gridx = 1; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 1; 
      panel.add(component, constraints); 

      itemsCount++; 
     } 

     public void addSeparator() { 
      // (little hacky) 
      addComponent(new JPanel()); 
     } 

     public void addTitle(String title) { 
      addComponent(new JLabel(title)); 
     } 

     public void addButton(String actionName) { 
      addComponent(new Button(actionName)); 
     } 

     public void addCheckBox(String description) { 
      addNamedComponent(description, new JCheckBox()); 
     } 

     public void addSpinner(String description) { 
      addNamedComponent(description, new JSpinner()); 
     } 

     public void addTextField(String description, String text) { 
      addNamedComponent(description, new JTextField(text)); 
     } 

     public void addComboBox(String description, String[] options) { 
      JComboBox<String> comboBox = new JComboBox<>(); 
      ComboBoxModel<String> model = new DefaultComboBoxModel<>(options); 
      comboBox.setModel(model); 

      addNamedComponent(description, comboBox); 
     } 

     public void finish() { 
      constraints.gridx = 0; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 2; 
      constraints.weighty = 1.0; 

      panel.add(new JPanel(), constraints); 
     } 
    } 
} 
+0

개별적으로 질문해야합니다. – sdasdadas

+0

GridBagLayout을 변경했습니다. 실제로는 MigLayout의 모든 레이아웃이 변경되었습니다. 당신이 시도하면 동의 할 수 있습니다. – pstanton

답변

1

당신이 200x0에 sp의 추천 사이즈를 설정하고 있기 때문에 당신이 스크롤 다운 할 수없는 이유. 이 줄을 제거해야합니다.

p.setPreferredSize(new Dimension(200, 0)); 

모든 것이 맨 위가 아닌 가운데에 배치되는 문제. FlowLayout으로 p을두고 각 "섹션"에 자체 패널을 제공하고 해당 패널을 GridBagLayout으로 지정하는 것이 좋습니다. 이렇게하면 더 이상 addSeparator()이 필요하지 않게됩니다.

public class Test { 

    // Setup test scenario 
    public Test() { 

     // Create window 
     JFrame f = new JFrame(); 
     f.setLayout(new BorderLayout()); 
     f.setSize(800, 600); 
     f.setTitle("Inspector"); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     // Create panel which will be used for the inspector 
     JPanel p = new JPanel(); 

     // Encapsulate it to the scroll panel so it can grow vertically 
     JScrollPane sp = new JScrollPane(); 
     sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     sp.setViewportView(p); 

     // Create the inspector inside panel p 
     Inspector inspector = new Inspector(p); 

     // Fill the inspector with some test data 
     int n = 2; 
     for (int i = 0; i < n; ++i) { 
      inspector.addTitle("Title"); 
      inspector.addButton("push me"); 
      inspector.addCheckBox("check me"); 
      inspector.addSpinner("Spin me"); 
      inspector.addTextField("Edit me", "here"); 
      inspector.addComboBox("Choose one", new String[]{"A", "B", "C"}); 
     } 

     // The inspector will be on the right side of the window 
     f.getContentPane().add(sp, BorderLayout.LINE_END); 

     // Show the window 
     f.setVisible(true); 
    } 

    // Main method 
    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 

    // Inspector class itself 
    private class Inspector { 

     private final JPanel panel; 
     private final GridBagConstraints constraints; 
     private int itemsCount = 0; 

     public Inspector(JPanel p) { 
      panel = new JPanel(); 
      p.add(panel); 
      panel.setLayout(new GridBagLayout()); 

      constraints = new GridBagConstraints(); 
      constraints.fill = GridBagConstraints.HORIZONTAL; 
      constraints.weightx = 1.0; 
     } 

     // Adds component which will span across whole row 
     private void addComponent(Component component) { 
      constraints.gridx = 0; 
      constraints.gridwidth = 2; 
      constraints.gridy = itemsCount; 

      panel.add(component, constraints); 

      itemsCount++; 
     } 

     // Adds descriptive label on the left and component on the right side of the row 
     private void addNamedComponent(String description, Component component) { 
      constraints.gridx = 0; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 1; 
      panel.add(new JLabel(description), constraints); 

      constraints.gridx = 1; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 1; 
      panel.add(component, constraints); 

      itemsCount++; 
     } 

     public void addSeparator() { 
      // (little hacky) 
      addComponent(new JPanel()); 
     } 

     public void addTitle(String title) { 
      addComponent(new JLabel(title)); 
     } 

     public void addButton(String actionName) { 
      addComponent(new Button(actionName)); 
     } 

     public void addCheckBox(String description) { 
      addNamedComponent(description, new JCheckBox()); 
     } 

     public void addSpinner(String description) { 
      addNamedComponent(description, new JSpinner()); 
     } 

     public void addTextField(String description, String text) { 
      addNamedComponent(description, new JTextField(text)); 
     } 

     public void addComboBox(String description, String[] options) { 
      JComboBox<String> comboBox = new JComboBox<>(); 
      ComboBoxModel<String> model = new DefaultComboBoxModel<>(options); 
      comboBox.setModel(model); 

      addNamedComponent(description, comboBox); 
     } 

     public void finish() { 
      constraints.gridx = 0; 
      constraints.gridy = itemsCount; 
      constraints.gridwidth = 2; 
      constraints.weighty = 1.0; 

      panel.add(new JPanel(), constraints); 
     } 
    } 
} 
+0

덕분에 유동 레이아웃 내부의 격자 무늬 레이아웃이 고정되었습니다. –