package gui;
import com.jidesoft.pane.CollapsiblePane;
import com.jidesoft.popup.JidePopup;
import com.jidesoft.swing.JideButton;
import entity.info.*;
import op.OPDE;
import op.system.AppInfo;
import op.system.FileDrop;
import op.threads.DisplayMessage;
import op.tools.PopupPanel;
import op.tools.SYSConst;
import op.tools.SYSTools;
import org.apache.commons.collections.Closure;
import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.TimingSource;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.core.animation.timing.interpolators.AccelerationInterpolator;
import org.jdesktop.swing.animation.timing.sources.SwingTimerTimingSource;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.Style;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyVetoException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/**
* Created by IntelliJ IDEA.
* User: tloehr
* Date: 16.06.11
* Time: 14:46
* To change this template use File | Settings | File Templates.
*/
public class GUITools {
public static void exportToPNG(JPanel pnl, File output) {
BufferedImage bi = new BufferedImage(pnl.getSize().width, pnl.getSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
pnl.paint(g);
g.dispose();
try {
ImageIO.write(bi, "png", output);
OPDE.getDisplayManager().addSubMessage(new DisplayMessage("PNG exported"));
} catch (Exception e) {
}
}
public static String createStringListFrom(Collection<String> collection) {
String result = "";
for (String s : collection) {
result += SYSTools.xx(s) + ", ";
}
return result.isEmpty() ? null : result.substring(0, result.length() - 2);
}
public static ByteArrayOutputStream getAsImage(JPanel pnl) throws Exception {
BufferedImage bi = new BufferedImage(pnl.getPreferredSize().width, pnl.getPreferredSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
pnl.paint(g);
g.dispose();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "png", baos);
return baos;
}
public static void exportToPNG(JPanel pnl, String prefix) {
if (prefix == null) {
prefix = "pnl2png";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
exportToPNG(pnl, new File(AppInfo.getOPCache() + File.separator + prefix + "_" + sdf.format(new Date()) + ".png"));
}
public static JideButton createHyperlinkButton(String titleORlangbundle, Icon icon, ActionListener actionListener) {
final JideButton button = new JideButton(SYSTools.xx(titleORlangbundle), icon);
button.setButtonStyle(JideButton.HYPERLINK_STYLE);
button.setFont(SYSConst.ARIAL14);
button.setOpaque(false);
button.setHorizontalAlignment(SwingConstants.LEADING);
button.setRequestFocusEnabled(true);
button.setFocusable(true);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
if (actionListener != null) {
button.addActionListener(actionListener);
}
return button;
}
public static JTextField createIntegerTextField(final int min, final int max, final int init) {
final JTextField txt = new JTextField(Integer.toString(init), 10);
txt.setFont(SYSConst.ARIAL14);
txt.setHorizontalAlignment(SwingConstants.RIGHT);
txt.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
txt.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
int i = 0;
try {
i = Integer.parseInt(txt.getText());
} catch (NumberFormatException e1) {
txt.setText(Integer.toString(init));
}
if (min > i || i > max) {
txt.setText(Integer.toString(init));
}
}
});
return txt;
}
public static void addAllComponents(JPanel panel, java.util.List<Component> componentList) {
for (Component component : componentList) {
panel.add(component);
}
}
public static MouseAdapter getHyperlinkStyleMouseAdapter() {
return new MouseAdapter() {
String text = "";
@Override
public void mouseEntered(MouseEvent mouseEvent) {
text = SYSTools.removeTags(((javax.swing.AbstractButton) mouseEvent.getSource()).getText(), "html");
((javax.swing.AbstractButton) mouseEvent.getSource()).setText("<html><u>" + text + "</u></html>");
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
((javax.swing.AbstractButton) mouseEvent.getSource()).setText(SYSTools.toHTMLForScreen(text));
}
};
}
public static JToggleButton getNiceToggleButton(String titleORlangbundle, ItemListener il) {
JToggleButton btn = getNiceToggleButton(titleORlangbundle);
btn.addItemListener(il);
return btn;
}
// public static JPanel getNiceToggleButton(String titleORlangbundleYes, String titleORlangbundleNo) {
// JPanel pnl = new JPanel(new GridLayout(1, 2));
//// pnl.setLayout(new BoxLayout(pnl, BoxLayout.LINE_AXIS));
//
// JToggleButton tbYes = new JToggleButton(SYSTools.xx(titleORlangbundleYes));
// JToggleButton tbNo = new JToggleButton(SYSTools.xx(titleORlangbundleNo));
//
// pnl.add(tbYes);
// pnl.add(tbNo);
//
// tbYes.setSelected(true);
// tbNo.setSelected(false);
// tbYes.setOpaque(true);
// tbNo.setOpaque(true);
// tbNo.setBackground(SYSConst.darkred);
// tbYes.setBackground(SYSConst.darkgreen);
// tbYes.addItemListener(e -> tbNo.setSelected(e.getStateChange() != ItemEvent.SELECTED));
//
// tbNo.addItemListener(e -> tbYes.setSelected(e.getStateChange() != ItemEvent.SELECTED));
//
// return pnl;
// }
public static JToggleButton getNiceToggleButton(String titleORlangbundle) {
String title = SYSTools.catchNull(titleORlangbundle);
try {
title = SYSTools.xx(titleORlangbundle);
} catch (Exception e) {
// ok, its not a langbundle key
}
JToggleButton tb = new JToggleButton(title);
tb.setIcon(new ImageIcon(tb.getClass().getResource("/artwork/22x22/cb-off.png")));
tb.setSelectedIcon(new ImageIcon(tb.getClass().getResource("/artwork/22x22/cb-on.png")));
tb.setContentAreaFilled(false);
tb.setBorderPainted(false);
tb.setBorder(null);
tb.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
tb.setBackground(Color.WHITE);
tb.setAlignmentX(Component.LEFT_ALIGNMENT);
return tb;
}
public static JButton getTinyButton(String tooltip, Icon icon) {
JButton jButton = new JButton(icon);
jButton.setContentAreaFilled(false);
jButton.setBorder(null);
jButton.setBorderPainted(false);
jButton.setToolTipText(SYSTools.xx(tooltip));
jButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
return jButton;
}
/**
* Shows a JidePopup in relation to its owner. Calculates the new position that it leaves the owner
* visible. The popup is placed according to the <code>location</code> setting. The size of the content
* pane is taken into the calculation in order to find the necessary <code>x, y</code> coordinates on the screen.
* <p>
* <ul>
* <li>SwingConstants.CENTER <i>You can use this, but I fail to see the sense in it.</i></li>
* <li>SwingConstants.SOUTH</li>
* <li>SwingConstants.NORTH</li>
* <li>SwingConstants.WEST</li>
* <li>SwingConstants.EAST</li>
* <li>SwingConstants.NORTH_EAST</li>
* <li>SwingConstants.NORTH_WEST</li>
* <li>SwingConstants.SOUTH_EAST</li>
* <li>SwingConstants.SOUTH_WEST</li>
* </ul>
*
* @param popup the JidePopup to show
* @param location where to show the popup in relation to the <code>reference</code>. Use the SwingConstants above.
*/
public static void showPopup(JidePopup popup, int location, boolean keepOnScreen) {
Point desiredPosition = getDesiredPosition(popup, location);
// OPDE.debug(Boolean.toString(isFullyVisibleOnScreen(popup, desiredPosition)));
if (keepOnScreen && !isFullyVisibleOnScreen(popup, desiredPosition)) {
int[] positions = new int[]{SwingConstants.SOUTH_EAST, SwingConstants.SOUTH_WEST, SwingConstants.NORTH_EAST, SwingConstants.NORTH_WEST, SwingConstants.SOUTH, SwingConstants.EAST, SwingConstants.SOUTH_WEST, SwingConstants.NORTH, SwingConstants.CENTER};
boolean found = false;
for (int pos : positions) {
desiredPosition = getDesiredPosition(popup, pos);
if (isFullyVisibleOnScreen(popup, desiredPosition)) {
found = true;
OPDE.debug("fits on screen");
break;
}
}
if (!found) {
// desiredPosition = getDesiredPosition(popup, location);
desiredPosition = centerOnScreen(popup);
OPDE.debug("didnt find any position thats on the screen");
}
}
popup.showPopup(desiredPosition.x, desiredPosition.y);
}
private static Point centerOnScreen(JidePopup popup) {
GraphicsDevice gd = getCurrentScreen(OPDE.getMainframe());
int width = gd.getDisplayMode().getWidth();
int height = gd.getDisplayMode().getHeight();
int midx = width / 2;
int midy = height / 2;
int x = midx - popup.getContentPane().getPreferredSize().width / 2;
int y = midy - popup.getContentPane().getPreferredSize().height / 2;
return new Point(x, y);
}
private static Point getDesiredPosition(JidePopup popup, int location) {
Container content = popup.getContentPane();
final Point screenposition = new Point(popup.getOwner().getLocationOnScreen().x, popup.getOwner().getLocationOnScreen().y);
// Point screenposition = new Point(popup.getOwner().getLocation());
// SwingUtilities.convertPointToScreen(screenposition, OPDE.getMainframe());
int x = screenposition.x;
int y = screenposition.y;
switch (location) {
case SwingConstants.SOUTH_WEST: {
x = screenposition.x - content.getPreferredSize().width;
y = screenposition.y;
break;
}
case SwingConstants.SOUTH: {
x = screenposition.x;
y = screenposition.y + popup.getOwner().getPreferredSize().height;
break;
}
case SwingConstants.SOUTH_EAST: {
x = screenposition.x + popup.getOwner().getPreferredSize().width;
y = screenposition.y + popup.getOwner().getPreferredSize().height;
break;
}
case SwingConstants.NORTH_EAST: {
x = screenposition.x + popup.getOwner().getPreferredSize().width;
y = screenposition.y - popup.getOwner().getPreferredSize().height - content.getPreferredSize().height;
break;
}
case SwingConstants.NORTH_WEST: {
x = screenposition.x - content.getPreferredSize().width - popup.getOwner().getPreferredSize().width;
y = screenposition.y - popup.getOwner().getPreferredSize().height - content.getPreferredSize().height;
break;
}
case SwingConstants.EAST: {
x = screenposition.x + popup.getOwner().getPreferredSize().width;
y = screenposition.y - (popup.getOwner().getPreferredSize().height / 2);
break;
}
case SwingConstants.WEST: {
x = screenposition.x - content.getPreferredSize().width;
y = screenposition.y - (popup.getOwner().getPreferredSize().height / 2);
break;
}
case SwingConstants.NORTH: {
x = screenposition.x;
y = screenposition.y - content.getPreferredSize().height;
break;
}
case SwingConstants.CENTER: {
x = screenposition.x + popup.getOwner().getPreferredSize().width / 2 - content.getPreferredSize().width / 2;
y = screenposition.y + popup.getOwner().getPreferredSize().height / 2 - content.getPreferredSize().height / 2;
break;
}
default: {
// nop
}
}
return new Point(x, y);
}
public static boolean isFullyVisibleOnScreen(JidePopup popup, Point point) {
// GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
GraphicsDevice gd = getCurrentScreen(OPDE.getMainframe());
int width = gd.getDisplayMode().getWidth();
int height = gd.getDisplayMode().getHeight();
int spreadX = point.x + popup.getContentPane().getPreferredSize().width;
int spreadY = point.y + popup.getContentPane().getPreferredSize().height;
OPDE.debug("PointX: " + point.x);
OPDE.debug("PointY: " + point.y);
return point.x >= 0 && point.y >= 0 && width > spreadX && height > spreadY;
}
public static void showPopup(JidePopup popup, int location) {
showPopup(popup, location, true);
}
public static JPanel getDropPanel(FileDrop.Listener dropListener) {
return getDropPanel(dropListener, SYSTools.xx("nursingrecords.files.drophere"));
}
public static JPanel getDropPanel(FileDrop.Listener dropListener, String text) {
JPanel dropPanel = new JPanel();
dropPanel.setLayout(new BorderLayout());
JLabel dropLabel = new JLabel(text, new ImageIcon(Double.class.getResource("/artwork/48x48/kget_dock.png")), SwingConstants.CENTER);
dropLabel.setFont(SYSConst.ARIAL20);
dropLabel.setHorizontalTextPosition(SwingConstants.CENTER);
dropLabel.setVerticalTextPosition(SwingConstants.BOTTOM);
dropPanel.add(BorderLayout.CENTER, dropLabel);
dropPanel.setPreferredSize(new Dimension(180, 180));
dropPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
new FileDrop(dropPanel, dropListener);
return dropPanel;
}
public static void setResidentDisplay(Resident resident) {
OPDE.getDisplayManager().setMainMessage(ResidentTools.getLabelText(resident), SYSTools.toHTML(ResInfoTools.getTXReportHeader(resident, false)));
// result += getTXReportHeader(resident, withlongheader);
ResInfo biohazard = ResInfoTools.getLastResinfo(resident, ResInfoTypeTools.getByType(ResInfoTypeTools.TYPE_INFECTION));
ResInfo diabetes = ResInfoTools.getLastResinfo(resident, ResInfoTypeTools.getByType(ResInfoTypeTools.TYPE_DIABETES));
ResInfo warning = ResInfoTools.getLastResinfo(resident, ResInfoTypeTools.getByType(ResInfoTypeTools.TYPE_WARNING));
ResInfo allergy = ResInfoTools.getLastResinfo(resident, ResInfoTypeTools.getByType(ResInfoTypeTools.TYPE_ALLERGY));
OPDE.getDisplayManager().setIconBiohazard(biohazard != null && biohazard.isCurrentlyValid() ? SYSTools.toHTML(SYSConst.html_div(biohazard.getHtml())) : null);
OPDE.getDisplayManager().setIconDiabetes(diabetes != null && diabetes.isCurrentlyValid() ? SYSTools.toHTML(SYSConst.html_div(diabetes.getHtml())) : null);
OPDE.getDisplayManager().setIconWarning(warning != null && warning.isCurrentlyValid() ? SYSTools.toHTML(SYSConst.html_div(warning.getHtml())) : null);
OPDE.getDisplayManager().setIconAllergy(allergy != null && allergy.isCurrentlyValid() ? SYSTools.toHTML(SYSConst.html_div(allergy.getHtml())) : null);
if (ResInfoTools.isAway(resident)) {
OPDE.getDisplayManager().setIconAway();
} else if (ResInfoTools.isDead(resident)) {
OPDE.getDisplayManager().setIconDead();
} else if (ResInfoTools.isGone(resident)) {
OPDE.getDisplayManager().setIconGone();
}
OPDE.getDisplayManager().clearSubMessages();
}
public static void appendText(String text, JTextPane txt, Style style) {
SwingUtilities.invokeLater(() -> {
try {
txt.getStyledDocument().insertString(txt.getStyledDocument().getLength(), SYSTools.xx(text), style);
} catch (BadLocationException e) {
e.printStackTrace();
}
if (txt.getParent().getParent() instanceof JScrollPane) {
JScrollPane scrl = (JScrollPane) txt.getParent().getParent();
scrl.getVerticalScrollBar().setValue(scrl.getVerticalScrollBar().getMaximum());
}
txt.revalidate();
txt.repaint();
});
}
public static String[] getLocalizedMessages(String[] languagekeys) {
String[] result = new String[languagekeys.length];
int index = 0;
for (String key : languagekeys) {
result[index] = SYSTools.xx(key);
index++;
}
return result;
}
public static void setCollapsed(Container root, boolean collapsed) throws PropertyVetoException {
if (root instanceof CollapsiblePane) {
if (((CollapsiblePane) root).isCollapsible()) {
((CollapsiblePane) root).setCollapsed(collapsed);
}
}
for (Component component : root.getComponents()) {
if (component instanceof Container) {
setCollapsed((Container) component, collapsed);
}
}
}
public static void expand(CollapsiblePane cp) throws PropertyVetoException {
// ArrayList<CollapsiblePane> path = new ArrayList<CollapsiblePane>();
// path.add(cp);
cp.setCollapsed(false);
Container cont = cp.getParent();
while (cont != null) {
if (cont instanceof CollapsiblePane) {
((CollapsiblePane) cont).setCollapsed(false);
}
cont = cont.getParent();
}
//
//
// if (root instanceof CollapsiblePane) {
// if (((CollapsiblePane) root).isCollapsible()) {
// ((CollapsiblePane) root).setCollapsed(collapsed);
// }
// }
// for (Component component : root.getComponents()) {
// if (component instanceof Container) {
// setCollapsed((Container) component, collapsed);
// }
// }
}
public static void scroll2show(final JScrollPane jsp, int end, final Closure what2doAfterwards) {
final int start = jsp.getVerticalScrollBar().getValue();
OPDE.debug("scroll2show: trying to move from " + start);
OPDE.debug("scroll2show: trying to move to " + end);
end = Math.max(0, end);
end = Math.min(jsp.getVerticalScrollBar().getMaximum(), end);
if (OPDE.isAnimation()) {
final int distance = end - start;
final TimingSource ts = new SwingTimerTimingSource();
Animator.setDefaultTimingSource(ts);
ts.init();
Animator animator = new Animator.Builder().setInterpolator(new AccelerationInterpolator(0.15f, 0.8f)).setDuration(500, TimeUnit.MILLISECONDS).setStartDirection(Animator.Direction.FORWARD).addTarget(new TimingTargetAdapter() {
@Override
public void begin(Animator source) {
}
@Override
public void timingEvent(Animator animator, double fraction) {
final BigDecimal value = new BigDecimal(start).add(new BigDecimal(fraction).multiply(new BigDecimal(distance)));
SwingUtilities.invokeLater(() -> jsp.getVerticalScrollBar().setValue(value.intValue()));
}
@Override
public void end(Animator source) {
if (what2doAfterwards != null)
what2doAfterwards.execute(null);
}
}).build();
animator.start();
} else {
final int myend = end;
SwingUtilities.invokeLater(() -> jsp.getVerticalScrollBar().setValue(myend));
}
}
/**
* scrolls the given scrollpane to show the component within the surrounding container.
* <b>IMPORTANT: always validate() the container b4 using this method. otherwise the frigging
* scrollpane won't budge.</b>
*
* @param jsp
* @param component
* @param container
* @param what2doAfterwards
*/
public static void scroll2show(final JScrollPane jsp, final JComponent component, Container container, final Closure what2doAfterwards) {
if (component == null)
return; // this prevents NULL pointer exceptions when quickly switching the residents after the entry
final int start = jsp.getVerticalScrollBar().getValue();
final int end = SwingUtilities.convertPoint(component, component.getLocation(), container).y;
if (OPDE.isAnimation()) {
final int distance = end - start;
final TimingSource ts = new SwingTimerTimingSource();
Animator.setDefaultTimingSource(ts);
ts.init();
Animator animator = new Animator.Builder().setInterpolator(new AccelerationInterpolator(0.15f, 0.8f)).setDuration(750, TimeUnit.MILLISECONDS).setStartDirection(Animator.Direction.FORWARD).addTarget(new TimingTargetAdapter() {
@Override
public void begin(Animator source) {
}
@Override
public void timingEvent(final Animator animator, double fraction) {
final BigDecimal value = new BigDecimal(start).add(new BigDecimal(fraction).multiply(new BigDecimal(distance)));
SwingUtilities.invokeLater(() -> {
Rectangle r = component.getVisibleRect();
if (r.getSize().equals(component.getSize())) {
animator.stop();
} else if (r.isEmpty()) {
OPDE.debug("not visible");
jsp.getVerticalScrollBar().setValue(value.intValue());
} else {
OPDE.debug("partly visible");
jsp.getVerticalScrollBar().setValue(value.intValue());
}
});
}
@Override
public void end(Animator source) {
component.repaint();
if (what2doAfterwards != null)
what2doAfterwards.execute(null);
}
}).build();
animator.start();
} else {
final int myend = end;
SwingUtilities.invokeLater(() -> jsp.getVerticalScrollBar().setValue(myend));
}
}
public static Animator flashBackground(Animator animator, final JComponent component, final Color flashcolor, int repeatTimes) {
if (component == null)
return null; // this prevents NULL pointer exceptions when quickly switching the residents after the entry
final Color originalColor = component.getBackground();
if (animator == null || !animator.isRunning()) {
final TimingSource ts = new SwingTimerTimingSource();
final boolean wasOpaque = component.isOpaque();
Animator.setDefaultTimingSource(ts);
ts.init();
component.setOpaque(true);
animator = new Animator.Builder().setDuration(750, TimeUnit.MILLISECONDS).setRepeatCount(repeatTimes).setRepeatBehavior(Animator.RepeatBehavior.REVERSE).setStartDirection(Animator.Direction.FORWARD).addTarget(new TimingTargetAdapter() {
@Override
public void begin(Animator source) {
}
@Override
public void timingEvent(Animator animator, final double fraction) {
SwingUtilities.invokeLater(() -> {
component.setBackground(interpolateColor(originalColor, flashcolor, fraction));
component.repaint();
});
}
@Override
public void end(Animator source) {
component.setOpaque(wasOpaque);
component.repaint();
}
}).build();
} else {
animator.stop();
}
animator.start();
return animator;
}
public static void flashBackground(final JComponent component, final Color flashcolor, int repeatTimes) {
// https://github.com/tloehr/Offene-Pflege.de/issues/37
if (component == null)
return; // this prevents NULL pointer exceptions when quickly switching the residents after the entry
flashBackground(component, flashcolor, component.getBackground(), repeatTimes);
}
public static void flashBackground(final JComponent component, final Color flashcolor, final Color originalColor, int repeatTimes) {
if (component == null)
return; // this prevents NULL pointer exceptions when quickly switching the residents after the entry
// final Color originalColor = component.getBackground();
final TimingSource ts = new SwingTimerTimingSource();
final boolean wasOpaque = component.isOpaque();
Animator.setDefaultTimingSource(ts);
ts.init();
component.setOpaque(true);
Animator animator = new Animator.Builder().setDuration(750, TimeUnit.MILLISECONDS).setRepeatCount(repeatTimes).setRepeatBehavior(Animator.RepeatBehavior.REVERSE).setStartDirection(Animator.Direction.FORWARD).addTarget(new TimingTargetAdapter() {
@Override
public void begin(Animator source) {
}
@Override
public void timingEvent(Animator animator, final double fraction) {
SwingUtilities.invokeLater(() -> {
component.setBackground(interpolateColor(originalColor, flashcolor, fraction));
component.repaint();
});
}
@Override
public void end(Animator source) {
component.setOpaque(wasOpaque);
component.repaint();
}
}).build();
animator.start();
}
public static void flashIcon(final AbstractButton btn, final Icon icon) {
flashIcon(btn, icon, 2);
}
public static void flashIcon(final AbstractButton btn, final Icon icon, int repeat) {
if (btn == null)
return; // this prevents NULL pointer exceptions when quickly switching the residents after the entry
int textposition = btn.getHorizontalTextPosition();
btn.setHorizontalTextPosition(SwingConstants.LEADING);
final Icon originalIcon = btn.getIcon();
final TimingSource ts = new SwingTimerTimingSource();
Animator.setDefaultTimingSource(ts);
ts.init();
Animator animator = new Animator.Builder().setDuration(750, TimeUnit.MILLISECONDS).setRepeatCount(repeat).setRepeatBehavior(Animator.RepeatBehavior.REVERSE).setStartDirection(Animator.Direction.FORWARD).addTarget(new TimingTargetAdapter() {
Animator.Direction dir;
public void begin(Animator source) {
dir = null;
}
@Override
public void timingEvent(Animator animator, final double fraction) {
if (dir == null || !dir.equals(animator.getCurrentDirection())) {
dir = animator.getCurrentDirection();
SwingUtilities.invokeLater(() -> {
if (animator.getCurrentDirection().equals(Animator.Direction.FORWARD)) {
btn.setIcon(icon);
} else {
btn.setIcon(originalIcon);
}
// Logger.getLogger(getClass()).debug(fraction);
// btn.setIcon();
// component.setBackground(interpolateColor(originalColor, flashcolor, fraction));
btn.revalidate();
btn.repaint();
});
}
}
@Override
public void end(Animator source) {
SwingUtilities.invokeLater(() -> {
btn.setHorizontalTextPosition(textposition);
btn.setIcon(originalIcon);
btn.repaint();
});
}
}).build();
animator.start();
}
/**
* @param distance a double between 0.0f and 1.0f to express the distance between the source and destination color
* see http://stackoverflow.com/questions/27532/generating-gradients-programatically
* @return
*/
public static Color interpolateColor(Color source, Color destination, double distance) {
int red = (int) (destination.getRed() * distance + source.getRed() * (1 - distance));
int green = (int) (destination.getGreen() * distance + source.getGreen() * (1 - distance));
int blue = (int) (destination.getBlue() * distance + source.getBlue() * (1 - distance));
return new Color(red, green, blue);
}
public static JidePopup getHTMLPopup(Component owner, String html) {
final JTextPane txt = new JTextPane();
txt.setContentType("text/html");
txt.setEditable(false);
final JidePopup popupInfo = new JidePopup();
popupInfo.setMovable(false);
popupInfo.setContentPane(new JScrollPane(txt));
popupInfo.removeExcludedComponent(txt);
popupInfo.setDefaultFocusComponent(txt);
popupInfo.setOwner(owner);
txt.setText(SYSTools.toHTML(html));
return popupInfo;
}
public static void addExpandCollapseButtons(final Container cp, JPanel pane) {
final JButton btnExpandAll = new JButton(SYSConst.icon22expand);
btnExpandAll.setPressedIcon(SYSConst.icon22addPressed);
btnExpandAll.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnExpandAll.setContentAreaFilled(false);
btnExpandAll.setBorder(null);
btnExpandAll.setToolTipText(SYSTools.xx("misc.msg.expandall"));
btnExpandAll.addActionListener(actionEvent -> {
try {
GUITools.setCollapsed(cp, false);
} catch (PropertyVetoException e) {
// bah!
}
});
pane.add(btnExpandAll);
final JButton btnCollapseAll = new JButton(SYSConst.icon22collapse);
btnCollapseAll.setPressedIcon(SYSConst.icon22addPressed);
btnCollapseAll.setAlignmentX(Component.RIGHT_ALIGNMENT);
btnCollapseAll.setContentAreaFilled(false);
btnCollapseAll.setBorder(null);
btnCollapseAll.setToolTipText(SYSTools.xx("misc.msg.collapseall"));
btnCollapseAll.addActionListener(actionEvent -> {
try {
GUITools.setCollapsed(cp, true);
} catch (PropertyVetoException e) {
// bah!
}
});
pane.add(btnCollapseAll);
}
public static JidePopup getTextEditor(String preset, int rows, int cols, final Closure saveClosure, Component owner) {
final JidePopup popup = new JidePopup();
popup.setMovable(false);
popup.getContentPane().setLayout(new BoxLayout(popup.getContentPane(), BoxLayout.LINE_AXIS));
final JTextComponent editor = rows == 1 ? new JTextField(preset, cols) : new JTextArea(preset, rows, cols);
editor.setFont(SYSConst.ARIAL18);
if (rows > 1) {
((JTextArea) editor).setLineWrap(false);
((JTextArea) editor).setWrapStyleWord(false);
}
popup.getContentPane().add(new JScrollPane(editor));
final JButton saveButton = new JButton(SYSConst.icon16apply);
saveButton.addActionListener(e -> {
popup.hidePopup();
saveClosure.execute(SYSTools.tidy(editor.getText()));
});
saveButton.setHorizontalAlignment(SwingConstants.RIGHT);
JPanel pnl = new JPanel(new BorderLayout(10, 10));
JScrollPane pnlEditor = new JScrollPane(editor);
pnl.add(pnlEditor, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
saveButton.setContentAreaFilled(false);
saveButton.setBorder(null);
saveButton.setBorderPainted(false);
buttonPanel.add(saveButton);
pnl.setBorder(new EmptyBorder(10, 10, 10, 10));
pnl.add(buttonPanel, BorderLayout.EAST);
popup.setOwner(owner);
popup.removeExcludedComponent(owner);
popup.getContentPane().add(pnl);
popup.setDefaultFocusComponent(editor);
return popup;
}
public static JidePopup createPanelPopup(final PopupPanel myPnl, final Closure saveAction, Component owner) {
final JidePopup popup = new JidePopup();
popup.setMovable(false);
JPanel pnl = new JPanel(new BorderLayout(10, 10));
pnl.setBorder(new EmptyBorder(5, 5, 5, 5));
pnl.add(myPnl, BorderLayout.CENTER);
JPanel btnPanel = new JPanel();
btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.X_AXIS));
JButton saveButton = new JButton(SYSConst.icon22apply);
saveButton.addActionListener(e -> {
if (myPnl.isSaveOK()) {
popup.hidePopup();
saveAction.execute(myPnl.getResult());
}
});
saveButton.setContentAreaFilled(false);
saveButton.setBorder(null);
saveButton.setBorderPainted(false);
btnPanel.add(Box.createHorizontalGlue());
btnPanel.add(saveButton);
pnl.add(btnPanel, BorderLayout.SOUTH);
popup.setContentPane(pnl);
popup.setPreferredSize(pnl.getPreferredSize());
pnl.revalidate();
popup.setOwner(owner);
popup.removeExcludedComponent(owner);
// popup.removeExcludedComponent(pnl);
popup.setDefaultFocusComponent(pnl);
return popup;
}
public static boolean containsEmpty(ArrayList<JTextComponent> list) {
boolean result = false;
for (JTextComponent comp : list) {
if (comp.getText().trim().isEmpty()) {
result = true;
break;
}
}
return result;
}
public static FocusTraversalPolicy createTraversalPolicy(final ArrayList<Component> list) {
FocusTraversalPolicy myPolicy = new FocusTraversalPolicy() {
@Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
int pos = list.indexOf(aComponent) + 1;
if (pos == list.size()) {
pos = 0;
}
return list.get(pos);
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
int pos = list.indexOf(aComponent) - 1;
if (pos < 0) {
pos = list.size() - 1;
}
return list.get(pos);
}
@Override
public Component getFirstComponent(Container aContainer) {
return list.get(0);
}
@Override
public Component getLastComponent(Container aContainer) {
return list.get(list.size() - 1);
}
@Override
public Component getDefaultComponent(Container aContainer) {
return list.get(0);
}
};
return myPolicy;
}
public static void load(Properties content, java.util.List<Component> components) {
for (Component comp : components) {
if (comp instanceof JTextComponent) {
((JTextComponent) comp).setText(content.getProperty(comp.getName()));
} else if (comp instanceof AbstractButton) {
((AbstractButton) comp).setSelected(Boolean.parseBoolean(SYSTools.catchNull(content.getProperty(comp.getName()), "false")));
}
}
}
public static void save(Properties content, java.util.List<Component> components) {
for (Component comp : components) {
if (comp instanceof JTextComponent) {
content.setProperty(comp.getName(), ((JTextComponent) comp).getText());
} else if (comp instanceof AbstractButton) {
content.setProperty(comp.getName(), Boolean.toString(((AbstractButton) comp).isSelected()));
}
}
}
public static Color invert(Color color) {
return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
}
/**
* http://stackoverflow.com/questions/8741479/automatically-determine-optimal-fontcolor-by-backgroundcolor
*
* @param background
* @return
*/
public static Color getForeground(Color background) {
int red = 0;
int green = 0;
int blue = 0;
if (background.getRed() + background.getGreen() + background.getBlue() < 383) {
red = 255;
green = 255;
blue = 255;
}
return new Color(red, green, blue);
}
/**
* http://stackoverflow.com/questions/4059133/getting-html-color-codes-with-a-jcolorchooser
*
* @param c
* @return
*/
public static String getHTMLColor(Color c) {
StringBuilder sb = new StringBuilder("");
if (c.getRed() < 16) sb.append('0');
sb.append(Integer.toHexString(c.getRed()));
if (c.getGreen() < 16) sb.append('0');
sb.append(Integer.toHexString(c.getGreen()));
if (c.getBlue() < 16) sb.append('0');
sb.append(Integer.toHexString(c.getBlue()));
return sb.toString();
}
/**
* Creates a Color object according to the names of the Java color constants.
* A HTML color string like "62A9FF" may also be used. Please remove the leading "#".
*
* @param colornameOrHTMLCode
* @return the desired color. Defaults to BLACK, in case of an error.
*/
public static Color getColor(String colornameOrHTMLCode) {
Color color = Color.black;
if (colornameOrHTMLCode.equalsIgnoreCase("red")) {
color = Color.red;
} else if (colornameOrHTMLCode.equalsIgnoreCase("blue")) {
color = Color.blue;
} else if (colornameOrHTMLCode.equalsIgnoreCase("dark_red")) {
color = Color.red.darker();
} else if (colornameOrHTMLCode.equalsIgnoreCase("green")) {
color = Color.green;
} else if (colornameOrHTMLCode.equalsIgnoreCase("dark_green")) {
color = Color.green.darker();
} else if (colornameOrHTMLCode.equalsIgnoreCase("yellow")) {
color = Color.yellow;
} else if (colornameOrHTMLCode.equalsIgnoreCase("cyan")) {
color = Color.CYAN;
} else if (colornameOrHTMLCode.equalsIgnoreCase("light_gray")) {
color = Color.LIGHT_GRAY;
} else if (colornameOrHTMLCode.equalsIgnoreCase("dark_gray")) {
color = Color.DARK_GRAY;
} else if (colornameOrHTMLCode.equalsIgnoreCase("gray")) {
color = Color.GRAY;
} else if (colornameOrHTMLCode.equalsIgnoreCase("pink")) {
color = Color.PINK;
} else if (colornameOrHTMLCode.equalsIgnoreCase("magenta")) {
color = Color.MAGENTA;
} else if (colornameOrHTMLCode.equalsIgnoreCase("white")) {
color = Color.WHITE;
} else if (colornameOrHTMLCode.equalsIgnoreCase("orange")) {
color = SYSConst.gold7;
} else if (colornameOrHTMLCode.equalsIgnoreCase("dark_orange")) {
color = SYSConst.darkorange;
} else {
try {
int red = Integer.parseInt(colornameOrHTMLCode.substring(0, 2), 16);
int green = Integer.parseInt(colornameOrHTMLCode.substring(2, 4), 16);
int blue = Integer.parseInt(colornameOrHTMLCode.substring(4), 16);
color = new Color(red, green, blue);
} catch (NumberFormatException nfe) {
color = Color.BLACK;
}
}
return color;
}
/**
* creates a blend between two colors. The float specifies where the balance is.
* the more towards 1.0 emphasizes the <b>first</b> color.
* the more towards 0.0 emphasizes the <b>second</b> color.
*
* @param clOne
* @param clTwo
* @param fAmount
* @return
*/
public static Color blend(Color clOne, Color clTwo, float fAmount) {
float fInverse = 1.0f - fAmount;
// I had to look up getting colour components in java. Google is good :)
float afOne[] = new float[3];
clOne.getColorComponents(afOne);
float afTwo[] = new float[3];
clTwo.getColorComponents(afTwo);
float afResult[] = new float[3];
afResult[0] = afOne[0] * fAmount + afTwo[0] * fInverse;
afResult[1] = afOne[1] * fAmount + afTwo[1] * fInverse;
afResult[2] = afOne[2] * fAmount + afTwo[2] * fInverse;
return new Color(afResult[0], afResult[1], afResult[2]);
}
public static Color blend(String clOne, Color clTwo, float fAmount) {
return blend(GUITools.getColor(clOne), clTwo, fAmount);
}
// public static Color brighter(Color originalColour, float FACTOR) {
//
//
// float hsbVals[] = Color.RGBtoHSB(originalColour.getRed(),
// originalColour.getGreen(),
// originalColour.getBlue(), null);
//
// Color highlight = Color.getHSBColor(hsbVals[0], hsbVals[1], FACTOR * (1f + hsbVals[2]));
//// Color shadow = Color.getHSBColor( hsbVals[0], hsbVals[1], 0.5f * hsbVals[2] );
//
// return highlight;
//
//
//// return new Color(Math.min((int) (color.getRed() * (1 / FACTOR)), 255),
//// Math.min((int) (color.getGreen() * (1 / FACTOR)), 255),
//// Math.min((int) (color.getBlue() * (1 / FACTOR)), 255));
// }
//
// public static Color darker(Color color, float FACTOR) {
// return new Color(Math.max((int) (color.getRed() * FACTOR), 0),
// Math.max((int) (color.getGreen() * FACTOR), 0),
// Math.max((int) (color.getBlue() * FACTOR), 0));
// }
//
//
// static Image iconToImage(Icon icon) {
// if (icon instanceof ImageIcon) {
// return ((ImageIcon)icon).getImage();
// }
// else {
// int w = icon.getIconWidth();
// int h = icon.getIconHeight();
// GraphicsEnvironment ge =
// GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice gd = ge.getDefaultScreenDevice();
// GraphicsConfiguration gc = gd.getDefaultConfiguration();
// BufferedImage image = gc.createCompatibleImage(w, h);
// Graphics2D g = image.createGraphics();
// icon.paintIcon(null, g, 0, 0);
// g.dispose();
// return image;
// }
// }
// public static Icon paint(Icon in) {
// Image myImage = iconToImage(in);
// BufferedImage bufferedImage = new BufferedImage(myImage.getWidth(null), myImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
//
// GraphicsEnvironment ge =
// GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice gd = ge.getDefaultScreenDevice();
// GraphicsConfiguration gc = gd.getDefaultConfiguration();
// BufferedImage image = gc.createCompatibleImage(in.getIconWidth(), in.getIconHeight());
// Graphics2D g = image.createGraphics();
//
//
// Graphics gb = bufferedImage.getGraphics();
// gb.drawImage(myImage, 0, 0, null);
// gb.dispose();
//
// AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
// tx.translate(-myImage.getWidth(null), 0);
// AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// bufferedImage = op.filter(bufferedImage, null);
//
//
//
// g2d.drawImage(myImage, 10, 10, null);
// g2d.drawImage(bufferedImage, null, 300, 10);
// }
/**
* http://stackoverflow.com/questions/2234476/how-to-detect-the-current-display-with-java
*
* @param myWindow
* @return
*/
public static GraphicsDevice getCurrentScreen(JFrame myWindow) {
GraphicsConfiguration config = myWindow.getGraphicsConfiguration();
return config.getDevice();
// GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
// // AFAIK - there are no guarantees that screen devices are in order...
// // but they have been on every system I've used.
// GraphicsDevice[] allScreens = env.getScreenDevices();
// int myScreenIndex = -1;
// for (int i = 0; i < allScreens.length; i++) {
// if (allScreens[i].equals(myScreen))
// {
// myScreenIndex = i;
// break;
// }
// }
//// System.out.println("window is on screen" + myScreenIndex);
// return myScreenIndex;
}
public static Rectangle getScreenSize(GraphicsDevice myScreen) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
// AFAIK - there are no guarantees that screen devices are in order...
// but they have been on every system I've used.
GraphicsDevice[] allScreens = env.getScreenDevices();
int myScreenIndex = -1;
for (int i = 0; i < allScreens.length; i++) {
if (allScreens[i].equals(myScreen)) {
myScreenIndex = i;
break;
}
}
// System.out.println("window is on screen" + myScreenIndex);
return GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[myScreenIndex].getDefaultConfiguration().getBounds();
}
}