달성 방법은 거의 없습니다. 한 가지 가능한 방법은 무엇이가하는 것입니다 것은 설정하는 JWindow
생성, 투명한 JWindow
의 사용과 스윙 기본적으로 Timer
통해의 그것의 배경 색상 완전히 투명, 투명 창을. 그런 다음 간단한 배경을 렌더링하기 위해 BackgroundPane
을 사용하고 실제 메시지를 보유하려면 MessagePane
을 사용합니다. 하나의 패널에서이 작업을 수행 할 수 있지만이 유연성을 좋아합니다.
이제
, 개인적으로, 나는 팝업 창을 구축하고 가변 지연과 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)
업데이트
당신은 예를 들어, 간단한 API를 제공하기 위해 공장 또는 빌더 패턴을 사용할 수
...
new PopupBuilder().at(new Point(100, 100)).withMessage("Hello").withDelay(5000).show();
원하는 속성을 수집하는 것 빌더 지정하지 않은 경우 기본값을 제공 한 다음 최종 팝업을 표시합니다.
기본적인 아이디어는 당신이 show
를 호출 할 때, 그것은 ...
는 페이딩 팝업 창에 업데이트 등록 정보를 수집하고 생성자 지금 작동하는 방식과 유사한 창을 만들 것입니다
이 페이드 인/아웃 이펙트를 생성 할 수있는 방법의 예입니다.예는 메시지가 이제 지정된 지연 기간
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
을 변경하는 경우 당신은 또한 팝업 메시지의 불투명도에 걸쳐 영향을 미칠 수 있습니다. 이 메서드는 메시지 텍스트가 아닌 배경에만 영향을 미칩니다 ...
코드를 다운로드하여 시도해 보았습니다. 제 목적으로는 작동한다고 생각하지만 문제가 하나 있습니다. 텍스트 버블의 인용 부호와 위치를 지정할 수 있도록 코드 일부를 추상화하려고하면 내부 클래스를 사용하므로 전달한 매개 변수가 final로 선언되어야한다는 컴파일러 오류가 발생합니다. 이제 오류 자체는 명백합니다. 그러나이 설정을 사용하면 따옴표와 위치를 지정하는 기능을 추가하는 방법에 대해 궁금합니다. 이 코드를 완전히 다시 해보려고 할 수는 있지만이 아키텍처를 유지하는 방법이 있는지 궁금합니다. – user3670987
앞서 언급했듯이 실제로 수행 할 작업은 하나 이상의 정적 메서드가있는 팩토리 클래스를 만드는 것입니다. 이것들은 생성자가 지금하는 것처럼 윈도우를 생성하고 메시지를 적용합니다. setLocationRelativeTo 메소드를 setLocation과 윈도우의 위치를 재배치하여 윈도우의 위치를 지정할 수 있습니다. 나머지는 이미 설정해야합니다 ... more or less;) – MadProgrammer
조언을 주셔서 감사합니다. 완벽하게 작동했습니다. 나는 알파 합성물을 작동 시키려고 노력하고있다. 그러나 나는 한 단계에서 길을 잃었다 고 생각한다. 나는 paint 컴퍼넌트 메소드의 백그라운드 영역에 알파 합성을 적용하여 g2d에 영향을 미치려고한다고 가정하지만, 내가 한 것은 투명성에 전혀 영향을 미치지 않았습니다. 나는 또한 glp와 똑같은 일을 시도했지만 alpha 합성물이 거기에 적용된다고 생각하지 않는다. 여기에 대한 조언이 있으면 알고 싶을 것입니다. (이미 작업하고있는 것을 보시고, 물론 힌트를 주시고, 더 재미있게 보시길 바랍니다) – user3670987