2014-02-09 3 views
0

스윙 레이아웃을 사용하여 현재 창의 크기에서 계산 된 컨트롤 위에 간격을 두려고합니다. 기본적으로 윈도우가 가로로 크기가 조정될 때만 컨트롤이 이동한다는 점을 제외하고는 기본적으로 작동합니다. 세로로 크기를 조정하면 위치가 그대로 유지되고 가로로 1 픽셀 크기가 조정되면 올바른 위치에 스냅됩니다. 아무도 수직으로 크기를 조정할 때 크기 조정이 무시되는 이유를 설명 할 수 있습니까?스윙 레이아웃에서 가로 크기 조절을 무시합니다.

저는 componentResized()가 여전히 수직 크기 변경에서 호출되고 있으며 contentPane.getWidth() 및 contentPane.getHeight()가 여전히 올바른 값을 제공한다는 것을 입증했습니다. 따라서 Dimension의 크기가 올바르게 설정되고 무시됩니다. 그것처럼 나는 contentPane.payAttentionToUpdatesSizesOfYourComponents()에 전화를 걸 필요가 있지만,이 작업을 수행하는 모든 방법을 찾을 수 없습니다. contentPane.invalidate()는 아무 효과가 없습니다.

또한 BorderLayout을 제거하고 contentPane에서 BoxLayout을 직접 설정하면 원하는대로 작동합니다. 그러나이 작은 예제에서는 괜찮습니다.이 문제가있는 실제 창에는 위의 갭이있는 북쪽의 JPanel에있는 일부 구성 요소와 아래에 갭이있는 나머지 다른 JPanel의 일부 구성 요소가 있으며 BorderLayout은 유일한 것입니다 방법을 올바르게 배치 할 수 있으므로이를 제거 할 수 없습니다.

모든 조언이나 제안을 환영합니다!

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 

import javax.swing.Box.Filler; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.WindowConstants; 

public final class ResizeOnlyWorksHorizontally 
{ 
    public static final void main (final String [] args) 
    { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE); 

     final JPanel contentPane = new JPanel(); 
     frame.setContentPane (contentPane); 

     contentPane.setLayout (new BorderLayout()); 

     final JPanel top = new JPanel(); 
     top.setLayout (new BoxLayout (top, BoxLayout.Y_AXIS)); 
     contentPane.add (top, BorderLayout.NORTH); 

     // Put a space, then a label below it 
     final Dimension startSpace = new Dimension (0, 0); 
     final Filler filler = new Filler (startSpace, startSpace, startSpace); 
     top.add (filler); 

     top.add (new JLabel ("Text")); 

     contentPane.addComponentListener (new ComponentAdapter() 
     { 
      @Override 
      public final void componentResized (final ComponentEvent e) 
      { 
       // Just any calc based on contentPane width and height to demo problem 
       final int calc = (contentPane.getWidth() + contentPane.getHeight())/2; 

       // Alter the size of the space above the label 
       final Dimension newSpace = new Dimension (0, calc); 
       filler.setMinimumSize (newSpace); 
       filler.setPreferredSize (newSpace); 
       filler.setMaximumSize (newSpace); 
      } 
     }); 

     frame.pack(); 
     frame.setVisible (true); 
    } 
} 

답변

1

귀하의 질문에 대답하기 위해, 당신은 크기가 레이아웃 매니저가 호출되어 있는지 확인하도록 변경 한 후 다음이 필요합니다

filler.revalidate(); 

를 그가에 대한 전체 접근으로 좋은 해결책이 아니다 그러나 문제가 잘못되었습니다. 그런 구성 요소의 크기를 수동으로 계산해서는 안됩니다. 이것이 레이아웃 관리자의 임무입니다. 따라서 레이아웃 상태를 재고해야합니다. 레이아웃 관리자가 다른 패널을 중첩 할 수 있다는 사실을 잊지 마십시오.

예를 들어 프레임에 변화가 필요한 경우 아마도 BoxLayout을 사용해야하며 시작과 끝 부분에 "접착제"를 추가 할 수 있습니다. 사용 가능한 공간에 따라 컴포넌트의 크기를 조정하는 방법을 제어 할 수 있기 때문에 GridBagLayout을 사용할 수도 있습니다.

자세한 내용은 Layout Managers의 스윙 튜토리얼을 참조하십시오.

+0

대단히 감사에서 밀어 주셔서 대단히 감사합니다 - filler.revalidate() 작동, 나는 내가 제약 조건을 변경하는 동안이었다 내가 없어진 것 같아요 필러의 크기를 강제로 적용하려면 컨테이너를 옮길 필요가 없었습니다. – nigelg

0

당신이 대답을 camickr 아래에 충분히 길게 두지 않을 것입니다 :(나는 이것을 찾은 후에 BorderLayouts의 크기를 변경하는 것과 비슷하지만 동일하지 않은 문제를 발견했습니다. NORTH/SOUTH가 수직 크기 조정에 신경을 쓰지 않는 컨트롤을 배치했습니다. - Java Swing BorderLayout resize difficulties

GridBagLayout을 사용하는 것에 대한 응답을 토대로 시도 했으므로 약간의 노력을 기울여야 작동합니다. 기본적으로 1x5 격자 레이아웃입니다. (강제로 크기를 조정하고, 조절하고, 접착제로 붙이고, 더 많은 컨트롤과 공간을 강제적으로 크기 조정하는 공간을 포함하는) 셀이 포함 된이 셀은 효과가있었습니다.

이와 같은 구성 요소의 크기를 수동으로 계산하면 안됩니다.

내가 수동의 크기를 설정하고있어 유일한 것은 컨트롤 아래 + 위의 차이는, 모든 컨트롤 자신을 내가 함께 레이아웃 매니저 계약을시키는거야.이러한 틈새의 크기는 프레임 크기이지만 프레임 비율을 유지하는 프레임의 배경 이미지와 일치해야합니다. 따라서 테두리 관리자의 너비는 레이아웃 관리자가 알아낼 수있는 것이 아니며 'calc' 내 SSCCE의 비트 위입니다 : 사용자가 창을 넓게 크기를 조정

final int edge = Math.min (contentPane.getWidth()/4, contentPane.getHeight()/3); 
final int imgHeight = edge * 3; 
final int borderSize = (contentPane.getHeight() - imgHeight)/2; 

그렇다면, 거기에 검은 색 테두리는 이미지 + 좌우로, 그리고 borderSize = 0은 사용자가 윈도우 키가로 크기를 조정하는 경우, 이미지 위에 검은 색 테두리가 있고, 컨트롤이 거기에 가지 않도록해야합니다. 그래서 그들은 항상 배경 이미지에 앉아 있습니다.

그러나 올바른 방향 : 빠른 회신

관련 문제