2013-03-14 1 views
3

저는 스윙을 사용하여 Java로 GUI를 작성하고 있습니다. 지금은 왼쪽과 오른쪽 가장자리에 위젯 홀더 (검정색 막대)가있는 "모듈"(노란색 블록)을 만들려고합니다. 각 홀더에는 수직선으로 표시하려는 여러 개의 작은 블록이 있습니다. 다음 그림은 다음자바 스윙 - 원하는 레이아웃을 달성하기가 어렵습니다.

예시적인 모듈 : I 위젯 홀더 따라 마젠타/시안 블록 공간 고르게 할 수있게하려면 enter image description here

.

저는 스윙에 대한 몇 가지 자습서를 살펴본 결과 위젯 홀더의 레이아웃을 GridLayout 및 BoxLayout으로 구현하려고 시도했지만 운이 좋지 않았습니다. 단일 열 GridLayout이 자연스러운 선택 인 것처럼 보이지만 그리드를 적절히 사용하는 작은 테스트 프로그램을 작성했지만 작동하지는 못합니다.

레이아웃 관리자가 간단한 예제에서 작동하지만이 약간 더 복잡한 프로그램에서는 작동하지 않는다는 사실이 나에게 당황 스러웠다. 내 프로그램에서

,

  • 모듈은 JPanel의입니다
  • 위젯 홀더/블랙 바는
  • 위젯 자체 (시안/마젠타 블록) 현재 JPanel의,하지만 난이 'JPanel의입니다 ve는 JLabels 및 JButton으로도 사용하려고했습니다. 난 단지 그들이 마우스 이벤트를 듣고 지역과 색상을 가질 수 있기를 바랍니다.

위젯 홀더를 왼쪽과 오른쪽에 배치하기 위해 모듈 자체의 레이아웃에 문제가 있습니다. 나는 수평 BoxLayout (홀더, 수평 접착제, 홀더)를 사용하여 시도했고, BorderLayout (양쪽 홀더에 대해 동/서쪽을 ​​사용)을 사용해 보았던 또 다른 시간이지만 홀더가 무엇을했는지에 상관없이 나는 움직이지 않을 것이다. 싶지 않았어, 나는 그들을 배치하는 데 setBounds()를 사용했다.

모듈 클래스 (위젯 홀더이다 inputLine 및 outputLine) : 여기

public class Module extends JPanel 
{ 
private static final int MOD_WIDTH = 86; 
private static final int MOD_HEIGHT = 60; 

private int screenX, screenY, myX, myY; 

private boolean moving = false; 

// figure out the layout ! 
private JPanel inputLine, outputLine; 

public Module() 
{ 
    //super(new BorderLayout()); 

    initPanel(); 
    initWidgets(); 
    initMouse(); 

    setLayout(null); 

    list(); 
} 

private final void initPanel() 
{ 
    this.setSize(new Dimension(MOD_WIDTH, MOD_HEIGHT)); 
    this.setBackground(Color.ORANGE); 
} 

private void initWidgets() 
{ 
    inputLine = new JPanel(new GridLayout(0, 1, 5, 5)); 
    outputLine = new JPanel(new GridLayout(0, 1, 5, 5)); 

    inputLine.setBounds (0, 0, 18, 60); 
    outputLine.setBounds(68, 0, 18, 60); 

    this.add(inputLine); 
    this.add(outputLine); 

    /* adding IOWidgets to test */ 
    inputLine.add(new InputWidget()); 
    inputLine.add(new InputWidget()); 
    inputLine.add(new InputWidget()); 

    outputLine.add(new OutputWidget()); 
    outputLine.add(new OutputWidget()); 
    outputLine.add(new OutputWidget()); 
    outputLine.add(new OutputWidget()); 

    inputLine.setBackground(Color.BLACK); 
    outputLine.setBackground(Color.BLACK); 
} 


위젯의 두 종류 (입력 [마젠타, 출력 [시안])로부터 도출 추상 IOWidget 클래스이다. 나중에 기능이 추가됩니다.

public abstract class IOWidget extends JLabel 
{ 

    private static final int EDGE_SIZE = 8; 

    public IOWidget() 
    { 
     this.setSize(new Dimension(EDGE_SIZE, EDGE_SIZE)); 
    } 
} 


다음은 InputWidget 클래스입니다. 지금이 순간, 내가 여분의 기능을 추가 할 때까지 OutputWidget와 동일, 그래서 나는 단지이 하나를 게시합니다 : 내 응용 프로그램에서

public class InputWidget extends IOWidget 
{ 
    public InputWidget() 
    { 
     this.setBackground(Color.MAGENTA); 
    } 
} 


이 모듈은 더 큰 JPanel에 추가됩니다. 모듈의 레이아웃이 다른 JComponent에 추가 된 방법과는 무관하기를 ​​바랄 것이므로 나머지 코드는 생략하겠습니다.여기

는 프로그램이 실행될 때 모습입니다 :처럼 아주 많이 나는 거라고

rhopkins.honors.Dataflow.Module[,0,0,86x60,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 
javax.swing.JPanel[,0,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 
    rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
    rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
    rhopkins.honors.Dataflow.InputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
javax.swing.JPanel[,68,0,18x60,invalid,layout=java.awt.GridLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 
    rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
    rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
    rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 
    rhopkins.honors.Dataflow.OutputWidget[,0,0,8x8,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=8,height=8]] 

:

완성도를 들어

enter image description here

가 여기에 하나의 모듈에 호출 목록의 출력입니다 내가 뭘 잘못하고 있는지 알아. 또한 스윙과 GUI 개발에 익숙하지 않기 때문에 스타일/컨벤션/기타에 대한 비판을 환영합니다.

+2

이것은 10 개의 구성 요소가 포함 된 복잡한 레이아웃입니다. 귀하의 설명에 따라, 당신은 그것에 대해 올바르게가는 것 같습니다. 짧고, 자기 포함되고, 정확하고 실행 가능한 코드가 없으면 내가 더 이상 당신을 도울 수는 없을 것입니다. –

+0

흠. 방금 JFrame을 확장하고 새 Module을 만들고 추가하는 작은 Tester 클래스를 작성했습니다. 이 경우 모듈은 내가 원하는대로 자체 형식을 지정합니다. 또한 창을 최소화하고 다시 가져 오면 모듈이 올바르게 표시된다는 것을 알았습니다. 그래서 다시 그리거나 다시 검증하는 것일뿐입니다. – MIlkywayw

답변

3

null 레이아웃을 사용하지 마십시오.

기본 패널은 BorderLayout이어야합니다. 메인 패널의 WEST와 EAST에 위젯 홀더를 추가 할 수 있습니다.

위젯 패널은 수직 BoxLayout을 사용할 수 있어야합니다. 패널에 추가하는 모든 위젯의 전후에 접착제를 추가해야합니다. BoxLayout은 컴퍼넌트의 사이즈를 존중하므로, getPreferredSize(), getMinimumSize() 및 getMaximumSize() Methods를 오버라이드 (override) 해, 모두 같은 값을 돌려 줄 필요가 있습니다. 이 방법으로 패널의 추가 공간을 추가하는 접착제 사이에서 똑같이 나누어야합니다.

+0

고마워, 널 레이아웃을 사용하고 싶지 않았지만 작동하도록 "강제하는"유일한 방법 인 것처럼 보였기 때문에 나는 그것을 사용했다. 방금 BorderLayout으로 되 돌렸고, 근본적인 문제를 해결 한 후 완벽하게 작동했습니다! 또한 상자 레이아웃 제안에 감사드립니다 - 완벽합니다! 그렇게하면 국경이나 다른 것을 다룰 필요가 없습니다. – MIlkywayw

+0

이 (또는 다른) stackoverflow 질문에 응답하는이 대답 (및 기타 답변)을 받아 들여야합니다. – arcy

+0

완료! 고맙습니다. – MIlkywayw