You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
6.1 KiB
194 lines
6.1 KiB
package com.fr.design.mainframe.toast; |
|
|
|
import com.fr.concurrent.NamedThreadFactory; |
|
import com.fr.design.dialog.UIDialog; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.module.ModuleContext; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.Icon; |
|
import javax.swing.JPanel; |
|
import javax.swing.SwingConstants; |
|
import javax.swing.SwingUtilities; |
|
import java.awt.BorderLayout; |
|
import java.awt.Dimension; |
|
import java.awt.Point; |
|
import java.awt.Window; |
|
import java.util.concurrent.ScheduledExecutorService; |
|
import java.util.concurrent.TimeUnit; |
|
|
|
/** |
|
* toast弹窗 |
|
* */ |
|
public class SimpleToast extends UIDialog { |
|
private static final int MIN_HEIGHT = 36; |
|
private static final String TOAST_MSG_TIMER = "TOAST_MSG_TIMER"; |
|
private static final long DEFAULT_DISAPPEAR_DELAY = 5000; |
|
private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS; |
|
|
|
|
|
private ScheduledExecutorService timer; |
|
private int hideHeight = 0; |
|
private JPanel contentPane; |
|
private boolean show = false; |
|
private Window parent; |
|
private boolean autoDisappear; |
|
|
|
public SimpleToast(Window parent, Icon icon, String text, boolean autoDisappear) { |
|
super(parent); |
|
this.parent = parent; |
|
this.autoDisappear = autoDisappear; |
|
JPanel panel = createContentPane(icon, text); |
|
init(panel); |
|
} |
|
|
|
private JPanel createContentPane(Icon icon, String text) { |
|
JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
|
|
UILabel iconLabel = new UILabel(icon); |
|
iconLabel.setVerticalAlignment(SwingConstants.TOP); |
|
iconLabel.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); |
|
|
|
|
|
UILabel textLabel = new UILabel(text); |
|
pane.add(iconLabel, BorderLayout.WEST); |
|
pane.add(textLabel, BorderLayout.CENTER); |
|
pane.setBorder(BorderFactory.createEmptyBorder(8, 15, 8, 15)); |
|
|
|
return pane; |
|
} |
|
|
|
|
|
private void init(JPanel panel) { |
|
setFocusable(false); |
|
setAutoRequestFocus(false); |
|
setUndecorated(true); |
|
contentPane = panel; |
|
initComponent(); |
|
} |
|
|
|
private void initComponent() { |
|
this.getContentPane().setLayout(null); |
|
this.getContentPane().add(contentPane); |
|
Dimension dimension = calculatePreferSize(); |
|
hideHeight = dimension.height; |
|
setSize(new Dimension(dimension.width, 0)); |
|
contentPane.setSize(dimension); |
|
setRelativeLocation(dimension); |
|
if (autoDisappear) { |
|
disappear(contentPane); |
|
} |
|
} |
|
|
|
private void setRelativeLocation(Dimension dimension) { |
|
int positionX = parent.getLocationOnScreen().x + (parent.getWidth() - dimension.width) / 2; |
|
int positionY = parent.getLocationOnScreen().y + 10; |
|
this.setLocation(positionX, positionY); |
|
} |
|
|
|
private Dimension calculatePreferSize() { |
|
Dimension contentDimension = contentPane.getPreferredSize(); |
|
int height = Math.max(MIN_HEIGHT, contentDimension.height); |
|
return new Dimension(contentDimension.width, height); |
|
} |
|
|
|
|
|
public void display(JPanel outerPanel) { |
|
show = true; |
|
outerPanel.setLocation(0, -hideHeight); |
|
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
|
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
|
@Override |
|
public void run() { |
|
SwingUtilities.invokeLater(()->{ |
|
displayStep(outerPanel, tipToolTimer); |
|
}); |
|
} |
|
}, 0, 50, TimeUnit.MILLISECONDS); |
|
|
|
} |
|
|
|
void displayStep(JPanel outerPanel, ScheduledExecutorService timer) { |
|
Point point = outerPanel.getLocation(); |
|
if (point.y >= 0 && !timer.isShutdown()) { |
|
timer.shutdown(); |
|
} |
|
int showDistance = 5 + point.y < 0 ? 5 : -point.y; |
|
outerPanel.setLocation(point.x, point.y + showDistance); |
|
Dimension dimension = SimpleToast.this.getSize(); |
|
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height + showDistance)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
private void disappear(JPanel outerPanel, long delay, TimeUnit timeUnit) { |
|
timer = createToastScheduleExecutorService(); |
|
timer.schedule(new DisappearMotion(outerPanel), delay, timeUnit); |
|
} |
|
|
|
/** |
|
* toast消失的动画效果 |
|
* */ |
|
class DisappearMotion implements Runnable { |
|
JPanel panel; |
|
|
|
DisappearMotion(JPanel panel) { |
|
this.panel = panel; |
|
} |
|
|
|
@Override |
|
public void run() { |
|
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
|
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
|
@Override |
|
public void run() { |
|
SwingUtilities.invokeLater(()->{ |
|
disappearStep(tipToolTimer); |
|
}); |
|
} |
|
}, 0, 50, TimeUnit.MILLISECONDS); |
|
} |
|
|
|
void disappearStep(ScheduledExecutorService timer) { |
|
Point point = panel.getLocation(); |
|
if (point.y <= -hideHeight && !timer.isShutdown()) { |
|
timer.shutdown(); |
|
SimpleToast.this.setVisible(false); |
|
SimpleToast.this.dispose(); |
|
SimpleToast.this.show = false; |
|
} |
|
panel.setLocation(point.x, point.y - 5); |
|
Dimension dimension = SimpleToast.this.getSize(); |
|
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height - 5)); |
|
} |
|
} |
|
|
|
private void disappear(JPanel outerPanel) { |
|
disappear(outerPanel, DEFAULT_DISAPPEAR_DELAY, DEFAULT_TIME_UNIT); |
|
} |
|
|
|
private ScheduledExecutorService createToastScheduleExecutorService() { |
|
return ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory(TOAST_MSG_TIMER)); |
|
} |
|
|
|
@Override |
|
public void checkValid() throws Exception { |
|
} |
|
|
|
public void setVisible(boolean visible) { |
|
super.setVisible(visible); |
|
if (visible) { |
|
display(contentPane); |
|
} |
|
} |
|
|
|
@Override |
|
public void dispose() { |
|
super.dispose(); |
|
} |
|
|
|
} |