2009-05-29 4 views
0

JLabel을 확장하는 사용자 정의 클래스가 있습니다. 해당 클래스의 특정 인스턴스에 대해 왼쪽에 텍스트 간격을 추가하고 싶습니다. 이 JLabel의 배경을 설정할 때 간격이 필요합니다. 텍스트가 색상이있는 배경 가장자리 바로 옆에서 튀어 나오게하고 싶지 않습니다. 나는 주위에 꽤 낚시질하고 (페인트 함수 내에서)이 구현 :setBorder JLabel에서 페인트 문제가 발생합니다.

이는 내가 원하는 간격을 추가하는에 작업 표시
if (condition) { 
    bgColor = Color.red; 
    setBackground(bgColor); 
    setOpaque(true); 
    // This line merely adds some padding on the left 
    setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); 
} 
else { 
    setOpaque(false); 
} 

은, 그러나한다는 점에서 불행한 부작용이는 휴식을 표시했다 나머지 모든 응용 프로그램을 다시 칠해 보면 ... 해당 특정 구성 요소 만 다시 칠해지고 나머지는 응용 프로그램이 아닌 것처럼 보입니다. 결국 setBorder 호출에 이르기까지 추적했습니다 ... 모든 종류의 테두리를 설정하면 동일한 깨진 동작이 발생합니다. 우리는 두 가지 버전의 응용 프로그램을 가지고 있습니다. 하나는 Java 1.5에서 실행되고 다른 하나는 Java 1.6에서 실행되는 응용 프로그램입니다. Java 1.6 버전은 Java 1.5 버전이 올바르게 작동하지 않는 것처럼 보입니다. 이전 버전을 Java 1.6으로 업그레이드 할 수는 없습니다 ... Java 1.5에서 작동하는 것이 필요합니다.

setHorizontalTextPosition(JLabel.CENTER); 

을 그리고 그 또한 정확하게 같은 방법으로 재 도장을 깰 나타납니다 또한, 나는 (그냥 모습을 확인하려면 다음을 참조하십시오)이 시도. 우리 응용 프로그램의 소스를 살펴 보았지만 테두리를 설정 한 다른 영역 (빈 경계선 포함)을 발견했지만 JLabel (패널, 단추 등)에서는 찾을 수 없었습니다. 누구도 전에 이런 걸 본 사람 있어요? 그것을 고치는 방법을 아십니까? 또는 내가 버그를 해결할 수있는 간격을 얻기위한 또 다른 방법이 있을까요? 감사.

+0

이 코드를 어디에서 불러들입니까? 그것이 생성자에 있다면, 상황은 괜찮을 것이다 ... paintComponent() 또는 그와 비슷한 것이면, 당신이 묘사하고있는 종류의 문제에 부딪 힐 수도있다. –

답변

3

문제는 페인트 메서드 내에서 해당 코드를 호출한다는 것입니다. 스윙 페인팅 파이프 라인에서 원치 않는 루프로 EDT를 동결시킬 것이기 때문에 그렇게해서는 안됩니다.

생성자에 코드를 추가하고 앱 수명주기의 다른 곳에서 구성 요소 디자인 상태를 변경해야합니다.

스윙 페인팅에 대해 좀 더 알고 싶다면 pushing-pixels.org의 "스윙 페인팅 파이프 라인"게시물을 읽어보십시오.

BorderFactory.createCompoundBorder를 사용하여 두 개의 테두리를 결합 할 수 있습니다. 그런 다음 빈 경계선을 사용하여 간격을 설정하고 다른 경계선을 그리는 간격을 설정할 수 있습니다.

편집 : 예제가 추가되었습니다.

package com.stackoverflow.swing.paintpipeline; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 
import javax.swing.border.Border; 


public class JLabelSetBorderPaintProblem extends JLabel { 

    public JLabelSetBorderPaintProblem(String text) { 
     super(text); 
    } 

    /* 
    * @see javax.swing.JComponent paint(java.awt.Graphics) 
    */ 
    @Override 
    public void paint(Graphics g) { 
     super.paint(g); 
     // You can not call setBorder here. 

     // Please check javadoc. 
    } 

    /* 
    * @see javax.swing.JComponent paintBorder(java.awt.Graphics) 
    */ 
    @Override 
    protected void paintBorder(Graphics g) { 
     super.paintBorder(g); 
     // Here is where the Swing painting pipeline draws the current border 
     // for the JLabel instance. 

     // Please check javadoc. 
    } 

    // Start me here! 
    public static void main(String[] args) { 
     // SetBorder will dispatch an event to Event Dispatcher Thread to draw the 
     // new border around the component - you must call setBorder inside EDT. 
     // Swing rule 1. 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override public void run() { 
       // Inside EDT 
       JFrame frame = new JFrame("JLabel setBorder example"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       // Add the JLabel 
       final JLabelSetBorderPaintProblem label = new JLabelSetBorderPaintProblem("Just press or wait..."); 
       frame.add(label); 

       // And change the border... 
       label.addMouseListener(new MouseAdapter() { 
        @Override public void mousePressed(MouseEvent e) { 
         label.setBorder(BORDERS.get(new Random().nextInt(BORDERS.size()))); 
        } 
       }); 

       // ...whenever you want 
       new Timer(5000, new ActionListener() { 
        @Override public void actionPerformed(ActionEvent e) { 
         label.setBorder(BORDERS.get(new Random().nextInt(BORDERS.size()))); 
        } 
       }).start(); 

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

    } 

    public static final List<Border> BORDERS; 
    static { 
     BORDERS = new ArrayList<Border>(); 
     BORDERS.add(BorderFactory.createLineBorder(Color.BLACK)); 
     BORDERS.add(BorderFactory.createLineBorder(Color.RED)); 
     BORDERS.add(BorderFactory.createEtchedBorder()); 
     BORDERS.add(BorderFactory.createTitledBorder("A border")); 
    } 
} 
+0

확실히이 문제의 요점 인 것 같습니다. 우리는 테두리를 전역 정적 (응용 프로그램의 다른 테두리처럼)으로 만든 다음 페인트 메서드에서 테두리를 설정하여 문제를 해결했습니다. 나는 아직도 여기에서 무슨 일이 일어나고 있는지 충분히 잘 이해하지 못하고 있지만 이것은 문제를 해결하는 것처럼 보이기 때문에 충분히 호명 할 것입니다. – Morinar

관련 문제