2014-05-24 5 views
0

매우 구체적인 질문이 있습니다. 메소드 호출을 통해 텍스트가 포함 된 툴팁을 원할 수 있습니다. 메서드 호출시 특정 시간 동안 화면상의 주어진 위치 (논리가 대화 메서드에 있다고 가정)가 사라집니다. 어떻게하면 될까요? JTooltip을 통해이를 수행 할 수있는 방법이 있습니까? 아니면 내가 원하는 것을 얻기 위해 JNA에 뛰어 들어야합니까?자바의 스크립트를 통해 텍스트 상자 (또는 툴팁)를 팝업하는 방법

필자는 팝업과 같이 마우스의 큐가없는 지정된 위치의 텍스트로 툴팁을 팝업으로 표시하고 싶습니다.

또한 툴팁이 내가 원하는 것을 선택하는 올바른 방법이 아닌 경우 (내가 분명히했으면 좋겠다),보다 효과적인 대안이 있습니까?

답변

2

달성 방법은 거의 없습니다. 한 가지 가능한 방법은 무엇이가하는 것입니다 것은 설정하는 JWindow 생성, 투명한 JWindow의 사용과 스윙 기본적으로 Timer

통해의 그것의 배경 색상 완전히 투명, 투명 창을. 그런 다음 간단한 배경을 렌더링하기 위해 BackgroundPane을 사용하고 실제 메시지를 보유하려면 MessagePane을 사용합니다. 하나의 패널에서이 작업을 수행 할 수 있지만이 유연성을 좋아합니다.

이제

Popup

, 개인적으로, 나는 팝업 창을 구축하고 가변 지연과 Timer을 만들 수있는 간단한 API를 만들 것입니다,하지만 당신은 아이디어를 얻을

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.LinearGradientPaint; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.RoundRectangle2D; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JWindow; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 

public class PopupMessageWindow { 

    public static void main(String[] args) { 
     new PopupMessageWindow(); 
    } 

    public PopupMessageWindow() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       final JWindow frame = new JWindow(); 
       frame.setBackground(new Color(0, 0, 0, 0)); 
       BackgroundPane pane = new BackgroundPane(); 
       pane.setMessage("Boo, This is a popup..."); 
       frame.add(pane); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
       frame.setAlwaysOnTop(true); 

       Timer timer = new Timer(10000, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         frame.dispose(); 
         System.exit(0); 
        } 
       }); 
       timer.setRepeats(false); 
       timer.start(); 
      } 
     }); 
    } 

    public class BackgroundPane extends JPanel { 

     private MessagePane messagePane; 

     public BackgroundPane() { 
      setBorder(new EmptyBorder(40, 40, 40, 40)); 
      messagePane = new MessagePane(); 
      setLayout(new BorderLayout()); 
      add(messagePane); 
      setOpaque(false); 
     } 

     public void setMessage(String msg) { 
      messagePane.setMessage(msg); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); 
      g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
      g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
      g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 
      LinearGradientPaint glp = new LinearGradientPaint(
          new Point(0, 0), 
          new Point(0, getHeight()), 
          new float[]{0f, 1f}, 
          new Color[]{Color.GRAY, Color.BLACK}); 
      RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 
      g2d.setPaint(glp); 
      g2d.fill(frame); 
      g2d.setColor(Color.WHITE); 
      g2d.draw(frame); 
     } 

    } 

    public class MessagePane extends JPanel { 

     private JLabel label; 

     public MessagePane() { 
      setOpaque(false); 
      label = new JLabel(); 
      label.setForeground(Color.WHITE); 
      setLayout(new GridBagLayout()); 
      add(label); 
     } 

     public void setMessage(String msg) { 
      label.setText(msg); 
     } 

    } 

} 
당신은 놀 수

a 반투명 배경을 만들려면 배경 패널에 AlphaComposite을 넣으십시오.

팝업 창 50 % AlphaComposite

을 사용하는 팝업 창 (210)

Popup

업데이트

당신은 예를 들어, 간단한 API를 제공하기 위해 공장 또는 빌더 패턴을 사용할 수

...

new PopupBuilder().at(new Point(100, 100)).withMessage("Hello").withDelay(5000).show(); 

원하는 속성을 수집하는 것 빌더 지정하지 않은 경우 기본값을 제공 한 다음 최종 팝업을 표시합니다.

기본적인 아이디어는 당신이 show를 호출 할 때, 그것은 ...

는 페이딩 팝업 창에 업데이트 등록 정보를 수집하고 생성자 지금 작동하는 방식과 유사한 창을 만들 것입니다

이 페이드 인/아웃 이펙트를 생성 할 수있는 방법의 예입니다.예는 메시지가 이제 지정된 지연 기간

Popup

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.LinearGradientPaint; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.Window; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.RoundRectangle2D; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JWindow; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 

public class PopupMessageExample { 

    public static void main(String[] args) { 
     new PopupMessageExample(); 
    } 

    public PopupMessageExample() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 
       new PopupMessageBuilder().withDelay(10000).withMessage("Hello, this is a fading message").show(); 
      } 
     }); 
    } 

    public class PopupMessageBuilder { 

     private int delay; 
     private Point location; 
     private String message; 

     private long startTime; 
     private Timer fadeTimer; 

     public PopupMessageBuilder at(Point p) { 
      this.location = p; 
      return this; 
     } 

     public PopupMessageBuilder withDelay(int delay) { 
      this.delay = delay; 
      return this; 
     } 

     public PopupMessageBuilder withMessage(String msg) { 
      this.message = msg; 
      return this; 
     } 

     public PopupMessageBuilder show() { 

      final JWindow frame = new JWindow(); 
      frame.setOpacity(0f); 
      frame.setBackground(new Color(0, 0, 0, 0)); 
      BackgroundPane pane = new BackgroundPane(); 
      pane.setMessage(message); 
      frame.add(pane); 
      frame.pack(); 
      if (location == null) { 
       frame.setLocationRelativeTo(null); 
      } else { 
       frame.setLocation(location); 
      } 
      frame.setVisible(true); 
      frame.setAlwaysOnTop(true); 

      new FadeTimer(frame, 1000, 0f, 1f, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        Timer timer = new Timer(delay, new ActionListener() { 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          new FadeTimer(frame, 1000, 1f, 0f, new ActionListener() { 
           @Override 
           public void actionPerformed(ActionEvent e) { 
            frame.dispose(); 
           } 
          }).start(); 
         } 
        }); 
        timer.setRepeats(false); 
        timer.start(); 
       } 
      }).start(); 

      return this; 
     } 

     public class FadeTimer extends Timer implements ActionListener { 

      private final float startAt; 
      private final float endAt; 
      private final int duration; 
      private long startTimer; 

      private ActionListener endListener; 

      private Window window; 

      public FadeTimer(Window window, int duration, float startAt, float endAt, ActionListener endListener) { 
       super(5, null); 
       addActionListener(this); 
       this.duration = duration; 
       this.startAt = startAt; 
       this.endAt = endAt; 
       this.window = window; 

       this.endListener = endListener; 
      } 

      @Override 
      public void start() { 
       startTime = System.currentTimeMillis(); 
       super.start(); 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       long now = System.currentTimeMillis(); 
       long lapsed = now - startTime; 
       float opacity = startAt; 
       if (lapsed >= duration) { 
        opacity = endAt; 
        ((Timer) e.getSource()).stop(); 
        if (endListener != null) { 
         endListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "stopped")); 
        } 
       } else { 
        float progress = (float) lapsed/(float) duration; 
        float distance = endAt - startAt; 
        opacity = (float) (distance * progress); 
        opacity += startAt; 
       } 
       window.setOpacity(opacity); 
      } 

     } 

     public class BackgroundPane extends JPanel { 

      private MessagePane messagePane; 

      public BackgroundPane() { 
       setBorder(new EmptyBorder(40, 40, 40, 40)); 
       messagePane = new MessagePane(); 
       setLayout(new BorderLayout()); 
       add(messagePane); 
       setOpaque(false); 
      } 

      public void setMessage(String msg) { 
       messagePane.setMessage(msg); 
      } 

      @Override 
      protected void paintComponent(Graphics g) { 
       super.paintComponent(g); 
       Graphics2D g2d = (Graphics2D) g.create(); 
       g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); 
       g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
       g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
       g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
       g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 
       LinearGradientPaint glp = new LinearGradientPaint(
           new Point(0, 0), 
           new Point(0, getHeight()), 
           new float[]{0f, 1f}, 
           new Color[]{Color.GRAY, Color.BLACK}); 
       RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 
       g2d.setPaint(glp); 
       g2d.fill(frame); 
       g2d.setColor(Color.WHITE); 
       g2d.draw(frame); 
      } 

     } 

     public class MessagePane extends JPanel { 

      private JLabel label; 

      public MessagePane() { 
       setOpaque(false); 
       label = new JLabel(); 
       label.setForeground(Color.WHITE); 
       setLayout(new GridBagLayout()); 
       add(label); 
      } 

      public void setMessage(String msg) { 
       label.setText(msg); 
      } 

     } 

    } 

} 

에서의 화면 (전체)에있을 것입니다 보장, 당신은 아마 또한, 프레임의 최대 불투명도 레벨을 변경하여이 작업을 수행하지만, 당신이 BackgroundPane

protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g.create(); 
    AlphaComposite alpha = AlphaComposite.SrcOver.derive(0.75f); 
    g2d.setComposite(alpha); 

paintComponent을 변경하는 경우 당신은 또한 팝업 메시지의 불투명도에 걸쳐 영향을 미칠 수 있습니다. 이 메서드는 메시지 텍스트가 아닌 배경에만 영향을 미칩니다 ...

+0

코드를 다운로드하여 시도해 보았습니다. 제 목적으로는 작동한다고 생각하지만 문제가 하나 있습니다. 텍스트 버블의 인용 부호와 위치를 지정할 수 있도록 코드 일부를 추상화하려고하면 내부 클래스를 사용하므로 전달한 매개 변수가 final로 선언되어야한다는 컴파일러 오류가 발생합니다. 이제 오류 자체는 명백합니다. 그러나이 설정을 사용하면 따옴표와 위치를 지정하는 기능을 추가하는 방법에 대해 궁금합니다. 이 코드를 완전히 다시 해보려고 할 수는 있지만이 아키텍처를 유지하는 방법이 있는지 궁금합니다. – user3670987

+0

앞서 언급했듯이 실제로 수행 할 작업은 하나 이상의 정적 메서드가있는 팩토리 클래스를 만드는 것입니다. 이것들은 생성자가 지금하는 것처럼 윈도우를 생성하고 메시지를 적용합니다. setLocationRelativeTo 메소드를 setLocation과 윈도우의 위치를 ​​재배치하여 윈도우의 위치를 ​​지정할 수 있습니다. 나머지는 이미 설정해야합니다 ... more or less;) – MadProgrammer

+0

조언을 주셔서 감사합니다. 완벽하게 작동했습니다. 나는 알파 합성물을 작동 시키려고 노력하고있다. 그러나 나는 한 단계에서 길을 잃었다 고 생각한다. 나는 paint 컴퍼넌트 메소드의 백그라운드 영역에 알파 합성을 적용하여 g2d에 영향을 미치려고한다고 가정하지만, 내가 한 것은 투명성에 전혀 영향을 미치지 않았습니다. 나는 또한 glp와 똑같은 일을 시도했지만 alpha 합성물이 거기에 적용된다고 생각하지 않는다. 여기에 대한 조언이 있으면 알고 싶을 것입니다. (이미 작업하고있는 것을 보시고, 물론 힌트를 주시고, 더 재미있게 보시길 바랍니다) – user3670987