
jadex.commons.gui.SGUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-commons-gui Show documentation
Show all versions of jadex-commons-gui Show documentation
Common GUI support classes.
package jadex.commons.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dialog; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URL; import java.util.ArrayList; import java.util.EventObject; import java.util.Iterator; import java.util.LinkedList; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriter; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageOutputStream; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.SwingUtilities; import javax.swing.UIDefaults; import javax.swing.border.LineBorder; import javax.swing.event.CellEditorListener; import javax.swing.table.TableCellEditor; import jadex.commons.SReflect; import jadex.commons.SUtil; /** * Static helper class with useful gui related methods. */ public class SGUI { //-------- constants -------- /** This property can be set on components to be automatically adjusted to equal sizes. */ public static final String AUTO_ADJUST = "auto-adjust"; //-------- methods -------- /** * Create a menu bar, given a list of actions. * @param actions The actions (null is mapped to separator). * @return A menu bar with a menu containing the actions. */ public static JMenuBar createMenuBar(Action[] actions) { JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("Actions"); menubar.add(menu); for(int i=0; i
filename. */ // Hack!!! Required, because LookAndFeel.makeIcon returns an IconUIResource, // but only ImageIcons can be greyed out. grrr... public static Object makeIcon(final Class baseclass, final String imgloc) { return new UIDefaults.LazyValue() { public Object createValue(UIDefaults table) { URL url = baseclass.getResource(imgloc); if(url==null) throw new RuntimeException("Cannot load image: "+imgloc); return new ImageIcon(url); } }; } /** * Render an object on a grid. * @param g The graphics object. * @param comp The object to render. * @param cellw The cell width. * @param cellh The cell height. */ public static void renderObject(Graphics g, Component comp, double cellw, double cellh, int x, int y, int gridwidth) { Rectangle bounds = new Rectangle( (int)(cellw*x)+gridwidth, (int)(cellh*y)+gridwidth, (int)(cellw*(x+1)) - (int)(cellw*x) - gridwidth*2, (int)(cellh*(y+1)) - (int)(cellh*y) - gridwidth*2); // Paint component into component. comp.setBounds(bounds); g.translate(bounds.x, bounds.y); comp.paint(g); g.translate(-bounds.x, -bounds.y); } /** * Calculate the middle position of a window relativ to */ public static Point calculateMiddlePosition(Window win) { return calculateMiddlePosition(null, win); } /** * Calculate the middle position of a window relativ to */ public static Point calculateMiddlePosition(Window outer, Window win) { int rx; int ry; if(outer!=null && outer.isVisible()) { Point p = outer.getLocationOnScreen(); rx = (int)(p.getX()+outer.getWidth()/2); ry = (int)(p.getY()+outer.getHeight()/2); } else { Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); rx = (int)size.getWidth() / 2; ry = (int)size.getHeight() / 2; } int x = rx - win.getWidth()/2; int y = ry - win.getHeight()/2; return new Point(x, y); } /** * Get the window parent if any. * @param comp The component. * @return The window if any. */ public static Window getWindowParent(Component comp) { while(comp!=null && !(comp instanceof Window)) { comp = comp.getParent(); } return (Window)comp; } /** * Show an non-model message dialog. */ public static void showMessageDialog(Component parent, Object message, String title, int msgtype) { final JOptionPane pane = new JOptionPane(message, msgtype); final JDialog dialog = pane.createDialog(parent, title); dialog.setModal(false); pane.selectInitialValue(); dialog.setVisible(true); // todo: find out why only called on JCC exit. dialog.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { dialog.removeWindowListener(this); dialog.dispose(); } }); } /** * Display an error dialog. * * @param errortitle The title to use for an error dialog (required). * @param errormessage An optional error message displayed before the exception. * @param exception The exception (if any). */ public static void showError(Component parent, String errortitle, String errormessage, final Exception exception) { // if(exception!=null) // { // Thread.dumpStack(); // exception.printStackTrace(); // } final String text; String exmsg = exception==null ? null : exception.getMessage(); if(errormessage==null && exmsg==null) { text = errortitle; } else if(errormessage!=null && exmsg==null) { text = errormessage; } else if(errormessage==null && exmsg!=null) { text = exmsg; } else// if(errormessage!=null && exmsg!=null) { text = errormessage + "\n" + exmsg; } Object message = SUtil.wrapText(text); if(exception!=null) { final JPanel panel = new JPanel(new BorderLayout()); final JButton details = new JButton("Show Details") { public Insets getInsets() { return new Insets(1, 1, 1, 1); } }; details.addActionListener(new ActionListener() { JComponent area = null; boolean shown = false; public void actionPerformed(ActionEvent e) { if(shown) { panel.remove(area); details.setText("Show Details"); } else { if(area==null) { StringWriter sw = new StringWriter(); exception.printStackTrace(new PrintWriter(sw)); area = new JScrollPane(new JTextArea(sw.toString(), 10, 40)); } panel.add(area, BorderLayout.CENTER); details.setText("Hide Details"); } SGUI.getWindowParent(panel).pack(); shown = !shown; } }); JPanel but = new JPanel(new FlowLayout(FlowLayout.RIGHT)); but.add(details); JTextArea msg = new JTextArea(message.toString()); msg.setEditable(false); // Java Bug #7100524 Workaround: // This is needed to avoid throwing an obscure exception later msg.setDropTarget(null); msg.setCursor(null); msg.setOpaque(false); // msg.setFocusable(false); panel.add(msg, BorderLayout.NORTH); panel.add(but, BorderLayout.SOUTH); message = panel; // Make dialogs resizable panel.addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { Window window = SwingUtilities.getWindowAncestor(panel); if(window instanceof Dialog) { Dialog dialog = (Dialog)window; if(!dialog.isResizable()) { dialog.setResizable(true); } } } }); } JOptionPane.showMessageDialog(parent, message, errortitle, JOptionPane.ERROR_MESSAGE); } /** * Adjust components to equal sizes according to their * miminum, maximum, and preferred sizes. */ public static void adjustComponentSizes(JComponent[] components) { int minimumwidth = 0; int minimumheight = 0; int maximumwidth = 0; int maximumheight = 0; int preferredwidth = 0; int preferredheight = 0; for(int i=0; igifFile 0) { Object comp = components.remove(0); // Add adjustables to adjustable list. if(comp instanceof JComponent) { JComponent jcomp = (JComponent)comp; if(jcomp.getClientProperty(AUTO_ADJUST)!=null) { adjustables.add(jcomp); } } // Add children to traversal list. if(comp instanceof Container) { Container container = (Container)comp; for(int i=0; i 1) { JComponent[] jcomps = (JComponent[])adjustables.toArray(new JComponent[adjustables.size()]); adjustComponentSizes(jcomps); } } /** * Create a table that displays its contents using nto editable text fields. */ public static JTable createReadOnlyTable() { final JTextField editor = new JTextField(); editor.setEditable(false); JTable table = new JTable(); table.setBackground(editor.getBackground()); table.setBorder(new LineBorder(table.getGridColor())); // table.setShowGrid(false); // final TableCellRenderer defrenderer = table.getDefaultRenderer(Object.class); // table.setDefaultRenderer(Object.class, new TableCellRenderer() // { // public Component getTableCellRendererComponent(JTable table, Object value, // boolean isSelected, boolean hasFocus, int row, int column) // { // Component ret = defrenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Dimension dim = ret.getPreferredSize(); // ret.setBounds(new Rectangle(0, 0, dim.width, dim.height)); // return ret; // } // }); table.setDefaultEditor(Object.class, new TableCellEditor() { public boolean stopCellEditing() { return true; } public boolean shouldSelectCell(EventObject anEvent) { return true; } public void removeCellEditorListener(CellEditorListener l) { } public boolean isCellEditable(EventObject anEvent) { return true; } public Object getCellEditorValue() { return null; } public void cancelCellEditing() { } public void addCellEditorListener(CellEditorListener l) { } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { editor.setText(""+value); Dimension dim = editor.getPreferredSize(); editor.setBounds(new Rectangle(0, 0, dim.width, dim.height)); return editor; } }); return table; } /** * Get the proportional split location. */ public static double getProportionalDividerLocation(JSplitPane pane) { double full = pane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT? pane.getSize().getWidth(): pane.getSize().getHeight(); double ret = ((double)pane.getDividerLocation())/full; return ret; } /** * Color conversion method for "web-style" color definitions. * This method is needed because CSS.stringToColor() is * protected and StyleSheet.stringToColor() may be unavailable * without a GUI. */ public static Color stringToColor(String str) { // Note: Unlike CSS.stringToColor, this method is missing "rgb(1.0, 1.0, 1.0)"-style definitions. if (str.length() == 0 || str.equalsIgnoreCase("Black")) str = "#000000"; else if(str.equalsIgnoreCase("Silver")) str = "#C0C0C0"; else if(str.equalsIgnoreCase("Gray")) str = "#808080"; else if(str.equalsIgnoreCase("White")) str = "#FFFFFF"; else if(str.equalsIgnoreCase("Maroon")) str = "#800000"; else if(str.equalsIgnoreCase("Red")) str = "#FF0000"; else if(str.equalsIgnoreCase("Purple")) str = "#800080"; else if(str.equalsIgnoreCase("Fuchsia")) str = "#FF00FF"; else if(str.equalsIgnoreCase("Green")) str = "#008000"; else if(str.equalsIgnoreCase("Lime")) str = "#00FF00"; else if(str.equalsIgnoreCase("Olive")) str = "#808000"; else if(str.equalsIgnoreCase("Yellow")) str = "#FFFF00"; else if(str.equalsIgnoreCase("Navy")) str = "#000080"; else if(str.equalsIgnoreCase("Blue")) str = "#0000FF"; else if(str.equalsIgnoreCase("Teal")) str = "#008080"; else if(str.equalsIgnoreCase("Aqua")) str = "#00FFFF"; Color ret = null; if(str.startsWith("#")) { String b = str.substring(5, 7); String g = str.substring(3, 5); String r = str.substring(1, 3); if (str.length()==9) { String alpha = str.substring(7); ret = new Color(Integer.parseInt(r, 16), Integer.parseInt(g, 16), Integer.parseInt(b, 16), Integer.parseInt(alpha, 16)); } else { ret = new Color(Integer.parseInt(r, 16), Integer.parseInt(g, 16), Integer.parseInt(b, 16)); } } return ret; } /** * Convert a color to an html representation. * * @param color The color. * @return The html string representing the color. */ public static String colorToHTML(Color color) { return "#" + Integer.toHexString(color.getRed()) + Integer.toHexString(color.getGreen()) + Integer.toHexString(color.getBlue()); } /** * Convert a font to an html representation. * * @param font The font. * @return The html string representing the font. */ public static String fontToHTML(Font font) { String style; if(font.isBold()) { style = font.isItalic() ? "bolditalic " : "bold "; } else { style = font.isItalic() ? "italic " : ""; } return style + font.getSize() + " " + font.getName(); } /** * Scale an image. * @param scr The src image. * @param w The width. * @param h The height. * @param type The type (Image.SCALE_XYZ). */ public static BufferedImage scaleImage(Image src, int w, int h, int type) { Image img = src.getScaledInstance(w, h, type); BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics g = ret.createGraphics(); g.drawImage(img, 0, 0, new Color(0,0,0), null); g.dispose(); return ret; } /** * Use SwingUtilities to put the given runnable in the AWT Event queue. * * @param runnable */ public static void invokeLater(Runnable runnable) { SwingUtilities.invokeLater(runnable); } // /** Lookup table for divider locations (split->Integer).*/ // protected static Map locations; // // /** // * Set a split location. // * Delays the call until the component is valid. // */ // public static void setDividerLocation(final JSplitPane split, int loc) // { // assert SwingUtilities.isEventDispatchThread(); // // // Set direct. // if(split.isValid()) // { // System.out.println("setDividerLocation: "+loc+", @"+split.hashCode()); // split.setDividerLocation(loc); // if(locations!=null) // { // locations.remove(split); // if(locations.isEmpty()) // { // locations = null; // } // } // } // // // Wait until valid. // else // { // // Already queued // if(locations!=null && locations.containsKey(split)) // { //// System.out.println("setDividerLocation updated: "+loc+", @"+split.hashCode()); // locations.put(split, Integer.valueOf(loc)); // } // // // First time call. // else // { // split.validate(); //// System.out.println("setDividerLocation queued: "+loc+", @"+split.hashCode()); // if(locations==null) // locations = new HashMap(); // locations.put(split, Integer.valueOf(loc)); // SwingUtilities.invokeLater(new Runnable() // { // public void run() // { // if(locations!=null && locations.containsKey(split)) // { // int loc = ((Integer)locations.remove(split)).intValue(); // if(locations.isEmpty()) // { // locations = null; // } // setDividerLocation(split, loc); // } // } // }); // } // } // } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy