2011-11-23 4 views
0

그라데이션 효과로 사용자 지정 단추를 만들고 있습니다. 그래디언트 효과를 설정할 수는 있지만 텍스트가 표시되지 않습니다. 내가 어디로 잘못 가고 있니?사용자 지정 그라디언트 단추 - 텍스트를 볼 수 없습니다.

class CustomButton extends JButton { 
    Color color1, color2; 

    public CustomButton(String text, Color color1, Color color2) { 
     super(text); 
     this.color1 = color1; 
     this.color2 = color2; 
     setOpaque(false); 
     setSize(new Dimension(450, 350)); 
     setForeground(Color.white); 
     setText(text); 
     setContentAreaFilled(false); 
    } 

    protected void paintComponent(Graphics g) {  
     super.paintComponent(g); 
     int width = getWidth(); 
     int height = getHeight(); 

     GradientPaint paint = new GradientPaint(0, 0, color1, width, height, 
       color2, true); 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     Paint oldPaint = g2d.getPaint(); 
     g2d.setPaint(paint); 
     g2d.fillRect(0, 0, width, height); 
     g2d.drawString("Button 1", getWidth()/2, 10); 
     g2d.setPaint(oldPaint); 
    } 
} 

참고 : 사용자가 런타임에 색을 변경할 수 있도록 허용합니다. 변경된 색상에 따라 배경을 적절하게 설정합니다.

+0

아직 super.paintComponent를 끝까지 이동하지 않았습니다 ... 왜 안 되니? – kleopatra

+0

어떤 어두운 차선을 따라 가지 마십시오 (수동으로 텍스트를 그리는 것처럼). 당장의 작업은 나에게 게시 된 솔루션 (그리고 Rob이 검사)이 귀하의 상황에서 작동하지 않는 이유를 찾아내는 것입니다 문제가 발생했을 때 문제를 시연하는 SSCCE를 보여줄 시간. 내 직감 다른 걸 말해. – kleopatra

답변

5

는 솔루션의 한 부분이

button.setOpaque(false) 

버튼을 정말이 배경

그림없는 그들이 에 모여 싶은, 조금 미친 것입니다
button.setContentAreaFilled(false) 

주의 : 정확한 결과는 여전히 고도의 LAF 일 수 있습니다. 의존 - f.i. 정말 나쁜 찾고. 신스 기반 (f.i.후광이) 당신은 그라디언트로 구성된 사용자 정의 화가를 설치하는 것이 좋습니다/색상은 사용자가 선택이 끝난로

편집

단지 재확인 :

// tell ui to not paint the background 
button.setOpaque(false); 
button.setContentAreaFilled(false); 

// override paintComponent 
protected void paintComponent(...) { 
    // do custom backgroudn painting 
    ... 
    // let ui handle the foreground (it wont touch the background due to the false settings above) 
    super.paintComponent() 
} 

모든 핵심 LAFS을 위해 잘 작동 (on win)

+0

업데이트 된 cade에서 볼 수 있듯이 setOpaque와 setContentAreaFilled를 구현했습니다. 또한 drawString이 추가되었습니다. 그러나 문자열은 어떤 경우에도 표시되지 않습니다. – Tvd

+0

@ 당신은 여전히 ​​수퍼 호를 메서드 끝까지 옮기지 않았습니다 – kleopatra

+0

나는 그것을 시도했습니다. 그렇게하면 모든 색상 변경이 사라지고 기본 색상이 나타납니다. 그래서 나는 다시 위로 움직였다. – Tvd

0

paintComponent 메서드를 재정의하고 해당 super 버전을 호출하지 마십시오.

paintComponent는 실제 텍스트를 쓰는 책임이 있습니다. 텍스트가 없으면 텍스트가 표시되지 않습니다.

그러니이 시점에서 :

가하거나 크기를 조정 처리하는 방법에 따라 복잡하지 않을 수도 있습니다 레이블 자신을 페인트하는 코드를 작성, 등

전화 super.paintComponent - 어떤 배경을 다시 칠하는 경우 작동하지 않을 수 있습니다.

+0

super.paintComponent가 작동하지 않는다 &없이 시도했지만 텍스트를 표시하는 데 도움이되지 않습니다. 문자를 쓰는 것으로 시작하는 힌트 라인 코드 나 예제 또는 지침을 알려주십시오. – Tvd

4

배경 그림을 피하려면 opaque = false를 설정하십시오.

그라데이션 페인트 코드를 모두 호출하고 메서드가 끝나면 super.paintComponent()을 호출하십시오.

+0

나는 false로 불투명했다. 마지막에 super.paintComponents를 호출하면 색상 표시가 손실되는 일반적인 버튼이 표시됩니다. 나는 채색을 유지하고 또한 텍스트를 보여주고 싶습니다. "그라디언트 페인트 코드를 모두 불러라"는 것은 무엇을 의미합니까? – Tvd

+0

분명히 어떻게 든 그려진 배경. getBackground()가 호출 된 곳을 확인하십시오. 수퍼 리어 (super)와 리셋 (reset)을하기 전에 setBackground()를 투명 색상으로 설정하십시오. – StanislavL

0

나는 그 paintComponent()를 사용하여 사용자 정의하는 JButton의 배경을 만들 수있는 올바른 방법이 아니다 생각이 배경, example for MetalButtonUIBasicButtonUI을 무시) 기본 두 방법

1) 대체에게 BackGround

2를 변경할 수 있습니다 통지 MetalButtonUICrossPlatformLookAndFeel == MetalLookAndFeel

편집에서 작동 (ButtonModel에에서 더 나은 제거 될 것이다/비활성화 balast)

,369 스탠은 이미 대답으로 1,363,210

enter image description here

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.border.AbstractBorder; 
import javax.swing.border.Border; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import javax.swing.plaf.ComponentUI; 
import javax.swing.plaf.basic.BasicButtonUI; 
import javax.swing.plaf.metal.MetalButtonUI; 

public class TextAreaInButton { 

    private JFrame frame = new JFrame("sssssssss"); 
    private JButton tip1Null = new JButton(" test button "); 

    public TextAreaInButton() { 
     Border line, raisedbevel, loweredbevel, title, empty; 
     line = BorderFactory.createLineBorder(Color.black); 
     raisedbevel = BorderFactory.createRaisedBevelBorder(); 
     loweredbevel = BorderFactory.createLoweredBevelBorder(); 
     title = BorderFactory.createTitledBorder(""); 
     empty = BorderFactory.createEmptyBorder(1, 1, 1, 1); 
     final Border compound; 
     Color crl = (Color.blue); 
     compound = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl)); 
     Color crl1 = (Color.red); 
     final Border compound1; 
     compound1 = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl1)); 
     Color crl2 = (Color.black); 
     final Border compound2; 
     compound2 = BorderFactory.createCompoundBorder(empty, new OldRoundedBorderLine(crl2)); 
     tip1Null.setFont(new Font("Serif", Font.BOLD, 14)); 
     tip1Null.setForeground(Color.darkGray); 
     tip1Null.setPreferredSize(new Dimension(50, 30)); 
     tip1Null.addActionListener(new java.awt.event.ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
      } 
     }); 
     tip1Null.setBorderPainted(true); 
     tip1Null.setFocusPainted(false); 
     tip1Null.setBorder(compound); 
     tip1Null.setHorizontalTextPosition(SwingConstants.CENTER); 
     tip1Null.setVerticalTextPosition(SwingConstants.BOTTOM); 
     tip1Null.setUI(new ModifButtonUI()); 

     tip1Null.getModel().addChangeListener(new ChangeListener() { 

      @Override 
      public void stateChanged(ChangeEvent e) { 
       ButtonModel model = (ButtonModel) e.getSource(); 
       if (model.isRollover()) { 
        tip1Null.setBorder(compound1); 
       } else { 
        tip1Null.setBorder(compound); 
       } 
       if (model.isPressed()) { 
        tip1Null.setBorder(compound2); 
       } 
      } 
     }); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(tip1Null, BorderLayout.CENTER); 
     frame.setLocation(150, 150); 
     frame.setPreferredSize(new Dimension(310, 75)); 
     frame.setLocationRelativeTo(null); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       TextAreaInButton taib = new TextAreaInButton(); 
      } 
     }); 
    } 
} 

class OldRoundedBorderLine extends AbstractBorder { 

    private final static int MARGIN = 5; 
    private static final long serialVersionUID = 1L; 
    private Color color; 

    OldRoundedBorderLine(Color clr) { 
     color = clr; 
    } 

    public void setColor(Color clr) { 
     color = clr; 
    } 

    @Override 
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 
     ((Graphics2D) g).setRenderingHint(
       RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g.setColor(color); 
     g.drawRoundRect(x, y, width, height, MARGIN, MARGIN); 
    } 

    @Override 
    public Insets getBorderInsets(Component c) { 
     return new Insets(MARGIN, MARGIN, MARGIN, MARGIN); 
    } 

    @Override 
    public Insets getBorderInsets(Component c, Insets insets) { 
     insets.left = MARGIN; 
     insets.top = MARGIN; 
     insets.right = MARGIN; 
     insets.bottom = MARGIN; 
     return insets; 
    } 
} 

class ModifButtonUI extends BasicButtonUI { 

    //private static final ModifButtonUI buttonUI = new ModifButtonUI(); 

    ModifButtonUI() { 
    } 

    public static ComponentUI createUI(JComponent c) { 
     return new ModifButtonUI(); 
    } 

    @Override 
    public void paint(Graphics g, JComponent c) { 
     //final Color color1 = new Color(230, 255, 255, 0); 
     //final Color color2 = new Color(255, 230, 255, 64); 
     final Color color1 = new Color(00, 0, 200, 0); 
     final Color color2 = new Color(255, 230, 255, 64); 
     final Color alphaColor = new Color(00, 200, 230, 64); 
     final Color color3 = new Color(
       alphaColor.getRed(), alphaColor.getGreen(), alphaColor.getBlue(), 0); 
     final Color color4 = new Color(
       alphaColor.getRed(), alphaColor.getGreen(), alphaColor.getBlue(), 64); 
     super.paint(g, c); 
     Graphics2D g2D = (Graphics2D) g; 
     GradientPaint gradient1 = new GradientPaint(
       0.0F, (float) c.getHeight()/(float) 2, color1, 0.0F, 0.0F, color2); 
     Rectangle rec1 = new Rectangle(0, 0, c.getWidth(), c.getHeight()/2); 
     g2D.setPaint(gradient1); 
     g2D.fill(rec1); 
     GradientPaint gradient2 = new GradientPaint(
       0.0F, (float) c.getHeight()/(float) 2, color3, 0.0F, c.getHeight(), color4); 
     Rectangle rec2 = new Rectangle(0, c.getHeight()/2, c.getWidth(), c.getHeight()); 
     g2D.setPaint(gradient2); 
     g2D.fill(rec2); 
    } 

    @Override 
    protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { 
     Font f = b.getFont(); 
     g.setFont(f); 
     FontMetrics fm = g.getFontMetrics(f); 

     if (b.isEnabled()) { 
      g.setColor(b.getForeground()); 
      g.drawString(text, textRect.x, textRect.y + fm.getAscent()); 
     } else { 
      g.setColor(b.getBackground().brighter()); 
      g.drawString(text, textRect.x, textRect.y + fm.getAscent()); 
      g.setColor(b.getBackground().darker()); 
      g.drawString(text, textRect.x + 1, textRect.y + fm.getAscent() + 1); 

     } 
    } 

    @Override 
    public void paintButtonPressed(Graphics g, AbstractButton b) { 
     paintText(g, b, b.getBounds(), b.getText()); 
     g.setColor(Color.red.brighter()); 
     g.fillRect(0, 0, b.getSize().width, b.getSize().height); 
    } 

    public void paintBorder(Graphics g) { 
    } 

    @Override 
    protected void paintFocus(Graphics g, AbstractButton b, 
      Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { 
    } 
} 
+0

mKorbel, 사용자가 색상을 변경하면 배경색을 변경해야합니다 (Q 참고 참고). 이 경우 기본 배경을 자주 바꿀 수 있으며 업데이트 될 예정입니다. – Tvd

+0

mKorbel, BasicButtonUI의 하위 클래스를 만들었지 만 버튼 만 표시하지는 않습니다. 제가 구현 한 클래스는 다음과 같습니다. https://skydrive.live.com/?cid=572d7026b8b4c709&sc=documents&uc=1&id=572D7026B8B4C709%21168# 그 클래스에서 잘못된 부분이 있습니다. – Tvd

+0

@ 편집 내 편집을보고, 나는 당신의 코드에서 paintText를 빨아 들였고, MetalXxxXx를 BasicXxxXx로 바꿨고, 색상을 변경했다. (테스트 목적으로 만), 거기에 뭔가 잘못되었다는 것을 확인하고 되돌릴 수 없다. – mKorbel

3

배경과 전경을 페인트하기 위해 동일한 Paint 객체를 사용하는 것처럼 보입니다. 그래서 배경과 병합되는 텍스트를 추측합니다.

Paint oldPaint = g2d.getPaint(); 
g2d.setPaint(paint); 
g2d.fillRect(0, 0, width, height); 
g2d.setPaint(oldPaint); // try adding this 
g2d.drawString("Button 1", getWidth()/2, 10); 
//g2d.setPaint(oldPaint); 
+0

+1 좋은 캐치! 심지어 그가 drawString을하고있는 것을 보지 못했습니다. 우리가 알고있는 것처럼 잘못되었습니다 :-) 가능한 한 많이 처리하자 – kleopatra

+0

kleopatra가 제안했듯이 drawString() 메서드는 사용하지 않아야합니다. 포스터 코드는 drawString() 메서드가 제거되고'super.paintComponent (g)'는 Paint 객체가 원래 Paint로 복원 된 후에 추가됩니다. – camickr

+1

그냥 호기심 .. 정말 그래픽의 상태를 복원해야합니까? Worksforme없이 (나는 게으른 태어난거야 :-) – kleopatra

관련 문제