diff --git a/src/com/alee/examples/content/SourceViewer.java b/src/com/alee/examples/content/SourceViewer.java index a836a37d9..1ea03f824 100644 --- a/src/com/alee/examples/content/SourceViewer.java +++ b/src/com/alee/examples/content/SourceViewer.java @@ -770,9 +770,7 @@ public void actionPerformed ( ActionEvent e ) } } - boolean ltr = rootElement.getComponentOrientation ().isLeftToRight (); - rootMenu.show ( rootElement, ltr ? 1 : rootElement.getWidth () - 1 - rootMenu.getPreferredSize ().width, - rootElement.getHeight () + 2 ); + rootMenu.showBelowMiddle ( rootElement ); } } ); classPath.add ( rootElement ); @@ -801,11 +799,7 @@ public void actionPerformed ( ActionEvent e ) { packageMenu.add ( createEntryMenuItem ( menuEntry ) ); } - - boolean ltr = rootElement.getComponentOrientation ().isLeftToRight (); - packageMenu.show ( element, - ltr ? classPath.getElementOverlap () : element.getWidth () - classPath.getElementOverlap () - - packageMenu.getPreferredSize ().width, element.getHeight () + 2 ); + packageMenu.showBelowMiddle ( element ); } } } ); @@ -1034,7 +1028,7 @@ private String loadSource ( JarEntry lastEntry ) String source = loadString ( lastEntry ); // Removing space-eating license notice - if ( source.startsWith ( "/*" ) ) + if ( source.startsWith ( commentStart ) ) { int index = source.indexOf ( commentEnd ); if ( index != -1 ) diff --git a/src/com/alee/examples/groups/menubar/DefaultMenuBarExample.java b/src/com/alee/examples/groups/menubar/DefaultMenuBarExample.java index 7df8dee55..a68f56364 100644 --- a/src/com/alee/examples/groups/menubar/DefaultMenuBarExample.java +++ b/src/com/alee/examples/groups/menubar/DefaultMenuBarExample.java @@ -18,13 +18,13 @@ package com.alee.examples.groups.menubar; import com.alee.examples.content.DefaultExample; -import com.alee.laf.menu.WebMenu; -import com.alee.laf.menu.WebMenuBar; -import com.alee.laf.menu.WebMenuItem; +import com.alee.laf.menu.*; import com.alee.managers.hotkey.Hotkey; import com.alee.managers.tooltip.TooltipManager; import com.alee.managers.tooltip.TooltipWay; +import javax.swing.*; + /** * User: mgarin Date: 07.11.12 Time: 18:21 */ @@ -42,7 +42,7 @@ public void setupMenuBar ( WebMenuBar menuBar ) add ( new WebMenuItem ( "New image", loadIcon ( "menubar/file_image.png" ) ) { { - setHotkey ( Hotkey.CTRL_N ); + setAccelerator ( Hotkey.CTRL_N ); } } ); add ( new WebMenuItem ( "New music", loadIcon ( "menubar/file_music.png" ) ) ); @@ -58,7 +58,7 @@ public void setupMenuBar ( WebMenuBar menuBar ) add ( new WebMenuItem ( "Exit", loadIcon ( "menubar/file_exit.png" ) ) { { - setHotkey ( Hotkey.ALT_F4 ); + setAccelerator ( Hotkey.ALT_F4 ); } } ); } @@ -69,32 +69,80 @@ public void setupMenuBar ( WebMenuBar menuBar ) add ( new WebMenuItem ( "Cut", loadIcon ( "menubar/edit_cut.png" ) ) { { - setHotkey ( Hotkey.CTRL_X ); + setAccelerator ( Hotkey.CTRL_X ); } } ); add ( new WebMenuItem ( "Copy", loadIcon ( "menubar/edit_copy.png" ) ) { { - setHotkey ( Hotkey.CTRL_C ); + setAccelerator ( Hotkey.CTRL_C ); } } ); add ( new WebMenuItem ( "Paste", loadIcon ( "menubar/edit_paste.png" ) ) { { - setHotkey ( Hotkey.CTRL_V ); + setAccelerator ( Hotkey.CTRL_V ); setEnabled ( false ); } } ); } } ); + menuBar.add ( new WebMenu ( "States", loadIcon ( "menubar/states.png" ) ) + { + { + add ( new WebCheckBoxMenuItem ( "Checkbox item 1", loadIcon ( "menubar/check1.png" ) ) + { + { + setAccelerator ( Hotkey.NUMBER_1 ); + setSelected ( true ); + } + } ); + add ( new WebCheckBoxMenuItem ( "Checkbox item 2", loadIcon ( "menubar/check2.png" ) ) + { + { + setAccelerator ( Hotkey.NUMBER_2 ); + } + } ); + addSeparator (); + final ButtonGroup buttonGroup = new ButtonGroup (); + add ( new WebRadioButtonMenuItem ( "Radio item 1", loadIcon ( "menubar/radio1.png" ) ) + { + { + setAccelerator ( Hotkey.A ); + setSelected ( true ); + buttonGroup.add ( this ); + } + } ); + add ( new WebRadioButtonMenuItem ( "Radio item 2", loadIcon ( "menubar/radio2.png" ) ) + { + { + setAccelerator ( Hotkey.B ); + buttonGroup.add ( this ); + } + } ); + add ( new WebRadioButtonMenuItem ( "Radio item 3", loadIcon ( "menubar/radio3.png" ) ) + { + { + setAccelerator ( Hotkey.C ); + buttonGroup.add ( this ); + } + } ); + } + } ); menuBar.add ( new WebMenu ( "Menu tooltip", loadIcon ( "menubar/tooltip.png" ) ) { { TooltipManager.setTooltip ( this, "Menu tooltip" ); - add ( new WebMenuItem ( "Menu item tooltip", loadIcon ( "menubar/tooltip.png" ) ) + add ( new WebMenuItem ( "Trailing tooltip", loadIcon ( "menubar/tooltip.png" ) ) + { + { + TooltipManager.setTooltip ( this, "Tip", TooltipWay.trailing ); + } + } ); + add ( new WebMenuItem ( "Bottom tooltip", loadIcon ( "menubar/tooltip.png" ) ) { { - TooltipManager.setTooltip ( this, "Menu item tooltip", TooltipWay.trailing ); + TooltipManager.setTooltip ( this, "Tip", TooltipWay.down ); } } ); } diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/check1.png b/src/com/alee/examples/groups/menubar/icons/menubar/check1.png new file mode 100644 index 000000000..0cd3155e9 Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/check1.png differ diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/check2.png b/src/com/alee/examples/groups/menubar/icons/menubar/check2.png new file mode 100644 index 000000000..fe618fc9e Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/check2.png differ diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/radio1.png b/src/com/alee/examples/groups/menubar/icons/menubar/radio1.png new file mode 100644 index 000000000..689d4b841 Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/radio1.png differ diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/radio2.png b/src/com/alee/examples/groups/menubar/icons/menubar/radio2.png new file mode 100644 index 000000000..351866942 Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/radio2.png differ diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/radio3.png b/src/com/alee/examples/groups/menubar/icons/menubar/radio3.png new file mode 100644 index 000000000..e193d530e Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/radio3.png differ diff --git a/src/com/alee/examples/groups/menubar/icons/menubar/states.png b/src/com/alee/examples/groups/menubar/icons/menubar/states.png new file mode 100644 index 000000000..05eed23df Binary files /dev/null and b/src/com/alee/examples/groups/menubar/icons/menubar/states.png differ diff --git a/src/com/alee/extended/filechooser/WebPathField.java b/src/com/alee/extended/filechooser/WebPathField.java index 81ec81021..82a0fdf97 100644 --- a/src/com/alee/extended/filechooser/WebPathField.java +++ b/src/com/alee/extended/filechooser/WebPathField.java @@ -750,8 +750,7 @@ public void actionPerformed ( ActionEvent e ) // todo Apply orientation globally on change, not here WebPathField.this.transferFocus (); SwingUtils.applyOrientation ( menu ); - menu.show ( childs, childs.getComponentOrientation ().isLeftToRight () ? 0 : - childs.getWidth () - menu.getPreferredSize ().width, childs.getHeight () ); + menu.showBelowMiddle ( childs ); } } ); contentPanel.add ( childs ); @@ -794,7 +793,7 @@ public void popupMenuCanceled ( PopupMenuEvent e ) } if ( canShortenPath () ) { - getRootsMenu ().add ( new JPopupMenu.Separator (), 0 ); + getRootsMenu ().addSeparator ( 0 ); } while ( canShortenPath () ) { @@ -927,8 +926,7 @@ public void actionPerformed ( ActionEvent e ) { WebPathField.this.transferFocus (); SwingUtils.applyOrientation ( rootsMenu ); - rootsMenu.show ( rootsArrowButton, rootsArrowButton.getComponentOrientation ().isLeftToRight () ? 0 : - rootsArrowButton.getWidth () - rootsMenu.getPreferredSize ().width, rootsArrowButton.getHeight () ); + rootsMenu.showBelowMiddle ( rootsArrowButton ); } } ); diff --git a/src/com/alee/extended/transition/TransitionUtils.java b/src/com/alee/extended/transition/TransitionUtils.java index 039d4e037..7ef98020d 100644 --- a/src/com/alee/extended/transition/TransitionUtils.java +++ b/src/com/alee/extended/transition/TransitionUtils.java @@ -102,7 +102,7 @@ public static BlockType getActualValue ( final BlockType blockType ) /** * Returns actual curtain type for the specified curtain type. * - * @param blockType curtain type to process + * @param curtainType curtain type to process * @return actual curtain type for the specified curtain type */ public static CurtainType getActualValue ( final CurtainType curtainType ) @@ -121,7 +121,7 @@ public static CurtainType getActualValue ( final CurtainType curtainType ) /** * Returns actual slide type for the specified slide type. * - * @param blockType slide type to process + * @param slideType slide type to process * @return actual slide type for the specified slide type */ public static SlideType getActualValue ( final SlideType slideType ) @@ -140,7 +140,7 @@ public static SlideType getActualValue ( final SlideType slideType ) /** * Returns actual zoom type for the specified zoom type. * - * @param blockType zoom type to process + * @param zoomType zoom type to process * @return actual zoom type for the specified zoom type */ public static ZoomType getActualValue ( final ZoomType zoomType ) diff --git a/src/com/alee/extended/tree/WebAsyncTreeFilterField.java b/src/com/alee/extended/tree/WebAsyncTreeFilterField.java index 6edc40e0f..c2f52f022 100644 --- a/src/com/alee/extended/tree/WebAsyncTreeFilterField.java +++ b/src/com/alee/extended/tree/WebAsyncTreeFilterField.java @@ -27,6 +27,7 @@ import com.alee.utils.swing.DocumentChangeListener; import com.alee.utils.text.TextProvider; +import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; @@ -44,6 +45,18 @@ public class WebAsyncTreeFilterField extends WebTextField { + /** + * Used icons. + */ + public static final ImageIcon settingsIcon = + new ImageIcon ( WebAsyncTreeFilterField.class.getResource ( "icons/filter/settings.png" ) ); + public static final ImageIcon matchCaseIcon = + new ImageIcon ( WebAsyncTreeFilterField.class.getResource ( "icons/filter/matchCase.png" ) ); + public static final ImageIcon useSpaceAsSeparatorIcon = + new ImageIcon ( WebAsyncTreeFilterField.class.getResource ( "icons/filter/useSpaceAsSeparator.png" ) ); + public static final ImageIcon searchFromStartIcon = + new ImageIcon ( WebAsyncTreeFilterField.class.getResource ( "icons/filter/searchFromStart.png" ) ); + /** * Async tree to which this field should apply filtering. */ @@ -107,7 +120,7 @@ protected void init () protected void initFilterIcon () { - filterIcon = new WebImage ( WebAsyncTreeFilterField.class, "icons/filter.png" ); + filterIcon = new WebImage ( WebAsyncTreeFilterField.class, "icons/filter/settings.png" ); filterIcon.setMargin ( 0, 2, 0, 2 ); filterIcon.setCursor ( Cursor.getDefaultCursor () ); filterIcon.addMouseListener ( new MouseAdapter () @@ -115,7 +128,7 @@ protected void initFilterIcon () @Override public void mousePressed ( final MouseEvent e ) { - settingsMenu.showUnder ( WebAsyncTreeFilterField.this ); + settingsMenu.showBelowMiddle ( filterIcon ); } } ); setLeadingComponent ( filterIcon ); @@ -125,7 +138,7 @@ protected void initSettingsMenu () { settingsMenu = new WebPopupMenu (); - matchCaseItem = new WebCheckBoxMenuItem ( "Match case" ); + matchCaseItem = new WebCheckBoxMenuItem ( "Match case", matchCaseIcon ); matchCaseItem.addActionListener ( new ActionListener () { @Override @@ -137,7 +150,7 @@ public void actionPerformed ( final ActionEvent e ) } ); settingsMenu.add ( matchCaseItem ); - useSpaceAsSeparatorItem = new WebCheckBoxMenuItem ( "Use space as separator" ); + useSpaceAsSeparatorItem = new WebCheckBoxMenuItem ( "Use space as separator", useSpaceAsSeparatorIcon ); useSpaceAsSeparatorItem.addActionListener ( new ActionListener () { @Override @@ -149,7 +162,7 @@ public void actionPerformed ( final ActionEvent e ) } ); settingsMenu.add ( useSpaceAsSeparatorItem ); - searchFromStartItem = new WebCheckBoxMenuItem ( "Search from beginning" ); + searchFromStartItem = new WebCheckBoxMenuItem ( "Search from beginning", searchFromStartIcon ); searchFromStartItem.addActionListener ( new ActionListener () { @Override diff --git a/src/com/alee/extended/tree/icons/filter/matchCase.png b/src/com/alee/extended/tree/icons/filter/matchCase.png new file mode 100644 index 000000000..af6ee6e42 Binary files /dev/null and b/src/com/alee/extended/tree/icons/filter/matchCase.png differ diff --git a/src/com/alee/extended/tree/icons/filter/searchFromStart.png b/src/com/alee/extended/tree/icons/filter/searchFromStart.png new file mode 100644 index 000000000..2df6c5194 Binary files /dev/null and b/src/com/alee/extended/tree/icons/filter/searchFromStart.png differ diff --git a/src/com/alee/extended/tree/icons/filter.png b/src/com/alee/extended/tree/icons/filter/settings.png similarity index 100% rename from src/com/alee/extended/tree/icons/filter.png rename to src/com/alee/extended/tree/icons/filter/settings.png diff --git a/src/com/alee/extended/tree/icons/filter/useSpaceAsSeparator.png b/src/com/alee/extended/tree/icons/filter/useSpaceAsSeparator.png new file mode 100644 index 000000000..56644af34 Binary files /dev/null and b/src/com/alee/extended/tree/icons/filter/useSpaceAsSeparator.png differ diff --git a/src/com/alee/extended/window/TestFrame.java b/src/com/alee/extended/window/TestFrame.java index 0e0ddbfa6..070d6f969 100644 --- a/src/com/alee/extended/window/TestFrame.java +++ b/src/com/alee/extended/window/TestFrame.java @@ -667,10 +667,26 @@ public TestFrame displayFrame () */ public static String getFrameTitle ( final Component component ) { + // Tested class name final String className = ( component != null ? ReflectUtils.getClassName ( component.getClass () ) : "TestFrame" ) + " "; - final String libVersion = "[ " + VersionManager.getLibraryVersion ().toString () + " ] "; + + // WebLaF version + String libVersion = ""; + try + { + libVersion = "[ " + VersionManager.getLibraryVersion ().toString () + " ] "; + } + catch ( Throwable e ) + { + // Cannot load version now + } + + // Undelying OS name and version final String osVersion = "[ " + SystemUtils.getOsName () + " " + SystemUtils.getOsArch () + " ] "; + + // JRE version final String jreVersion = "[ JRE " + SystemUtils.getJavaVersionString () + " " + SystemUtils.getJreArch () + "-bit ]"; + return className + libVersion + osVersion + jreVersion; } } \ No newline at end of file diff --git a/src/com/alee/laf/WebLookAndFeel.java b/src/com/alee/laf/WebLookAndFeel.java index 4c531b56e..4ca86c958 100644 --- a/src/com/alee/laf/WebLookAndFeel.java +++ b/src/com/alee/laf/WebLookAndFeel.java @@ -456,18 +456,13 @@ protected void initComponentDefaults ( final UIDefaults table ) table.put ( "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE ); table.put ( "Tree.drawDashedFocusIndicator", Boolean.FALSE ); - // Disabled foreground color - table.put ( "MenuItem.disabledForeground", StyleConstants.disabledTextColor ); - // We don't need uneven heights - table.put ( "MenuItem.evenHeight", Boolean.TRUE ); - - // // JMenu expand spacing - // // Up-down menu expand - // table.put ( "Menu.menuPopupOffsetX", StyleConstants.shadeWidth ); - // table.put ( "Menu.menuPopupOffsetY", -StyleConstants.shadeWidth / 2 ); - // // Left-right menu expand - // table.put ( "Menu.submenuPopupOffsetX", StyleConstants.shadeWidth / 2 ); - // table.put ( "Menu.submenuPopupOffsetY", 0 ); + // JMenu expand spacing + // Up-down menu expand + table.put ( "Menu.menuPopupOffsetX", 0 ); + table.put ( "Menu.menuPopupOffsetY", 0 ); + // Left-right menu expand + table.put ( "Menu.submenuPopupOffsetX", 0 ); + table.put ( "Menu.submenuPopupOffsetY", 0 ); // Table defaults table.put ( "Table.cellNoFocusBorder", LafUtils.createWebBorder ( 1, 1, 1, 1 ) ); diff --git a/src/com/alee/laf/combobox/WebComboBoxCellRenderer.java b/src/com/alee/laf/combobox/WebComboBoxCellRenderer.java index a05f7933e..8ba70d05f 100644 --- a/src/com/alee/laf/combobox/WebComboBoxCellRenderer.java +++ b/src/com/alee/laf/combobox/WebComboBoxCellRenderer.java @@ -26,13 +26,13 @@ public class WebComboBoxCellRenderer extends DefaultListCellRenderer { - private JComboBox comboBox; - private WebComboBoxElement renderer; + protected Component component; + protected WebComboBoxElement renderer; - public WebComboBoxCellRenderer ( JComboBox comboBox ) + public WebComboBoxCellRenderer ( Component component ) { super (); - this.comboBox = comboBox; + this.component = component; this.renderer = new WebComboBoxElement (); } @@ -49,8 +49,8 @@ public Component getListCellRendererComponent ( JList list, Object value, int in renderer.setSelected ( isSelected ); renderer.updatePainter (); - renderer.setEnabled ( comboBox.isEnabled () ); - renderer.setFont ( comboBox.getFont () ); + renderer.setEnabled ( component.isEnabled () ); + renderer.setFont ( component.getFont () ); renderer.setForeground ( isSelected ? list.getSelectionForeground () : list.getForeground () ); renderer.setComponentOrientation ( list.getComponentOrientation () ); diff --git a/src/com/alee/laf/combobox/WebComboBoxElementPainter.java b/src/com/alee/laf/combobox/WebComboBoxElementPainter.java index 5784b5180..0389dd637 100644 --- a/src/com/alee/laf/combobox/WebComboBoxElementPainter.java +++ b/src/com/alee/laf/combobox/WebComboBoxElementPainter.java @@ -18,8 +18,7 @@ package com.alee.laf.combobox; import com.alee.extended.painter.DefaultPainter; -import com.alee.laf.StyleConstants; -import com.alee.utils.LafUtils; +import com.alee.laf.menu.WebMenuItemStyle; import java.awt.*; @@ -37,9 +36,7 @@ public WebComboBoxElementPainter () @Override public Insets getMargin ( WebComboBoxElement element ) { - return element.getIndex () != -1 ? - new Insets ( element.getIndex () == 0 ? 2 : 3, 2, element.getIndex () + 1 == element.getTotalElements () ? 2 : 3, 2 ) : - new Insets ( 2, 2, 2, 2 ); + return element.getIndex () != -1 ? new Insets ( 3, 5, 3, 5 ) : new Insets ( 2, 2, 2, 2 ); } @Override @@ -68,19 +65,9 @@ protected void paintBoxBackground ( Graphics2D g2d, WebComboBoxElement element ) protected void paintSelectedBackground ( Graphics2D g2d, WebComboBoxElement element ) { // Background - g2d.setPaint ( LafUtils.getWebGradientPaint ( 0, 0, 0, element.getHeight () ) ); + g2d.setPaint ( + new GradientPaint ( 0, 0, WebMenuItemStyle.selectedTopBg, 0, element.getHeight (), WebMenuItemStyle.selectedBottomBg ) ); g2d.fillRect ( 0, 0, element.getWidth (), element.getHeight () ); - - // Border - g2d.setPaint ( element.isEnabled () ? StyleConstants.darkBorderColor : StyleConstants.disabledBorderColor ); - if ( element.getIndex () != 0 ) - { - g2d.drawLine ( 0, 0, element.getWidth () - 1, 0 ); - } - if ( element.getIndex () < element.getTotalElements () - 1 ) - { - g2d.drawLine ( 0, element.getHeight () - 1, element.getWidth () - 1, element.getHeight () - 1 ); - } } @SuppressWarnings ("UnusedParameters") diff --git a/src/com/alee/laf/combobox/WebComboBoxUI.java b/src/com/alee/laf/combobox/WebComboBoxUI.java index 3691dfd01..7b8be76e2 100644 --- a/src/com/alee/laf/combobox/WebComboBoxUI.java +++ b/src/com/alee/laf/combobox/WebComboBoxUI.java @@ -61,7 +61,7 @@ public class WebComboBoxUI extends BasicComboBoxUI implements ShapeProvider private boolean drawFocus = WebComboBoxStyle.drawFocus; private boolean mouseWheelScrollingEnabled = WebComboBoxStyle.mouseWheelScrollingEnabled; - private MouseWheelListener mwl = null; + private MouseWheelListener mouseWheelListener = null; private WebButton arrow = null; @SuppressWarnings ("UnusedParameters") @@ -95,7 +95,7 @@ public void installUI ( JComponent c ) } // Rollover scrolling listener - mwl = new MouseWheelListener () + mouseWheelListener = new MouseWheelListener () { @Override public void mouseWheelMoved ( MouseWheelEvent e ) @@ -112,7 +112,7 @@ public void mouseWheelMoved ( MouseWheelEvent e ) } } }; - comboBox.addMouseWheelListener ( mwl ); + comboBox.addMouseWheelListener ( mouseWheelListener ); } /** @@ -121,7 +121,8 @@ public void mouseWheelMoved ( MouseWheelEvent e ) @Override public void uninstallUI ( JComponent c ) { - c.removeMouseWheelListener ( mwl ); + c.removeMouseWheelListener ( mouseWheelListener ); + mouseWheelListener = null; arrow = null; super.uninstallUI ( c ); @@ -245,24 +246,24 @@ protected ComboPopup createPopup () @Override protected JScrollPane createScroller () { - JScrollPane scroll = super.createScroller (); + final JScrollPane scroll = super.createScroller (); if ( WebLookAndFeel.isInstalled () ) { scroll.setOpaque ( false ); scroll.getViewport ().setOpaque ( false ); } - ScrollPaneUI scrollPaneUI = scroll.getUI (); + final ScrollPaneUI scrollPaneUI = scroll.getUI (); if ( scrollPaneUI instanceof WebScrollPaneUI ) { - WebScrollPaneUI webScrollPaneUI = ( WebScrollPaneUI ) scrollPaneUI; + final WebScrollPaneUI webScrollPaneUI = ( WebScrollPaneUI ) scrollPaneUI; webScrollPaneUI.setDrawBorder ( false ); - ScrollBarUI scrollBarUI = scroll.getVerticalScrollBar ().getUI (); + final ScrollBarUI scrollBarUI = scroll.getVerticalScrollBar ().getUI (); if ( scrollBarUI instanceof WebScrollBarUI ) { - WebScrollBarUI webScrollBarUI = ( WebScrollBarUI ) scrollBarUI; - webScrollBarUI.setScrollBorder ( webScrollPaneUI.getDarkBorder () ); + final WebScrollBarUI webScrollBarUI = ( WebScrollBarUI ) scrollBarUI; + webScrollBarUI.setDrawBorder ( false ); } } @@ -272,13 +273,15 @@ protected JScrollPane createScroller () @Override protected JList createList () { - JList list = super.createList (); + final JList list = super.createList (); // list.setOpaque ( false ); - ListUI listUI = list.getUI (); + final ListUI listUI = list.getUI (); if ( listUI instanceof WebListUI ) { - ( ( WebListUI ) listUI ).setHighlightRolloverCell ( false ); + final WebListUI webListUI = ( WebListUI ) listUI; + webListUI.setHighlightRolloverCell ( false ); + webListUI.setDecorateSelection ( false ); } return list; @@ -296,7 +299,7 @@ protected void configurePopup () * {@inheritDoc} */ @Override - public void popupMenuWillBecomeVisible ( PopupMenuEvent e ) + public void popupMenuWillBecomeVisible ( final PopupMenuEvent e ) { arrow.setIcon ( collapseIcon ); @@ -308,7 +311,7 @@ public void popupMenuWillBecomeVisible ( PopupMenuEvent e ) * {@inheritDoc} */ @Override - public void popupMenuWillBecomeInvisible ( PopupMenuEvent e ) + public void popupMenuWillBecomeInvisible ( final PopupMenuEvent e ) { arrow.setIcon ( expandIcon ); } @@ -317,7 +320,7 @@ public void popupMenuWillBecomeInvisible ( PopupMenuEvent e ) * {@inheritDoc} */ @Override - public void popupMenuCanceled ( PopupMenuEvent e ) + public void popupMenuCanceled ( final PopupMenuEvent e ) { arrow.setIcon ( expandIcon ); } @@ -327,61 +330,40 @@ public void popupMenuCanceled ( PopupMenuEvent e ) @Override public void show () { - // informing listeners comboBox.firePopupMenuWillBecomeVisible (); - // Updating list selection setListSelection ( comboBox.getSelectedIndex () ); - // Updating popup size - boolean cellEditor = isComboboxCellEditor (); - setupPopupSize ( cellEditor ); - - // Displaying popup - ComponentOrientation orientation = comboBox.getComponentOrientation (); - int sideShear = ( drawBorder ? shadeWidth : ( cellEditor ? -1 : 0 ) ); - int topShear = ( drawBorder ? shadeWidth : 0 ) - ( cellEditor ? 0 : 1 ); - show ( comboBox, orientation.isLeftToRight () ? sideShear : comboBox.getWidth () - getWidth () - sideShear, - comboBox.getHeight () - topShear ); + final Point location = getPopupLocation (); + show ( comboBox, location.x, location.y ); } - private void setupPopupSize ( boolean cellEditor ) + private void setListSelection ( int selectedIndex ) { - Dimension popupSize = comboBox.getSize (); - if ( drawBorder ) + if ( selectedIndex == -1 ) { - popupSize.width -= shadeWidth * 2; + list.clearSelection (); } - if ( cellEditor ) + else { - popupSize.width += 2; + list.setSelectedIndex ( selectedIndex ); + list.ensureIndexIsVisible ( selectedIndex ); } + } - Insets insets = getInsets (); - popupSize.setSize ( popupSize.width - ( insets.right + insets.left ), - getPopupHeightForRowCount ( comboBox.getMaximumRowCount () ) ); - - Rectangle popupBounds = computePopupBounds ( 0, comboBox.getBounds ().height, popupSize.width, popupSize.height ); - Dimension scrollSize = popupBounds.getSize (); + private Point getPopupLocation () + { + final Dimension comboSize = comboBox.getSize (); + comboSize.setSize ( comboSize.width - 2, getPopupHeightForRowCount ( comboBox.getMaximumRowCount () ) ); + final Rectangle popupBounds = computePopupBounds ( 0, comboBox.getBounds ().height, comboSize.width, comboSize.height ); + final Dimension scrollSize = popupBounds.getSize (); scroller.setMaximumSize ( scrollSize ); scroller.setPreferredSize ( scrollSize ); scroller.setMinimumSize ( scrollSize ); - list.revalidate (); - } - private void setListSelection ( int selectedIndex ) - { - if ( selectedIndex == -1 ) - { - list.clearSelection (); - } - else - { - list.setSelectedIndex ( selectedIndex ); - list.ensureIndexIsVisible ( selectedIndex ); - } + return popupBounds.getLocation (); } }; } @@ -390,7 +372,7 @@ public boolean isComboboxCellEditor () { if ( comboBox != null ) { - Object cellEditor = comboBox.getClientProperty ( WebDefaultCellEditor.COMBOBOX_CELL_EDITOR ); + final Object cellEditor = comboBox.getClientProperty ( WebDefaultCellEditor.COMBOBOX_CELL_EDITOR ); return cellEditor != null && ( Boolean ) cellEditor; } else diff --git a/src/com/alee/laf/filechooser/WebFileChooserPanel.java b/src/com/alee/laf/filechooser/WebFileChooserPanel.java index 2798f6f23..5502be474 100644 --- a/src/com/alee/laf/filechooser/WebFileChooserPanel.java +++ b/src/com/alee/laf/filechooser/WebFileChooserPanel.java @@ -36,9 +36,9 @@ import com.alee.laf.StyleConstants; import com.alee.laf.button.WebButton; import com.alee.laf.combobox.WebComboBox; +import com.alee.laf.combobox.WebComboBoxCellRenderer; import com.alee.laf.label.WebLabel; import com.alee.laf.list.WebList; -import com.alee.laf.list.WebListCellRenderer; import com.alee.laf.list.editor.ListEditAdapter; import com.alee.laf.menu.WebPopupMenu; import com.alee.laf.menu.WebRadioButtonMenuItem; @@ -368,7 +368,7 @@ public void actionPerformed ( ActionEvent e ) final WebList historyList = new WebList ( navigationHistory ); historyList.setVisibleRowCount ( Math.min ( 10, navigationHistory.size () ) ); historyList.setRolloverSelectionEnabled ( true ); - historyList.setCellRenderer ( new WebListCellRenderer () + historyList.setCellRenderer ( new WebComboBoxCellRenderer ( historyList ) { @Override public Component getListCellRendererComponent ( JList list, Object value, int index, boolean isSelected, @@ -379,17 +379,17 @@ public Component getListCellRendererComponent ( JList list, Object value, int in final File file = ( File ) value; if ( file == null ) { - setIcon ( FileUtils.getMyComputerIcon () ); - setText ( LanguageManager.get ( "weblaf.filechooser.root" ) ); + renderer.setIcon ( FileUtils.getMyComputerIcon () ); + renderer.setText ( LanguageManager.get ( "weblaf.filechooser.root" ) ); } else { - setIcon ( FileUtils.getFileIcon ( file ) ); - setText ( FileUtils.getDisplayFileName ( file ) ); + renderer.setIcon ( FileUtils.getFileIcon ( file ) ); + renderer.setText ( FileUtils.getDisplayFileName ( file ) ); } - setBoldFont ( index == currentHistoryIndex ); + renderer.setBoldFont ( index == currentHistoryIndex ); - return this; + return renderer; } } ); historyList.addMouseListener ( new MouseAdapter () @@ -401,18 +401,11 @@ public void mouseReleased ( MouseEvent e ) historyPopup.setVisible ( false ); } } ); - final WebScrollPane scrollPane = new WebScrollPane ( historyList ); + final WebScrollPane scrollPane = new WebScrollPane ( historyList, false, false ); scrollPane.setShadeWidth ( 0 ); historyPopup.add ( scrollPane ); - if ( history.getComponentOrientation ().isLeftToRight () ) - { - historyPopup.show ( history, 0, history.getHeight () ); - } - else - { - historyPopup.show ( history, history.getWidth () - historyPopup.getPreferredSize ().width, history.getHeight () ); - } + historyPopup.showBelowMiddle ( history ); historyList.setSelectedIndex ( currentHistoryIndex ); historyList.scrollToCell ( currentHistoryIndex ); @@ -589,14 +582,7 @@ public void actionPerformed ( ActionEvent e ) viewGroup.add ( tiles ); viewGroup.add ( table ); - if ( view.getComponentOrientation ().isLeftToRight () ) - { - viewChoose.show ( view, view.getWidth () - viewChoose.getPreferredSize ().width, view.getHeight () ); - } - else - { - viewChoose.show ( view, 0, view.getHeight () ); - } + viewChoose.showBelowMiddle ( view ); } } ); diff --git a/src/com/alee/laf/menu/MenuItemChangeListener.java b/src/com/alee/laf/menu/MenuItemChangeListener.java new file mode 100644 index 000000000..0c12a205c --- /dev/null +++ b/src/com/alee/laf/menu/MenuItemChangeListener.java @@ -0,0 +1,82 @@ +/* +* This file is part of WebLookAndFeel library. +* +* WebLookAndFeel library is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WebLookAndFeel library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with WebLookAndFeel library. If not, see . + */ + +package com.alee.laf.menu; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; + +/** + * Special menu item change listener required to update popup menu decoration properly. + * + * @author Mikle Garin + */ + +public class MenuItemChangeListener implements ChangeListener +{ + /** + * Listened menu item. + */ + protected JMenuItem menuItem; + + /** + * Constructs new menu item change listener. + * + * @param menuItem menu item to listen + */ + public MenuItemChangeListener ( final JMenuItem menuItem ) + { + super (); + this.menuItem = menuItem; + } + + /** + * {@inheritDoc} + */ + @Override + public void stateChanged ( final ChangeEvent e ) + { + final Container parent = menuItem.getParent (); + if ( parent instanceof JPopupMenu ) + { + final JPopupMenu popupMenu = ( JPopupMenu ) parent; + if ( popupMenu.getUI () instanceof WebPopupMenuUI ) + { + final WebPopupMenuUI ui = ( WebPopupMenuUI ) popupMenu.getUI (); + if ( ui.getPopupMenuStyle () == PopupMenuStyle.dropdown ) + { + // Checking whether this item state change affect the corner + final int zOrder = popupMenu.getComponentZOrder ( menuItem ); + if ( ui.getCornerSide () == SwingConstants.NORTH && zOrder == 0 ) + { + // Repainting only corner bounds + popupMenu.repaint ( 0, 0, popupMenu.getWidth (), menuItem.getBounds ().y ); + } + else if ( ui.getCornerSide () == SwingConstants.SOUTH && zOrder == popupMenu.getComponentCount () - 1 ) + { + // Repainting only corner bounds + final Rectangle itemBounds = menuItem.getBounds (); + final int y = itemBounds.y + itemBounds.height; + popupMenu.repaint ( 0, y, popupMenu.getWidth (), popupMenu.getHeight () - y ); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/com/alee/laf/menu/MenuItemLayoutHelper.java b/src/com/alee/laf/menu/MenuItemLayoutHelper.java deleted file mode 100644 index d37c1d725..000000000 --- a/src/com/alee/laf/menu/MenuItemLayoutHelper.java +++ /dev/null @@ -1,1459 +0,0 @@ -/* - * This file is part of WebLookAndFeel library. - * - * WebLookAndFeel library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * WebLookAndFeel library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with WebLookAndFeel library. If not, see . - */ - -package com.alee.laf.menu; - -import com.alee.utils.SwingUtils; - -import javax.swing.*; -import javax.swing.plaf.basic.BasicHTML; -import javax.swing.text.View; -import java.awt.*; -import java.awt.event.KeyEvent; -import java.util.HashMap; -import java.util.Map; - -/** - * Calculates preferred size and layouts menu items. - */ - -public class MenuItemLayoutHelper -{ - /* Client Property keys for calculation of maximal widths */ - public static final StringUIClientPropertyKey MAX_ARROW_WIDTH = new StringUIClientPropertyKey ( "maxArrowWidth" ); - public static final StringUIClientPropertyKey MAX_CHECK_WIDTH = new StringUIClientPropertyKey ( "maxCheckWidth" ); - public static final StringUIClientPropertyKey MAX_ICON_WIDTH = new StringUIClientPropertyKey ( "maxIconWidth" ); - public static final StringUIClientPropertyKey MAX_TEXT_WIDTH = new StringUIClientPropertyKey ( "maxTextWidth" ); - public static final StringUIClientPropertyKey MAX_ACC_WIDTH = new StringUIClientPropertyKey ( "maxAccWidth" ); - public static final StringUIClientPropertyKey MAX_LABEL_WIDTH = new StringUIClientPropertyKey ( "maxLabelWidth" ); - public static final StringUIClientPropertyKey BASICMENUITEMUI_MAX_TEXT_OFFSET = new StringUIClientPropertyKey ( "maxTextOffset" ); - - private JMenuItem mi; - private JComponent miParent; - - private Font font; - private Font accFont; - private FontMetrics fm; - private FontMetrics accFm; - - private Icon icon; - private Icon checkIcon; - private Icon arrowIcon; - private String text; - private String accText; - - private boolean isColumnLayout; - private boolean useCheckAndArrow; - private boolean isLeftToRight; - private boolean isTopLevelMenu; - private View htmlView; - - private int verticalAlignment; - private int horizontalAlignment; - private int verticalTextPosition; - private int horizontalTextPosition; - private int gap; - private int leadingGap; - private int afterCheckIconGap; - private int minTextOffset; - - private Rectangle viewRect; - - private RectSize iconSize; - private RectSize textSize; - private RectSize accSize; - private RectSize checkSize; - private RectSize arrowSize; - private RectSize labelSize; - - /** - * The empty protected constructor is necessary for derived classes. - */ - protected MenuItemLayoutHelper () - { - } - - public MenuItemLayoutHelper ( JMenuItem mi, Icon checkIcon, Icon arrowIcon, Rectangle viewRect, int gap, String accDelimiter, - boolean isLeftToRight, Font font, Font accFont, boolean useCheckAndArrow, String propertyPrefix ) - { - reset ( mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter, isLeftToRight, font, accFont, useCheckAndArrow, propertyPrefix ); - } - - protected void reset ( JMenuItem mi, Icon checkIcon, Icon arrowIcon, Rectangle viewRect, int gap, String accDelimiter, - boolean isLeftToRight, Font font, Font accFont, boolean useCheckAndArrow, String propertyPrefix ) - { - this.mi = mi; - this.miParent = getMenuItemParent ( mi ); - this.accText = getAccText ( accDelimiter ); - this.verticalAlignment = mi.getVerticalAlignment (); - this.horizontalAlignment = mi.getHorizontalAlignment (); - this.verticalTextPosition = mi.getVerticalTextPosition (); - this.horizontalTextPosition = mi.getHorizontalTextPosition (); - this.useCheckAndArrow = useCheckAndArrow; - this.font = font; - this.accFont = accFont; - this.fm = mi.getFontMetrics ( font ); - this.accFm = mi.getFontMetrics ( accFont ); - this.isLeftToRight = isLeftToRight; - this.isColumnLayout = isColumnLayout ( isLeftToRight, horizontalAlignment, horizontalTextPosition, verticalTextPosition ); - this.isTopLevelMenu = this.miParent == null; - this.checkIcon = checkIcon; - this.icon = mi.getIcon (); - this.arrowIcon = arrowIcon; - this.text = mi.getText (); - this.gap = gap; - this.afterCheckIconGap = getAfterCheckIconGap ( propertyPrefix ); - this.minTextOffset = getMinTextOffset ( propertyPrefix ); - this.htmlView = ( View ) mi.getClientProperty ( BasicHTML.propertyKey ); - this.viewRect = viewRect; - - this.iconSize = new RectSize (); - this.textSize = new RectSize (); - this.accSize = new RectSize (); - this.checkSize = new RectSize (); - this.arrowSize = new RectSize (); - this.labelSize = new RectSize (); - calcWidthsAndHeights (); - setOriginalWidths (); - calcMaxWidths (); - - this.leadingGap = getLeadingGap ( propertyPrefix ); - calcMaxTextOffset ( viewRect ); - } - - private void setOriginalWidths () - { - iconSize.origWidth = iconSize.width; - textSize.origWidth = textSize.width; - accSize.origWidth = accSize.width; - checkSize.origWidth = checkSize.width; - arrowSize.origWidth = arrowSize.width; - } - - private String getAccText ( String acceleratorDelimiter ) - { - String accText = ""; - KeyStroke accelerator = mi.getAccelerator (); - if ( accelerator != null ) - { - int modifiers = accelerator.getModifiers (); - if ( modifiers > 0 ) - { - accText = KeyEvent.getKeyModifiersText ( modifiers ); - accText += acceleratorDelimiter; - } - int keyCode = accelerator.getKeyCode (); - if ( keyCode != 0 ) - { - accText += KeyEvent.getKeyText ( keyCode ); - } - else - { - accText += accelerator.getKeyChar (); - } - } - return accText; - } - - private int getMinTextOffset ( String propertyPrefix ) - { - int minimumTextOffset = 0; - Object minimumTextOffsetObject = UIManager.get ( propertyPrefix + ".minimumTextOffset" ); - if ( minimumTextOffsetObject instanceof Integer ) - { - minimumTextOffset = ( Integer ) minimumTextOffsetObject; - } - return minimumTextOffset; - } - - private int getAfterCheckIconGap ( String propertyPrefix ) - { - int afterCheckIconGap = gap; - Object afterCheckIconGapObject = UIManager.get ( propertyPrefix + ".afterCheckIconGap" ); - if ( afterCheckIconGapObject instanceof Integer ) - { - afterCheckIconGap = ( Integer ) afterCheckIconGapObject; - } - return afterCheckIconGap; - } - - private int getLeadingGap ( String propertyPrefix ) - { - if ( checkSize.getMaxWidth () > 0 ) - { - return getCheckOffset ( propertyPrefix ); - } - else - { - return gap; // There is no any check icon - } - } - - private int getCheckOffset ( String propertyPrefix ) - { - int checkIconOffset = gap; - Object checkIconOffsetObject = UIManager.get ( propertyPrefix + ".checkIconOffset" ); - if ( checkIconOffsetObject instanceof Integer ) - { - checkIconOffset = ( Integer ) checkIconOffsetObject; - } - return checkIconOffset; - } - - protected void calcWidthsAndHeights () - { - // iconRect - if ( icon != null ) - { - iconSize.width = icon.getIconWidth (); - iconSize.height = icon.getIconHeight (); - } - else if ( useCheckAndArrow && arrowIcon != null ) - { - // Fix for JMenu w/o icon width - iconSize.width = 16; - iconSize.height = 16; - } - - // accRect - if ( !accText.equals ( "" ) ) - { - accSize.width = SwingUtils.stringWidth ( accFm, accText ); - accSize.height = accFm.getHeight (); - } - - // textRect - if ( text == null ) - { - text = ""; - } - else if ( !text.equals ( "" ) ) - { - if ( htmlView != null ) - { - // Text is HTML - textSize.width = ( int ) htmlView.getPreferredSpan ( View.X_AXIS ); - textSize.height = ( int ) htmlView.getPreferredSpan ( View.Y_AXIS ); - } - else - { - // Text isn't HTML - textSize.width = SwingUtils.stringWidth ( fm, text ); - textSize.height = fm.getHeight (); - } - } - - if ( useCheckAndArrow ) - { - // checkIcon - if ( checkIcon != null ) - { - checkSize.width = checkIcon.getIconWidth (); - checkSize.height = checkIcon.getIconHeight (); - } - // arrowRect - if ( arrowIcon != null ) - { - arrowSize.width = arrowIcon.getIconWidth (); - arrowSize.height = arrowIcon.getIconHeight (); - } - } - - // labelRect - if ( isColumnLayout ) - { - labelSize.width = iconSize.width + gap + textSize.width; - labelSize.height = max ( checkSize.height, iconSize.height, textSize.height, accSize.height, arrowSize.height ); - } - else - { - Rectangle textRect = new Rectangle (); - Rectangle iconRect = new Rectangle (); - SwingUtilities.layoutCompoundLabel ( mi, fm, text, icon, verticalAlignment, horizontalAlignment, verticalTextPosition, - horizontalTextPosition, viewRect, iconRect, textRect, gap ); - - Rectangle labelRect = iconRect.union ( textRect ); - labelSize.height = labelRect.height; - labelSize.width = labelRect.width; - } - } - - protected void calcMaxWidths () - { - calcMaxWidth ( checkSize, MAX_CHECK_WIDTH ); - calcMaxWidth ( arrowSize, MAX_ARROW_WIDTH ); - calcMaxWidth ( accSize, MAX_ACC_WIDTH ); - - if ( isColumnLayout ) - { - calcMaxWidth ( iconSize, MAX_ICON_WIDTH ); - calcMaxWidth ( textSize, MAX_TEXT_WIDTH ); - int curGap = gap; - if ( ( iconSize.getMaxWidth () == 0 ) || ( textSize.getMaxWidth () == 0 ) ) - { - curGap = 0; - } - labelSize.maxWidth = calcMaxValue ( MAX_LABEL_WIDTH, iconSize.maxWidth + textSize.maxWidth + curGap ); - } - else - { - // We shouldn't use current icon and text widths - // in maximal widths calculation for complex layout. - iconSize.maxWidth = getParentIntProperty ( MAX_ICON_WIDTH ); - calcMaxWidth ( labelSize, MAX_LABEL_WIDTH ); - // If maxLabelWidth is wider - // than the widest icon + the widest text + gap, - // we should update the maximal text witdh - int candidateTextWidth = labelSize.maxWidth - iconSize.maxWidth; - if ( iconSize.maxWidth > 0 ) - { - candidateTextWidth -= gap; - } - textSize.maxWidth = calcMaxValue ( MAX_TEXT_WIDTH, candidateTextWidth ); - } - } - - protected void calcMaxWidth ( RectSize rs, Object key ) - { - rs.maxWidth = calcMaxValue ( key, rs.width ); - } - - /** - * Calculates and returns maximal value through specified parent component client property. - * - * @param propertyName name of the property, which stores the maximal value. - * @param value a value which pretends to be maximal - * @return maximal value among the parent property and the value. - */ - protected int calcMaxValue ( Object propertyName, int value ) - { - // Get maximal value from parent client property - int maxValue = getParentIntProperty ( propertyName ); - // Store new maximal width in parent client property - if ( value > maxValue ) - { - if ( miParent != null ) - { - miParent.putClientProperty ( propertyName, value ); - } - return value; - } - else - { - return maxValue; - } - } - - /** - * Returns parent client property as int. - * - * @param propertyName name of the parent property. - * @return value of the property as int. - */ - protected int getParentIntProperty ( Object propertyName ) - { - Object value = null; - if ( miParent != null ) - { - value = miParent.getClientProperty ( propertyName ); - } - if ( ( value == null ) || !( value instanceof Integer ) ) - { - value = 0; - } - return ( Integer ) value; - } - - public static boolean isColumnLayout ( boolean isLeftToRight, JMenuItem mi ) - { - assert ( mi != null ); - return isColumnLayout ( isLeftToRight, mi.getHorizontalAlignment (), mi.getHorizontalTextPosition (), - mi.getVerticalTextPosition () ); - } - - /** - * Answers should we do column layout for a menu item or not. We do it when a user doesn't set any alignmentst set any alignments and - * text positions manually, except the vertical alignment. - */ - public static boolean isColumnLayout ( boolean isLeftToRight, int horizontalAlignment, int horizontalTextPosition, - int verticalTextPosition ) - { - if ( verticalTextPosition != SwingConstants.CENTER ) - { - return false; - } - if ( isLeftToRight ) - { - if ( horizontalAlignment != SwingConstants.LEADING && horizontalAlignment != SwingConstants.LEFT ) - { - return false; - } - if ( horizontalTextPosition != SwingConstants.TRAILING && horizontalTextPosition != SwingConstants.RIGHT ) - { - return false; - } - } - else - { - if ( horizontalAlignment != SwingConstants.LEADING && horizontalAlignment != SwingConstants.RIGHT ) - { - return false; - } - if ( horizontalTextPosition != SwingConstants.TRAILING && horizontalTextPosition != SwingConstants.LEFT ) - { - return false; - } - } - return true; - } - - /** - * Calculates maximal text offset. It is required for some L&Fs (ex: Vista L&F). The offset is meaningful only for L2R column layout. - * - * @param viewRect the rectangle, the maximal text offset will be calculated for. - */ - private void calcMaxTextOffset ( Rectangle viewRect ) - { - if ( !isColumnLayout || !isLeftToRight ) - { - return; - } - - // Calculate the current text offset - int offset = viewRect.x + leadingGap + checkSize.maxWidth + afterCheckIconGap + - iconSize.maxWidth + gap; - if ( checkSize.maxWidth == 0 ) - { - offset -= afterCheckIconGap; - } - if ( iconSize.maxWidth == 0 ) - { - offset -= gap; - } - - // maximal text offset shouldn't be less than minimal text offset; - if ( offset < minTextOffset ) - { - offset = minTextOffset; - } - - // Calculate and store the maximal text offset - calcMaxValue ( BASICMENUITEMUI_MAX_TEXT_OFFSET, offset ); - } - - /** - * Layout icon, text, check icon, accelerator text and arrow icon in the viewRect and return their positions. - *

- * If horizontalAlignment, verticalTextPosition and horizontalTextPosition are default (user doesn't set any manually) the layouting - * algorithm is:t set any manually) the layouting algorithm is: Elements are layouted in the five columns: check icon + icon + text + - * accelerator text + arrow icon - *

- * In the other case elements are layouted in the four columns: check icon + label + accelerator text + arrow icon Label is union of - * icon and text. - *

- * The order of columns can be reversed. It depends on the menu item orientation. - */ - public LayoutResult layoutMenuItem () - { - LayoutResult lr = createLayoutResult (); - prepareForLayout ( lr ); - - if ( isColumnLayout () ) - { - if ( isLeftToRight () ) - { - doLTRColumnLayout ( lr, getLTRColumnAlignment () ); - } - else - { - doRTLColumnLayout ( lr, getRTLColumnAlignment () ); - } - } - else - { - if ( isLeftToRight () ) - { - doLTRComplexLayout ( lr, getLTRColumnAlignment () ); - } - else - { - doRTLComplexLayout ( lr, getRTLColumnAlignment () ); - } - } - - alignAccCheckAndArrowVertically ( lr ); - return lr; - } - - private LayoutResult createLayoutResult () - { - return new LayoutResult ( new Rectangle ( iconSize.width, iconSize.height ), new Rectangle ( textSize.width, textSize.height ), - new Rectangle ( accSize.width, accSize.height ), new Rectangle ( checkSize.width, checkSize.height ), - new Rectangle ( arrowSize.width, arrowSize.height ), new Rectangle ( labelSize.width, labelSize.height ) ); - } - - public ColumnAlignment getLTRColumnAlignment () - { - return ColumnAlignment.LEFT_ALIGNMENT; - } - - public ColumnAlignment getRTLColumnAlignment () - { - return ColumnAlignment.RIGHT_ALIGNMENT; - } - - protected void prepareForLayout ( LayoutResult lr ) - { - lr.checkRect.width = checkSize.maxWidth; - lr.accRect.width = accSize.maxWidth; - lr.arrowRect.width = arrowSize.maxWidth; - } - - /** - * Aligns the accelertor text and the check and arrow icons vertically with the center of the label rect. - */ - private void alignAccCheckAndArrowVertically ( LayoutResult lr ) - { - lr.accRect.y = ( int ) ( lr.labelRect.y + ( float ) lr.labelRect.height / 2 - ( float ) lr.accRect.height / 2 ); - fixVerticalAlignment ( lr, lr.accRect ); - if ( useCheckAndArrow ) - { - lr.arrowRect.y = ( int ) ( lr.labelRect.y + ( float ) lr.labelRect.height / 2 - ( float ) lr.arrowRect.height / 2 ); - lr.checkRect.y = ( int ) ( lr.labelRect.y + ( float ) lr.labelRect.height / 2 - ( float ) lr.checkRect.height / 2 ); - fixVerticalAlignment ( lr, lr.arrowRect ); - fixVerticalAlignment ( lr, lr.checkRect ); - } - } - - /** - * Fixes vertical alignment of all menu item elements if rect.y or (rect.y + rect.height) is out of viewRect bounds - */ - private void fixVerticalAlignment ( LayoutResult lr, Rectangle r ) - { - int delta = 0; - if ( r.y < viewRect.y ) - { - delta = viewRect.y - r.y; - } - else if ( r.y + r.height > viewRect.y + viewRect.height ) - { - delta = viewRect.y + viewRect.height - r.y - r.height; - } - if ( delta != 0 ) - { - lr.checkRect.y += delta; - lr.iconRect.y += delta; - lr.textRect.y += delta; - lr.accRect.y += delta; - lr.arrowRect.y += delta; - lr.labelRect.y += delta; - } - } - - private void doLTRColumnLayout ( LayoutResult lr, ColumnAlignment alignment ) - { - // Set maximal width for all the five basic rects - // (three other ones are already maximal) - lr.iconRect.width = iconSize.maxWidth; - lr.textRect.width = textSize.maxWidth; - - // Set X coordinates - // All rects will be aligned at the left side - calcXPositionsLTR ( viewRect.x, leadingGap, gap, lr.checkRect, lr.iconRect, lr.textRect ); - - // Tune afterCheckIconGap - if ( lr.checkRect.width > 0 ) - { // there is the afterCheckIconGap - lr.iconRect.x += afterCheckIconGap - gap; - lr.textRect.x += afterCheckIconGap - gap; - } - - calcXPositionsRTL ( viewRect.x + viewRect.width, leadingGap, gap, lr.arrowRect, lr.accRect ); - - // Take into account minimal text offset - int textOffset = lr.textRect.x - viewRect.x; - if ( !isTopLevelMenu && ( textOffset < minTextOffset ) ) - { - lr.textRect.x += minTextOffset - textOffset; - } - - alignRects ( lr, alignment ); - - // Take into account the left side bearings for text and accelerator text. - fixTextRects ( lr ); - - // Set Y coordinate for text and icon. - // Y coordinates for other rects - // will be calculated later in layoutMenuItem. - calcTextAndIconYPositions ( lr ); - - // Calculate valid X and Y coordinates for labelRect - lr.setLabelRect ( lr.textRect.union ( lr.iconRect ) ); - } - - private void doLTRComplexLayout ( LayoutResult lr, ColumnAlignment alignment ) - { - lr.labelRect.width = labelSize.maxWidth; - - // Set X coordinates - calcXPositionsLTR ( viewRect.x, leadingGap, gap, lr.checkRect, lr.labelRect ); - - // Tune afterCheckIconGap - if ( lr.checkRect.width > 0 ) - { // there is the afterCheckIconGap - lr.labelRect.x += afterCheckIconGap - gap; - } - - calcXPositionsRTL ( viewRect.x + viewRect.width, leadingGap, gap, lr.arrowRect, lr.accRect ); - - // Take into account minimal text offset - int labelOffset = lr.labelRect.x - viewRect.x; - if ( !isTopLevelMenu && ( labelOffset < minTextOffset ) ) - { - lr.labelRect.x += minTextOffset - labelOffset; - } - - alignRects ( lr, alignment ); - - // Take into account the left side bearing for accelerator text. - // The LSB for text is taken into account in layoutCompoundLabel() below. - fixAccTextRect ( lr ); - - // Center labelRect vertically - calcLabelYPosition ( lr ); - - layoutIconAndTextInLabelRect ( lr ); - } - - private void doRTLColumnLayout ( LayoutResult lr, ColumnAlignment alignment ) - { - // Set maximal width for all the five basic rects - // (three other ones are already maximal) - lr.iconRect.width = iconSize.maxWidth; - lr.textRect.width = textSize.maxWidth; - - // Set X coordinates - calcXPositionsRTL ( viewRect.x + viewRect.width, leadingGap, gap, lr.checkRect, lr.iconRect, lr.textRect ); - - // Tune the gap after check icon - if ( lr.checkRect.width > 0 ) - { // there is the gap after check icon - lr.iconRect.x -= afterCheckIconGap - gap; - lr.textRect.x -= afterCheckIconGap - gap; - } - - calcXPositionsLTR ( viewRect.x, leadingGap, gap, lr.arrowRect, lr.accRect ); - - // Take into account minimal text offset - int textOffset = ( viewRect.x + viewRect.width ) - ( lr.textRect.x + lr.textRect.width ); - if ( !isTopLevelMenu && ( textOffset < minTextOffset ) ) - { - lr.textRect.x -= minTextOffset - textOffset; - } - - alignRects ( lr, alignment ); - - // Take into account the left side bearings for text and accelerator text. - fixTextRects ( lr ); - - // Set Y coordinates for text and icon. - // Y coordinates for other rects - // will be calculated later in layoutMenuItem. - calcTextAndIconYPositions ( lr ); - - // Calculate valid X and Y coordinate for labelRect - lr.setLabelRect ( lr.textRect.union ( lr.iconRect ) ); - } - - private void doRTLComplexLayout ( LayoutResult lr, ColumnAlignment alignment ) - { - lr.labelRect.width = labelSize.maxWidth; - - // Set X coordinates - calcXPositionsRTL ( viewRect.x + viewRect.width, leadingGap, gap, lr.checkRect, lr.labelRect ); - - // Tune the gap after check icon - if ( lr.checkRect.width > 0 ) - { // there is the gap after check icon - lr.labelRect.x -= afterCheckIconGap - gap; - } - - calcXPositionsLTR ( viewRect.x, leadingGap, gap, lr.arrowRect, lr.accRect ); - - // Take into account minimal text offset - int labelOffset = ( viewRect.x + viewRect.width ) - ( lr.labelRect.x + lr.labelRect.width ); - if ( !isTopLevelMenu && ( labelOffset < minTextOffset ) ) - { - lr.labelRect.x -= minTextOffset - labelOffset; - } - - alignRects ( lr, alignment ); - - // Take into account the left side bearing for accelerator text. - // The LSB for text is taken into account in layoutCompoundLabel() below. - fixAccTextRect ( lr ); - - // Center labelRect vertically - calcLabelYPosition ( lr ); - - layoutIconAndTextInLabelRect ( lr ); - } - - private void alignRects ( LayoutResult lr, ColumnAlignment alignment ) - { - alignRect ( lr.checkRect, alignment.getCheckAlignment (), checkSize.getOrigWidth () ); - alignRect ( lr.iconRect, alignment.getIconAlignment (), iconSize.getOrigWidth () ); - alignRect ( lr.textRect, alignment.getTextAlignment (), textSize.getOrigWidth () ); - alignRect ( lr.accRect, alignment.getAccAlignment (), accSize.getOrigWidth () ); - alignRect ( lr.arrowRect, alignment.getArrowAlignment (), arrowSize.getOrigWidth () ); - } - - private void alignRect ( Rectangle rect, int alignment, int origWidth ) - { - if ( alignment != SwingUtilities.LEFT ) - { - rect.x = rect.x + rect.width - origWidth; - rect.width = origWidth; - } - } - - protected void layoutIconAndTextInLabelRect ( LayoutResult lr ) - { - lr.setTextRect ( new Rectangle () ); - lr.setIconRect ( new Rectangle () ); - SwingUtilities.layoutCompoundLabel ( mi, fm, text, icon, verticalAlignment, horizontalAlignment, verticalTextPosition, - horizontalTextPosition, lr.labelRect, lr.iconRect, lr.textRect, gap ); - } - - private void calcXPositionsLTR ( int startXPos, int leadingGap, int gap, Rectangle... rects ) - { - int curXPos = startXPos + leadingGap; - for ( Rectangle rect : rects ) - { - rect.x = curXPos; - if ( rect.width > 0 ) - { - curXPos += rect.width + gap; - } - } - } - - private void calcXPositionsRTL ( int startXPos, int leadingGap, int gap, Rectangle... rects ) - { - int curXPos = startXPos - leadingGap; - for ( Rectangle rect : rects ) - { - rect.x = curXPos - rect.width; - if ( rect.width > 0 ) - { - curXPos -= rect.width + gap; - } - } - } - - /** - * Takes into account the left side bearings for text and accelerator text - */ - private void fixTextRects ( LayoutResult lr ) - { - if ( htmlView == null ) - { - // The text isn't a HTML - int lsb = SwingUtils.getLeftSideBearing ( mi, fm, text ); - if ( lsb < 0 ) - { - lr.textRect.x -= lsb; - } - } - fixAccTextRect ( lr ); - } - - /** - * Takes into account the left side bearing for accelerator text - */ - private void fixAccTextRect ( LayoutResult lr ) - { - int lsb = SwingUtils.getLeftSideBearing ( mi, accFm, accText ); - if ( lsb < 0 ) - { - lr.accRect.x -= lsb; - } - } - - /** - * Sets Y coordinates of text and icon taking into account the vertical alignment - */ - private void calcTextAndIconYPositions ( LayoutResult lr ) - { - if ( verticalAlignment == SwingUtilities.TOP ) - { - lr.textRect.y = ( int ) ( viewRect.y + ( float ) lr.labelRect.height / 2 - ( float ) lr.textRect.height / 2 ); - lr.iconRect.y = ( int ) ( viewRect.y + ( float ) lr.labelRect.height / 2 - ( float ) lr.iconRect.height / 2 ); - } - else if ( verticalAlignment == SwingUtilities.CENTER ) - { - lr.textRect.y = ( int ) ( viewRect.y + ( float ) viewRect.height / 2 - ( float ) lr.textRect.height / 2 ); - lr.iconRect.y = ( int ) ( viewRect.y + ( float ) viewRect.height / 2 - ( float ) lr.iconRect.height / 2 ); - } - else if ( verticalAlignment == SwingUtilities.BOTTOM ) - { - lr.textRect.y = ( int ) ( viewRect.y + viewRect.height - ( float ) lr.labelRect.height / 2 - - ( float ) lr.textRect.height / 2 ); - lr.iconRect.y = ( int ) ( viewRect.y + viewRect.height - ( float ) lr.labelRect.height / 2 - - ( float ) lr.iconRect.height / 2 ); - } - } - - /** - * Sets labelRect Y coordinate taking into account the vertical alignment - */ - private void calcLabelYPosition ( LayoutResult lr ) - { - if ( verticalAlignment == SwingUtilities.TOP ) - { - lr.labelRect.y = viewRect.y; - } - else if ( verticalAlignment == SwingUtilities.CENTER ) - { - lr.labelRect.y = ( int ) ( viewRect.y + ( float ) viewRect.height / 2 - ( float ) lr.labelRect.height / 2 ); - } - else if ( verticalAlignment == SwingUtilities.BOTTOM ) - { - lr.labelRect.y = viewRect.y + viewRect.height - lr.labelRect.height; - } - } - - /** - * Returns parent of this component if it is not a top-level menu Otherwise returns null. - * - * @param menuItem the menu item whose parent will be returned. - * @return parent of this component if it is not a top-level menu Otherwise returns null. - */ - public static JComponent getMenuItemParent ( JMenuItem menuItem ) - { - Container parent = menuItem.getParent (); - if ( ( parent instanceof JComponent ) && ( !( menuItem instanceof JMenu ) || !( ( JMenu ) menuItem ).isTopLevelMenu () ) ) - { - return ( JComponent ) parent; - } - else - { - return null; - } - } - - public static void clearUsedParentClientProperties ( JMenuItem menuItem ) - { - clearUsedClientProperties ( getMenuItemParent ( menuItem ) ); - } - - public static void clearUsedClientProperties ( JComponent c ) - { - if ( c != null ) - { - c.putClientProperty ( MAX_ARROW_WIDTH, null ); - c.putClientProperty ( MAX_CHECK_WIDTH, null ); - c.putClientProperty ( MAX_ACC_WIDTH, null ); - c.putClientProperty ( MAX_TEXT_WIDTH, null ); - c.putClientProperty ( MAX_ICON_WIDTH, null ); - c.putClientProperty ( MAX_LABEL_WIDTH, null ); - c.putClientProperty ( BASICMENUITEMUI_MAX_TEXT_OFFSET, null ); - } - } - - /** - * Finds and returns maximal integer value in the given array. - * - * @param values array where the search will be performed. - * @return maximal vaule. - */ - public static int max ( int... values ) - { - int maxValue = Integer.MIN_VALUE; - for ( int i : values ) - { - if ( i > maxValue ) - { - maxValue = i; - } - } - return maxValue; - } - - public static Rectangle createMaxRect () - { - return new Rectangle ( 0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE ); - } - - public static void addMaxWidth ( RectSize size, int gap, Dimension result ) - { - if ( size.maxWidth > 0 ) - { - result.width += size.maxWidth + gap; - } - } - - public static void addWidth ( int width, int gap, Dimension result ) - { - if ( width > 0 ) - { - result.width += width + gap; - } - } - - public JMenuItem getMenuItem () - { - return mi; - } - - public JComponent getMenuItemParent () - { - return miParent; - } - - public Font getFont () - { - return font; - } - - public Font getAccFont () - { - return accFont; - } - - public FontMetrics getFontMetrics () - { - return fm; - } - - public FontMetrics getAccFontMetrics () - { - return accFm; - } - - public Icon getIcon () - { - return icon; - } - - public Icon getCheckIcon () - { - return checkIcon; - } - - public Icon getArrowIcon () - { - return arrowIcon; - } - - public String getText () - { - return text; - } - - public String getAccText () - { - return accText; - } - - public boolean isColumnLayout () - { - return isColumnLayout; - } - - public boolean useCheckAndArrow () - { - return useCheckAndArrow; - } - - public boolean isLeftToRight () - { - return isLeftToRight; - } - - public boolean isTopLevelMenu () - { - return isTopLevelMenu; - } - - public View getHtmlView () - { - return htmlView; - } - - public int getVerticalAlignment () - { - return verticalAlignment; - } - - public int getHorizontalAlignment () - { - return horizontalAlignment; - } - - public int getVerticalTextPosition () - { - return verticalTextPosition; - } - - public int getHorizontalTextPosition () - { - return horizontalTextPosition; - } - - public int getGap () - { - return gap; - } - - public int getLeadingGap () - { - return leadingGap; - } - - public int getAfterCheckIconGap () - { - return afterCheckIconGap; - } - - public int getMinTextOffset () - { - return minTextOffset; - } - - public Rectangle getViewRect () - { - return viewRect; - } - - public RectSize getIconSize () - { - return iconSize; - } - - public RectSize getTextSize () - { - return textSize; - } - - public RectSize getAccSize () - { - return accSize; - } - - public RectSize getCheckSize () - { - return checkSize; - } - - public RectSize getArrowSize () - { - return arrowSize; - } - - public RectSize getLabelSize () - { - return labelSize; - } - - protected void setMenuItem ( JMenuItem mi ) - { - this.mi = mi; - } - - protected void setMenuItemParent ( JComponent miParent ) - { - this.miParent = miParent; - } - - protected void setFont ( Font font ) - { - this.font = font; - } - - protected void setAccFont ( Font accFont ) - { - this.accFont = accFont; - } - - protected void setFontMetrics ( FontMetrics fm ) - { - this.fm = fm; - } - - protected void setAccFontMetrics ( FontMetrics accFm ) - { - this.accFm = accFm; - } - - protected void setIcon ( Icon icon ) - { - this.icon = icon; - } - - protected void setCheckIcon ( Icon checkIcon ) - { - this.checkIcon = checkIcon; - } - - protected void setArrowIcon ( Icon arrowIcon ) - { - this.arrowIcon = arrowIcon; - } - - protected void setText ( String text ) - { - this.text = text; - } - - protected void setAccText ( String accText ) - { - this.accText = accText; - } - - protected void setColumnLayout ( boolean columnLayout ) - { - isColumnLayout = columnLayout; - } - - protected void setUseCheckAndArrow ( boolean useCheckAndArrow ) - { - this.useCheckAndArrow = useCheckAndArrow; - } - - protected void setLeftToRight ( boolean leftToRight ) - { - isLeftToRight = leftToRight; - } - - protected void setTopLevelMenu ( boolean topLevelMenu ) - { - isTopLevelMenu = topLevelMenu; - } - - protected void setHtmlView ( View htmlView ) - { - this.htmlView = htmlView; - } - - protected void setVerticalAlignment ( int verticalAlignment ) - { - this.verticalAlignment = verticalAlignment; - } - - protected void setHorizontalAlignment ( int horizontalAlignment ) - { - this.horizontalAlignment = horizontalAlignment; - } - - protected void setVerticalTextPosition ( int verticalTextPosition ) - { - this.verticalTextPosition = verticalTextPosition; - } - - protected void setHorizontalTextPosition ( int horizontalTextPosition ) - { - this.horizontalTextPosition = horizontalTextPosition; - } - - protected void setGap ( int gap ) - { - this.gap = gap; - } - - protected void setLeadingGap ( int leadingGap ) - { - this.leadingGap = leadingGap; - } - - protected void setAfterCheckIconGap ( int afterCheckIconGap ) - { - this.afterCheckIconGap = afterCheckIconGap; - } - - protected void setMinTextOffset ( int minTextOffset ) - { - this.minTextOffset = minTextOffset; - } - - protected void setViewRect ( Rectangle viewRect ) - { - this.viewRect = viewRect; - } - - protected void setIconSize ( RectSize iconSize ) - { - this.iconSize = iconSize; - } - - protected void setTextSize ( RectSize textSize ) - { - this.textSize = textSize; - } - - protected void setAccSize ( RectSize accSize ) - { - this.accSize = accSize; - } - - protected void setCheckSize ( RectSize checkSize ) - { - this.checkSize = checkSize; - } - - protected void setArrowSize ( RectSize arrowSize ) - { - this.arrowSize = arrowSize; - } - - protected void setLabelSize ( RectSize labelSize ) - { - this.labelSize = labelSize; - } - - /** - * Returns false if the component is a JMenu and it is a top level menu (on the menubar). - */ - public static boolean useCheckAndArrow ( JMenuItem menuItem ) - { - boolean b = true; - if ( ( menuItem instanceof JMenu ) && ( ( ( JMenu ) menuItem ).isTopLevelMenu () ) ) - { - b = false; - } - return b; - } - - public static class LayoutResult - { - private Rectangle iconRect; - private Rectangle textRect; - private Rectangle accRect; - private Rectangle checkRect; - private Rectangle arrowRect; - private Rectangle labelRect; - - public LayoutResult () - { - iconRect = new Rectangle (); - textRect = new Rectangle (); - accRect = new Rectangle (); - checkRect = new Rectangle (); - arrowRect = new Rectangle (); - labelRect = new Rectangle (); - } - - public LayoutResult ( Rectangle iconRect, Rectangle textRect, Rectangle accRect, Rectangle checkRect, Rectangle arrowRect, - Rectangle labelRect ) - { - this.iconRect = iconRect; - this.textRect = textRect; - this.accRect = accRect; - this.checkRect = checkRect; - this.arrowRect = arrowRect; - this.labelRect = labelRect; - } - - public Rectangle getIconRect () - { - return iconRect; - } - - public void setIconRect ( Rectangle iconRect ) - { - this.iconRect = iconRect; - } - - public Rectangle getTextRect () - { - return textRect; - } - - public void setTextRect ( Rectangle textRect ) - { - this.textRect = textRect; - } - - public Rectangle getAccRect () - { - return accRect; - } - - public void setAccRect ( Rectangle accRect ) - { - this.accRect = accRect; - } - - public Rectangle getCheckRect () - { - return checkRect; - } - - public void setCheckRect ( Rectangle checkRect ) - { - this.checkRect = checkRect; - } - - public Rectangle getArrowRect () - { - return arrowRect; - } - - public void setArrowRect ( Rectangle arrowRect ) - { - this.arrowRect = arrowRect; - } - - public Rectangle getLabelRect () - { - return labelRect; - } - - public void setLabelRect ( Rectangle labelRect ) - { - this.labelRect = labelRect; - } - - public Map getAllRects () - { - Map result = new HashMap (); - result.put ( "checkRect", checkRect ); - result.put ( "iconRect", iconRect ); - result.put ( "textRect", textRect ); - result.put ( "accRect", accRect ); - result.put ( "arrowRect", arrowRect ); - result.put ( "labelRect", labelRect ); - return result; - } - } - - public static class ColumnAlignment - { - private int checkAlignment; - private int iconAlignment; - private int textAlignment; - private int accAlignment; - private int arrowAlignment; - - public static final ColumnAlignment LEFT_ALIGNMENT = - new ColumnAlignment ( SwingConstants.LEFT, SwingConstants.LEFT, SwingConstants.LEFT, SwingConstants.LEFT, - SwingConstants.LEFT ); - - public static final ColumnAlignment RIGHT_ALIGNMENT = - new ColumnAlignment ( SwingConstants.RIGHT, SwingConstants.RIGHT, SwingConstants.RIGHT, SwingConstants.RIGHT, - SwingConstants.RIGHT ); - - public ColumnAlignment ( int checkAlignment, int iconAlignment, int textAlignment, int accAlignment, int arrowAlignment ) - { - this.checkAlignment = checkAlignment; - this.iconAlignment = iconAlignment; - this.textAlignment = textAlignment; - this.accAlignment = accAlignment; - this.arrowAlignment = arrowAlignment; - } - - public int getCheckAlignment () - { - return checkAlignment; - } - - public int getIconAlignment () - { - return iconAlignment; - } - - public int getTextAlignment () - { - return textAlignment; - } - - public int getAccAlignment () - { - return accAlignment; - } - - public int getArrowAlignment () - { - return arrowAlignment; - } - } - - public static class RectSize - { - private int width; - private int height; - private int origWidth; - private int maxWidth; - - public RectSize () - { - } - - public RectSize ( int width, int height, int origWidth, int maxWidth ) - { - this.width = width; - this.height = height; - this.origWidth = origWidth; - this.maxWidth = maxWidth; - } - - public int getWidth () - { - return width; - } - - public int getHeight () - { - return height; - } - - public int getOrigWidth () - { - return origWidth; - } - - public int getMaxWidth () - { - return maxWidth; - } - - public void setWidth ( int width ) - { - this.width = width; - } - - public void setHeight ( int height ) - { - this.height = height; - } - - public void setOrigWidth ( int origWidth ) - { - this.origWidth = origWidth; - } - - public void setMaxWidth ( int maxWidth ) - { - this.maxWidth = maxWidth; - } - - public String toString () - { - return "[w=" + width + ",h=" + height + ",ow=" + origWidth + ",mw=" + maxWidth + "]"; - } - } -} \ No newline at end of file diff --git a/src/com/alee/laf/menu/PopupMenuWay.java b/src/com/alee/laf/menu/PopupMenuWay.java new file mode 100644 index 000000000..7b3280fa2 --- /dev/null +++ b/src/com/alee/laf/menu/PopupMenuWay.java @@ -0,0 +1,81 @@ +/* + * This file is part of WebLookAndFeel library. + * + * WebLookAndFeel library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WebLookAndFeel library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WebLookAndFeel library. If not, see . + */ + +package com.alee.laf.menu; + +import javax.swing.*; + +/** + * This enumeration represents default ways of displaying popup menu. + * + * @author Mikle Garin + */ + +public enum PopupMenuWay +{ + /** + * Displays popup menu above the invoker component starting at its leading side. + */ + aboveStart, + + /** + * Displays popup menu above the invoker component at its middle. + */ + aboveMiddle, + + /** + * Displays popup menu above the invoker component starting at its trailing side. + */ + aboveEnd, + + /** + * Displays popup menu under the invoker component starting at its leading side. + */ + belowStart, + + /** + * Displays popup menu under the invoker component at its middle. + */ + belowMiddle, + + /** + * Displays popup menu under the invoker component starting at its trailing side. + */ + belowEnd; + + /** + * Returns corner side for this popup menu display location. + * + * @return corner side for this popup menu display location + */ + public int getCornerSide () + { + switch ( this ) + { + case aboveStart: + case aboveMiddle: + case aboveEnd: + return SwingConstants.SOUTH; + case belowStart: + case belowMiddle: + case belowEnd: + default: + return SwingConstants.NORTH; + + } + } +} \ No newline at end of file diff --git a/src/com/alee/laf/menu/StringUIClientPropertyKey.java b/src/com/alee/laf/menu/StringUIClientPropertyKey.java deleted file mode 100644 index 574b95f57..000000000 --- a/src/com/alee/laf/menu/StringUIClientPropertyKey.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of WebLookAndFeel library. - * - * WebLookAndFeel library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * WebLookAndFeel library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with WebLookAndFeel library. If not, see . - */ - -package com.alee.laf.menu; - -/** - * User: mgarin Date: 02.09.11 Time: 12:34 - */ - -public class StringUIClientPropertyKey implements UIClientPropertyKey -{ - private final String key; - - public StringUIClientPropertyKey ( String key ) - { - this.key = key; - } - - public String toString () - { - return key; - } -} diff --git a/src/com/alee/laf/menu/UIClientPropertyKey.java b/src/com/alee/laf/menu/UIClientPropertyKey.java deleted file mode 100644 index 36b108213..000000000 --- a/src/com/alee/laf/menu/UIClientPropertyKey.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of WebLookAndFeel library. - * - * WebLookAndFeel library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * WebLookAndFeel library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with WebLookAndFeel library. If not, see . - */ - -package com.alee.laf.menu; - -/** - * User: mgarin Date: 02.09.11 Time: 12:35 - */ - -public interface UIClientPropertyKey -{ -} diff --git a/src/com/alee/laf/menu/WebCheckBoxMenuItem.java b/src/com/alee/laf/menu/WebCheckBoxMenuItem.java index b36ff0ed9..09ff232fb 100644 --- a/src/com/alee/laf/menu/WebCheckBoxMenuItem.java +++ b/src/com/alee/laf/menu/WebCheckBoxMenuItem.java @@ -17,6 +17,7 @@ package com.alee.laf.menu; +import com.alee.extended.painter.Painter; import com.alee.laf.WebLookAndFeel; import com.alee.managers.hotkey.HotkeyData; import com.alee.managers.language.LanguageManager; @@ -31,58 +32,353 @@ import com.alee.utils.swing.FontMethods; import javax.swing.*; +import java.awt.*; /** - * User: mgarin Date: 19.09.11 Time: 18:41 + * This JCheckBoxMenuItem extension class provides a direct access to WebCheckBoxMenuItemUI methods. + * + * @author Mikle Garin */ public class WebCheckBoxMenuItem extends JCheckBoxMenuItem implements LanguageMethods, SettingsMethods, FontMethods { + /** + * Constructs new checkbox menu item. + */ public WebCheckBoxMenuItem () { super (); } - public WebCheckBoxMenuItem ( Action a ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param a menu item action + */ + public WebCheckBoxMenuItem ( final Action a ) { super ( a ); } - public WebCheckBoxMenuItem ( Icon icon ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param icon menu item icon + */ + public WebCheckBoxMenuItem ( final Icon icon ) { super ( icon ); } - public WebCheckBoxMenuItem ( String text ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param text menu item text + */ + public WebCheckBoxMenuItem ( final String text ) { super ( text ); } - public WebCheckBoxMenuItem ( String text, boolean b ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param text menu item text + * @param b whether this checkbox item is selected or not + */ + public WebCheckBoxMenuItem ( final String text, final boolean b ) { super ( text, b ); } - public WebCheckBoxMenuItem ( String text, Icon icon ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param text menu item text + * @param icon menu item icon + */ + public WebCheckBoxMenuItem ( final String text, final Icon icon ) { super ( text, icon ); } - public WebCheckBoxMenuItem ( String text, Icon icon, boolean b ) + /** + * Constructs new checkbox menu item using the specified settings. + * + * @param text menu item text + * @param icon menu item icon + * @param b whether this checkbox item is selected or not + */ + public WebCheckBoxMenuItem ( final String text, final Icon icon, final boolean b ) { super ( text, icon, b ); } - public void setHotkey ( HotkeyData hotkey ) + /** + * Sets the key combination which invokes the menu item's action listeners without navigating the menu hierarchy. + * + * @param hotkey hotkey data + */ + public void setAccelerator ( final HotkeyData hotkey ) { SwingUtils.setAccelerator ( this, hotkey ); } + /** + * Returns menu item margin. + * + * @return menu item margin + */ + @Override + public Insets getMargin () + { + return getWebUI ().getMargin (); + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + @Override + public void setMargin ( final Insets margin ) + { + getWebUI ().setMargin ( margin ); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return getWebUI ().getDisabledFg (); + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + getWebUI ().setDisabledFg ( foreground ); + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return getWebUI ().getSelectedTopBg (); + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + getWebUI ().setSelectedTopBg ( background ); + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return getWebUI ().getSelectedBottomBg (); + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + getWebUI ().setSelectedBottomBg ( background ); + } + + /** + * Returns accelerator text background. + * + * @return accelerator text background + */ + public Color getAcceleratorBg () + { + return getWebUI ().getAcceleratorBg (); + } + + /** + * Sets accelerator text background. + * + * @param background new accelerator text background + */ + public void setAcceleratorBg ( final Color background ) + { + getWebUI ().setAcceleratorBg ( background ); + } + + /** + * Returns accelerator foreground. + * + * @return accelerator foreground + */ + public Color getAcceleratorFg () + { + return getWebUI ().getAcceleratorFg (); + } + + /** + * Sets accelerator foreground. + * + * @param foreground new accelerator foreground + */ + public void setAcceleratorFg ( final Color foreground ) + { + getWebUI ().setAcceleratorFg ( foreground ); + } + + /** + * Returns disabled accelerator foreground. + * + * @return disabled accelerator foreground + */ + public Color getAcceleratorDisabledFg () + { + return getWebUI ().getAcceleratorDisabledFg (); + } + + /** + * Sets disabled accelerator foreground. + * + * @param foreground new disabled accelerator foreground + */ + public void setAcceleratorDisabledFg ( final Color foreground ) + { + getWebUI ().setAcceleratorDisabledFg ( foreground ); + } + + /** + * Returns gap between menu item icon/text and accelerator. + * + * @return gap between menu item icon/text and accelerator + */ + public int getAcceleratorGap () + { + return getWebUI ().getAcceleratorGap (); + } + + /** + * Sets gap between menu icon/text and accelerator. + * + * @param gap new gap between menu icon/text and accelerator + */ + public void setAcceleratorGap ( final int gap ) + { + getWebUI ().setAcceleratorGap ( gap ); + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return getWebUI ().isAlignTextToMenuIcons (); + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + getWebUI ().setAlignTextToMenuIcons ( align ); + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return getWebUI ().getIconAlignment (); + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + getWebUI ().setIconAlignment ( alignment ); + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return getWebUI ().getPainter (); + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + getWebUI ().setPainter ( painter ); + } + + /** + * Returns checkbox menu item check color. + * + * @return checkbox menu item check color + */ + public Color getCheckColor () + { + return getWebUI ().getCheckColor (); + } + + /** + * Sets checkbox menu item check color. + * + * @param color checkbox menu item check color + */ + public void setCheckColor ( final Color color ) + { + getWebUI ().setCheckColor ( color ); + } + + /** + * Returns Web-UI applied to this class. + * + * @return Web-UI applied to this class + */ public WebCheckBoxMenuItemUI getWebUI () { return ( WebCheckBoxMenuItemUI ) getUI (); } + /** + * Installs a Web-UI into this component. + */ @Override public void updateUI () { @@ -104,15 +400,11 @@ public void updateUI () } } - /** - * Language methods - */ - /** * {@inheritDoc} */ @Override - public void setLanguage ( String key, Object... data ) + public void setLanguage ( final String key, final Object... data ) { LanguageManager.registerComponent ( this, key, data ); } @@ -121,7 +413,7 @@ public void setLanguage ( String key, Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( Object... data ) + public void updateLanguage ( final Object... data ) { LanguageManager.updateComponent ( this, data ); } @@ -130,7 +422,7 @@ public void updateLanguage ( Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( String key, Object... data ) + public void updateLanguage ( final String key, final Object... data ) { LanguageManager.updateComponent ( this, key, data ); } @@ -157,7 +449,7 @@ public boolean isLanguageSet () * {@inheritDoc} */ @Override - public void setLanguageUpdater ( LanguageUpdater updater ) + public void setLanguageUpdater ( final LanguageUpdater updater ) { LanguageManager.registerLanguageUpdater ( this, updater ); } @@ -171,15 +463,11 @@ public void removeLanguageUpdater () LanguageManager.unregisterLanguageUpdater ( this ); } - /** - * Settings methods - */ - /** * {@inheritDoc} */ @Override - public void registerSettings ( String key ) + public void registerSettings ( final String key ) { SettingsManager.registerComponent ( this, key ); } @@ -188,7 +476,7 @@ public void registerSettings ( String key ) * {@inheritDoc} */ @Override - public void registerSettings ( String key, Class defaultValueClass ) + public void registerSettings ( final String key, final Class defaultValueClass ) { SettingsManager.registerComponent ( this, key, defaultValueClass ); } @@ -197,7 +485,7 @@ public void registerSettings ( String key, Class def * {@inheritDoc} */ @Override - public void registerSettings ( String key, Object defaultValue ) + public void registerSettings ( final String key, final Object defaultValue ) { SettingsManager.registerComponent ( this, key, defaultValue ); } @@ -206,7 +494,7 @@ public void registerSettings ( String key, Object defaultValue ) * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key ) + public void registerSettings ( final String group, final String key ) { SettingsManager.registerComponent ( this, group, key ); } @@ -215,7 +503,7 @@ public void registerSettings ( String group, String key ) * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Class defaultValueClass ) + public void registerSettings ( final String group, final String key, final Class defaultValueClass ) { SettingsManager.registerComponent ( this, group, key, defaultValueClass ); } @@ -224,7 +512,7 @@ public void registerSettings ( String group, String key * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Object defaultValue ) + public void registerSettings ( final String group, final String key, final Object defaultValue ) { SettingsManager.registerComponent ( this, group, key, defaultValue ); } @@ -233,7 +521,7 @@ public void registerSettings ( String group, String key, Object defaultValue ) * {@inheritDoc} */ @Override - public void registerSettings ( String key, boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String key, final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, loadInitialSettings, applySettingsChanges ); } @@ -242,8 +530,8 @@ public void registerSettings ( String key, boolean loadInitialSettings, boolean * {@inheritDoc} */ @Override - public void registerSettings ( String key, Class defaultValueClass, boolean loadInitialSettings, - boolean applySettingsChanges ) + public void registerSettings ( final String key, final Class defaultValueClass, + final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, defaultValueClass, loadInitialSettings, applySettingsChanges ); } @@ -252,7 +540,8 @@ public void registerSettings ( String key, Class def * {@inheritDoc} */ @Override - public void registerSettings ( String key, Object defaultValue, boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String key, final Object defaultValue, final boolean loadInitialSettings, + final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, defaultValue, loadInitialSettings, applySettingsChanges ); } @@ -261,8 +550,8 @@ public void registerSettings ( String key, Object defaultValue, boolean loadInit * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Class defaultValueClass, - boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String group, final String key, final Class defaultValueClass, + final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, group, key, defaultValueClass, loadInitialSettings, applySettingsChanges ); } @@ -271,8 +560,8 @@ public void registerSettings ( String group, String key * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Object defaultValue, boolean loadInitialSettings, - boolean applySettingsChanges ) + public void registerSettings ( final String group, final String key, final Object defaultValue, final boolean loadInitialSettings, + final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, group, key, defaultValue, loadInitialSettings, applySettingsChanges ); } @@ -281,7 +570,7 @@ public void registerSettings ( String group, String key, Object defaultValue, bo * {@inheritDoc} */ @Override - public void registerSettings ( SettingsProcessor settingsProcessor ) + public void registerSettings ( final SettingsProcessor settingsProcessor ) { SettingsManager.registerComponent ( this, settingsProcessor ); } @@ -313,10 +602,6 @@ public void saveSettings () SettingsManager.saveComponentSettings ( this ); } - /** - * Font methods - */ - /** * {@inheritDoc} */ @@ -330,7 +615,7 @@ public WebCheckBoxMenuItem setPlainFont () * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setPlainFont ( boolean apply ) + public WebCheckBoxMenuItem setPlainFont ( final boolean apply ) { return SwingUtils.setPlainFont ( this, apply ); } @@ -357,7 +642,7 @@ public WebCheckBoxMenuItem setBoldFont () * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setBoldFont ( boolean apply ) + public WebCheckBoxMenuItem setBoldFont ( final boolean apply ) { return SwingUtils.setBoldFont ( this, apply ); } @@ -384,7 +669,7 @@ public WebCheckBoxMenuItem setItalicFont () * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setItalicFont ( boolean apply ) + public WebCheckBoxMenuItem setItalicFont ( final boolean apply ) { return SwingUtils.setItalicFont ( this, apply ); } @@ -402,7 +687,7 @@ public boolean isItalicFont () * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontStyle ( boolean bold, boolean italic ) + public WebCheckBoxMenuItem setFontStyle ( final boolean bold, final boolean italic ) { return SwingUtils.setFontStyle ( this, bold, italic ); } @@ -411,7 +696,7 @@ public WebCheckBoxMenuItem setFontStyle ( boolean bold, boolean italic ) * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontStyle ( int style ) + public WebCheckBoxMenuItem setFontStyle ( final int style ) { return SwingUtils.setFontStyle ( this, style ); } @@ -420,7 +705,7 @@ public WebCheckBoxMenuItem setFontStyle ( int style ) * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontSize ( int fontSize ) + public WebCheckBoxMenuItem setFontSize ( final int fontSize ) { return SwingUtils.setFontSize ( this, fontSize ); } @@ -429,7 +714,7 @@ public WebCheckBoxMenuItem setFontSize ( int fontSize ) * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem changeFontSize ( int change ) + public WebCheckBoxMenuItem changeFontSize ( final int change ) { return SwingUtils.changeFontSize ( this, change ); } @@ -447,7 +732,7 @@ public int getFontSize () * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontSizeAndStyle ( int fontSize, boolean bold, boolean italic ) + public WebCheckBoxMenuItem setFontSizeAndStyle ( final int fontSize, final boolean bold, final boolean italic ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, bold, italic ); } @@ -456,7 +741,7 @@ public WebCheckBoxMenuItem setFontSizeAndStyle ( int fontSize, boolean bold, boo * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontSizeAndStyle ( int fontSize, int style ) + public WebCheckBoxMenuItem setFontSizeAndStyle ( final int fontSize, final int style ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, style ); } @@ -465,7 +750,7 @@ public WebCheckBoxMenuItem setFontSizeAndStyle ( int fontSize, int style ) * {@inheritDoc} */ @Override - public WebCheckBoxMenuItem setFontName ( String fontName ) + public WebCheckBoxMenuItem setFontName ( final String fontName ) { return SwingUtils.setFontName ( this, fontName ); } diff --git a/src/com/alee/laf/menu/WebCheckBoxMenuItemUI.java b/src/com/alee/laf/menu/WebCheckBoxMenuItemUI.java index 748a49697..b9cae2df7 100644 --- a/src/com/alee/laf/menu/WebCheckBoxMenuItemUI.java +++ b/src/com/alee/laf/menu/WebCheckBoxMenuItemUI.java @@ -19,6 +19,7 @@ import javax.swing.*; import javax.swing.plaf.ComponentUI; +import java.awt.*; /** * Custom UI for JCheckBoxMenuItem component. @@ -28,6 +29,11 @@ public class WebCheckBoxMenuItemUI extends WebMenuItemUI { + /** + * Style settings. + */ + protected Color checkColor = WebMenuItemStyle.checkColor; + /** * Returns an instance of the WebCheckBoxMenuItemUI for the specified component. * This tricky method is used by UIManager to create component UIs when needed. @@ -36,7 +42,7 @@ public class WebCheckBoxMenuItemUI extends WebMenuItemUI * @return instance of the WebCheckBoxMenuItemUI */ @SuppressWarnings ("UnusedParameters") - public static ComponentUI createUI ( JComponent c ) + public static ComponentUI createUI ( final JComponent c ) { return new WebCheckBoxMenuItemUI (); } @@ -51,4 +57,41 @@ protected String getPropertyPrefix () { return "CheckBoxMenuItem"; } + + /** + * Returns checkbox menu item check color. + * + * @return checkbox menu item check color + */ + public Color getCheckColor () + { + return checkColor; + } + + /** + * Sets checkbox menu item check color. + * + * @param color checkbox menu item check color + */ + public void setCheckColor ( final Color color ) + { + this.checkColor = color; + } + + /** + * {@inheritDoc} + */ + @Override + protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, final int x, final int y, final int w, final int h, + final boolean selected, final boolean ltr ) + { + super.paintBackground ( g2d, menuItem, x, y, w, h, selected, ltr ); + + // Painting check selection + if ( painter == null && !selected && menuItem.isSelected () ) + { + g2d.setPaint ( checkColor ); + g2d.fillRect ( 0, 0, menuItem.getWidth (), menuItem.getHeight () ); + } + } } \ No newline at end of file diff --git a/src/com/alee/laf/menu/WebMenu.java b/src/com/alee/laf/menu/WebMenu.java index 4c98f0fac..f831bef46 100644 --- a/src/com/alee/laf/menu/WebMenu.java +++ b/src/com/alee/laf/menu/WebMenu.java @@ -17,6 +17,7 @@ package com.alee.laf.menu; +import com.alee.extended.painter.Painter; import com.alee.laf.WebLookAndFeel; import com.alee.managers.language.LanguageManager; import com.alee.managers.language.LanguageMethods; @@ -26,44 +27,282 @@ import com.alee.utils.swing.FontMethods; import javax.swing.*; +import java.awt.*; /** - * User: mgarin Date: 15.08.11 Time: 19:47 + * This JMenu extension class provides a direct access to WebMenuUI methods. + * + * @author Mikle Garin */ public class WebMenu extends JMenu implements LanguageMethods, FontMethods { + /** + * Constructs new menu. + */ public WebMenu () { super (); } - public WebMenu ( String s ) + /** + * Constructs new menu using the specified settings. + * + * @param icon menu icon + */ + public WebMenu ( final Icon icon ) { - super ( s ); + super (); + setIcon ( icon ); } - public WebMenu ( Action a ) + /** + * Constructs new menu using the specified settings. + * + * @param s menu text + */ + public WebMenu ( final String s ) { - super ( a ); + super ( s ); } - public WebMenu ( String s, boolean b ) + /** + * Constructs new menu using the specified settings. + * + * @param a menu action + */ + public WebMenu ( final Action a ) { - super ( s, b ); + super ( a ); } - public WebMenu ( String s, Icon icon ) + /** + * Constructs new menu using the specified settings. + * + * @param s menu text + * @param icon menu item icon + */ + public WebMenu ( final String s, final Icon icon ) { super ( s ); setIcon ( icon ); } + /** + * Returns top-level menu border rounding. + * + * @return top-level menu border rounding + */ + public int getRound () + { + return getWebUI ().getRound (); + } + + /** + * Sets top-level menu border rounding. + * + * @param round new top-level menu border rounding + */ + public void setRound ( final int round ) + { + getWebUI ().setRound ( round ); + } + + /** + * Returns top-level menu shade width. + * + * @return top-level menu shade width + */ + public int getShadeWidth () + { + return getWebUI ().getShadeWidth (); + } + + /** + * Sets top-level menu shade width. + * + * @param shadeWidth new top-level menu shade width + */ + public void setShadeWidth ( final int shadeWidth ) + { + getWebUI ().setShadeWidth ( shadeWidth ); + } + + /** + * Returns menu item margin. + * + * @return menu item margin + */ + @Override + public Insets getMargin () + { + return getWebUI ().getMargin (); + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + @Override + public void setMargin ( final Insets margin ) + { + getWebUI ().setMargin ( margin ); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return getWebUI ().getDisabledFg (); + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + getWebUI ().setDisabledFg ( foreground ); + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return getWebUI ().getSelectedTopBg (); + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + getWebUI ().setSelectedTopBg ( background ); + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return getWebUI ().getSelectedBottomBg (); + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + getWebUI ().setSelectedBottomBg ( background ); + } + + /** + * Returns gap between menu icon/text and submenu arrow. + * + * @return gap between menu icon/text and submenu arrow + */ + public int getArrowGap () + { + return getWebUI ().getArrowGap (); + } + + /** + * Sets gap between menu icon/text and submenu arrow. + * + * @param gap new gap between menu icon/text and submenu arrow + */ + public void setArrowGap ( final int gap ) + { + getWebUI ().setArrowGap ( gap ); + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return getWebUI ().isAlignTextToMenuIcons (); + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + getWebUI ().setAlignTextToMenuIcons ( align ); + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return getWebUI ().getIconAlignment (); + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + getWebUI ().setIconAlignment ( alignment ); + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return getWebUI ().getPainter (); + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + getWebUI ().setPainter ( painter ); + } + + /** + * Returns Web-UI applied to this class. + * + * @return Web-UI applied to this class + */ public WebMenuUI getWebUI () { return ( WebMenuUI ) getUI (); } + /** + * Installs a Web-UI into this component. + */ @Override public void updateUI () { @@ -89,15 +328,11 @@ public void updateUI () } } - /** - * Language methods - */ - /** * {@inheritDoc} */ @Override - public void setLanguage ( String key, Object... data ) + public void setLanguage ( final String key, final Object... data ) { LanguageManager.registerComponent ( this, key, data ); } @@ -106,7 +341,7 @@ public void setLanguage ( String key, Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( Object... data ) + public void updateLanguage ( final Object... data ) { LanguageManager.updateComponent ( this, data ); } @@ -115,7 +350,7 @@ public void updateLanguage ( Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( String key, Object... data ) + public void updateLanguage ( final String key, final Object... data ) { LanguageManager.updateComponent ( this, key, data ); } @@ -142,7 +377,7 @@ public boolean isLanguageSet () * {@inheritDoc} */ @Override - public void setLanguageUpdater ( LanguageUpdater updater ) + public void setLanguageUpdater ( final LanguageUpdater updater ) { LanguageManager.registerLanguageUpdater ( this, updater ); } @@ -156,10 +391,6 @@ public void removeLanguageUpdater () LanguageManager.unregisterLanguageUpdater ( this ); } - /** - * Font methods - */ - /** * {@inheritDoc} */ @@ -173,7 +404,7 @@ public WebMenu setPlainFont () * {@inheritDoc} */ @Override - public WebMenu setPlainFont ( boolean apply ) + public WebMenu setPlainFont ( final boolean apply ) { return SwingUtils.setPlainFont ( this, apply ); } @@ -200,7 +431,7 @@ public WebMenu setBoldFont () * {@inheritDoc} */ @Override - public WebMenu setBoldFont ( boolean apply ) + public WebMenu setBoldFont ( final boolean apply ) { return SwingUtils.setBoldFont ( this, apply ); } @@ -227,7 +458,7 @@ public WebMenu setItalicFont () * {@inheritDoc} */ @Override - public WebMenu setItalicFont ( boolean apply ) + public WebMenu setItalicFont ( final boolean apply ) { return SwingUtils.setItalicFont ( this, apply ); } @@ -245,7 +476,7 @@ public boolean isItalicFont () * {@inheritDoc} */ @Override - public WebMenu setFontStyle ( boolean bold, boolean italic ) + public WebMenu setFontStyle ( final boolean bold, final boolean italic ) { return SwingUtils.setFontStyle ( this, bold, italic ); } @@ -254,7 +485,7 @@ public WebMenu setFontStyle ( boolean bold, boolean italic ) * {@inheritDoc} */ @Override - public WebMenu setFontStyle ( int style ) + public WebMenu setFontStyle ( final int style ) { return SwingUtils.setFontStyle ( this, style ); } @@ -263,7 +494,7 @@ public WebMenu setFontStyle ( int style ) * {@inheritDoc} */ @Override - public WebMenu setFontSize ( int fontSize ) + public WebMenu setFontSize ( final int fontSize ) { return SwingUtils.setFontSize ( this, fontSize ); } @@ -272,7 +503,7 @@ public WebMenu setFontSize ( int fontSize ) * {@inheritDoc} */ @Override - public WebMenu changeFontSize ( int change ) + public WebMenu changeFontSize ( final int change ) { return SwingUtils.changeFontSize ( this, change ); } @@ -290,7 +521,7 @@ public int getFontSize () * {@inheritDoc} */ @Override - public WebMenu setFontSizeAndStyle ( int fontSize, boolean bold, boolean italic ) + public WebMenu setFontSizeAndStyle ( final int fontSize, final boolean bold, final boolean italic ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, bold, italic ); } @@ -299,7 +530,7 @@ public WebMenu setFontSizeAndStyle ( int fontSize, boolean bold, boolean italic * {@inheritDoc} */ @Override - public WebMenu setFontSizeAndStyle ( int fontSize, int style ) + public WebMenu setFontSizeAndStyle ( final int fontSize, final int style ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, style ); } @@ -308,7 +539,7 @@ public WebMenu setFontSizeAndStyle ( int fontSize, int style ) * {@inheritDoc} */ @Override - public WebMenu setFontName ( String fontName ) + public WebMenu setFontName ( final String fontName ) { return SwingUtils.setFontName ( this, fontName ); } diff --git a/src/com/alee/laf/menu/WebMenuItem.java b/src/com/alee/laf/menu/WebMenuItem.java index 411d32bf9..10ad2bad1 100644 --- a/src/com/alee/laf/menu/WebMenuItem.java +++ b/src/com/alee/laf/menu/WebMenuItem.java @@ -17,6 +17,7 @@ package com.alee.laf.menu; +import com.alee.extended.painter.Painter; import com.alee.laf.WebLookAndFeel; import com.alee.managers.hotkey.HotkeyData; import com.alee.managers.language.LanguageManager; @@ -27,53 +28,321 @@ import com.alee.utils.swing.FontMethods; import javax.swing.*; +import java.awt.*; /** - * User: mgarin Date: 15.08.11 Time: 15:57 + * This JMenuItem extension class provides a direct access to WebMenuItemUI methods. + * + * @author Mikle Garin */ public class WebMenuItem extends JMenuItem implements LanguageMethods, FontMethods { + /** + * Constructs new menu item. + */ public WebMenuItem () { super (); } - public WebMenuItem ( Icon icon ) + /** + * Constructs new menu item using the specified settings. + * + * @param icon menu item icon + */ + public WebMenuItem ( final Icon icon ) { super ( icon ); } - public WebMenuItem ( String text ) + /** + * Constructs new menu item using the specified settings. + * + * @param text menu item text + */ + public WebMenuItem ( final String text ) { super ( text ); } - public WebMenuItem ( Action a ) + /** + * Constructs new menu item using the specified settings. + * + * @param a menu item action + */ + public WebMenuItem ( final Action a ) { super ( a ); } - public WebMenuItem ( String text, Icon icon ) + /** + * Constructs new menu item using the specified settings. + * + * @param text menu item text + * @param icon menu item icon + */ + public WebMenuItem ( final String text, final Icon icon ) { super ( text, icon ); } - public WebMenuItem ( String text, int mnemonic ) + /** + * Constructs new menu item using the specified settings. + * + * @param text menu item text + * @param mnemonic menu item mnemonic + */ + public WebMenuItem ( final String text, final int mnemonic ) { super ( text, mnemonic ); } - public void setHotkey ( HotkeyData hotkey ) + /** + * Sets the key combination which invokes the menu item's action listeners without navigating the menu hierarchy. + * + * @param hotkey hotkey data + */ + public void setAccelerator ( final HotkeyData hotkey ) { SwingUtils.setAccelerator ( this, hotkey ); } + /** + * Returns menu item margin. + * + * @return menu item margin + */ + @Override + public Insets getMargin () + { + return getWebUI ().getMargin (); + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + @Override + public void setMargin ( final Insets margin ) + { + getWebUI ().setMargin ( margin ); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return getWebUI ().getDisabledFg (); + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + getWebUI ().setDisabledFg ( foreground ); + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return getWebUI ().getSelectedTopBg (); + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + getWebUI ().setSelectedTopBg ( background ); + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return getWebUI ().getSelectedBottomBg (); + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + getWebUI ().setSelectedBottomBg ( background ); + } + + /** + * Returns accelerator text background. + * + * @return accelerator text background + */ + public Color getAcceleratorBg () + { + return getWebUI ().getAcceleratorBg (); + } + + /** + * Sets accelerator text background. + * + * @param background new accelerator text background + */ + public void setAcceleratorBg ( final Color background ) + { + getWebUI ().setAcceleratorBg ( background ); + } + + /** + * Returns accelerator foreground. + * + * @return accelerator foreground + */ + public Color getAcceleratorFg () + { + return getWebUI ().getAcceleratorFg (); + } + + /** + * Sets accelerator foreground. + * + * @param foreground new accelerator foreground + */ + public void setAcceleratorFg ( final Color foreground ) + { + getWebUI ().setAcceleratorFg ( foreground ); + } + + /** + * Returns disabled accelerator foreground. + * + * @return disabled accelerator foreground + */ + public Color getAcceleratorDisabledFg () + { + return getWebUI ().getAcceleratorDisabledFg (); + } + + /** + * Sets disabled accelerator foreground. + * + * @param foreground new disabled accelerator foreground + */ + public void setAcceleratorDisabledFg ( final Color foreground ) + { + getWebUI ().setAcceleratorDisabledFg ( foreground ); + } + + /** + * Returns gap between menu item icon/text and accelerator. + * + * @return gap between menu item icon/text and accelerator + */ + public int getAcceleratorGap () + { + return getWebUI ().getAcceleratorGap (); + } + + /** + * Sets gap between menu icon/text and accelerator. + * + * @param gap new gap between menu icon/text and accelerator + */ + public void setAcceleratorGap ( final int gap ) + { + getWebUI ().setAcceleratorGap ( gap ); + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return getWebUI ().isAlignTextToMenuIcons (); + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + getWebUI ().setAlignTextToMenuIcons ( align ); + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return getWebUI ().getIconAlignment (); + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + getWebUI ().setIconAlignment ( alignment ); + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return getWebUI ().getPainter (); + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + getWebUI ().setPainter ( painter ); + } + + /** + * Returns Web-UI applied to this class. + * + * @return Web-UI applied to this class + */ public WebMenuItemUI getWebUI () { return ( WebMenuItemUI ) getUI (); } + /** + * Installs a Web-UI into this component. + */ @Override public void updateUI () { @@ -95,10 +364,6 @@ public void updateUI () } } - /** - * Language methods - */ - /** * {@inheritDoc} */ @@ -162,10 +427,6 @@ public void removeLanguageUpdater () LanguageManager.unregisterLanguageUpdater ( this ); } - /** - * Font methods - */ - /** * {@inheritDoc} */ diff --git a/src/com/alee/laf/menu/WebMenuItemStyle.java b/src/com/alee/laf/menu/WebMenuItemStyle.java index 81b330e34..635f654d6 100644 --- a/src/com/alee/laf/menu/WebMenuItemStyle.java +++ b/src/com/alee/laf/menu/WebMenuItemStyle.java @@ -36,20 +36,37 @@ public final class WebMenuItemStyle */ public static Insets margin = StyleConstants.emptyMargin; + /** + * Separate menu item corners rounding. + * This will be applied to menu items that are placed outside popup menu. + */ + public static int round = StyleConstants.smallRound; + + /** + * Separate menu item shade width. + * This will be applied to menu items that are placed outside popup menu. + */ + public static int shadeWidth = StyleConstants.shadeWidth; + /** * Disabled menu item foreground. */ public static Color disabledFg = Color.LIGHT_GRAY; + /** + * Checkbox and radiobutton menu items check color. + */ + public static Color checkColor = new Color ( 230, 230, 220 ); + /** * Top background color for selected item. */ - public static Color topBg = new Color ( 208, 208, 198 ); + public static Color selectedTopBg = new Color ( 208, 208, 198 ); /** * Bottom background color for selected item. */ - public static Color bottomBg = new Color ( 196, 196, 186 ); + public static Color selectedBottomBg = new Color ( 196, 196, 186 ); /** * Accelerator text foreground. diff --git a/src/com/alee/laf/menu/WebMenuItemUI.java b/src/com/alee/laf/menu/WebMenuItemUI.java index 7ea1addaf..1a4f6e105 100644 --- a/src/com/alee/laf/menu/WebMenuItemUI.java +++ b/src/com/alee/laf/menu/WebMenuItemUI.java @@ -24,6 +24,7 @@ import com.alee.utils.SwingUtils; import javax.swing.*; +import javax.swing.event.ChangeListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PopupMenuUI; import javax.swing.plaf.basic.BasicHTML; @@ -47,12 +48,11 @@ public class WebMenuItemUI extends BasicMenuItemUI */ protected Insets margin = WebMenuItemStyle.margin; protected Color disabledFg = WebMenuItemStyle.disabledFg; - protected Color topBg = WebMenuItemStyle.topBg; - protected Color bottomBg = WebMenuItemStyle.bottomBg; + protected Color selectedTopBg = WebMenuItemStyle.selectedTopBg; + protected Color selectedBottomBg = WebMenuItemStyle.selectedBottomBg; protected Color acceleratorBg = WebMenuItemStyle.acceleratorBg; protected Color acceleratorFg = WebMenuItemStyle.acceleratorFg; protected Color acceleratorDisabledFg = WebMenuItemStyle.acceleratorDisabledFg; - protected int iconTextGap = WebMenuItemStyle.iconTextGap; protected int acceleratorGap = WebMenuItemStyle.itemSidesGap; protected boolean alignTextToMenuIcons = WebMenuItemStyle.alignTextToMenuIcons; protected int iconAlignment = WebMenuItemStyle.iconAlignment; @@ -62,6 +62,7 @@ public class WebMenuItemUI extends BasicMenuItemUI * Menu item listeners. */ protected PropertyChangeListener propertyChangeListener; + protected ChangeListener buttonModelChangeListener; /** * Returns an instance of the WebMenuItemUI for the specified component. @@ -89,19 +90,23 @@ public void installUI ( final JComponent c ) // Default settings SwingUtils.setOrientation ( menuItem ); menuItem.setOpaque ( false ); - menuItem.setIconTextGap ( iconTextGap ); + menuItem.setIconTextGap ( WebMenuItemStyle.iconTextGap ); updateBorder (); // Orientation change listener propertyChangeListener = new PropertyChangeListener () { @Override - public void propertyChange ( PropertyChangeEvent evt ) + public void propertyChange ( final PropertyChangeEvent evt ) { updateBorder (); } }; menuItem.addPropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, propertyChangeListener ); + + // Button model change listener + buttonModelChangeListener = new MenuItemChangeListener ( menuItem ); + menuItem.getModel ().addChangeListener ( buttonModelChangeListener ); } /** @@ -114,6 +119,9 @@ public void uninstallUI ( final JComponent c ) { // Removing listeners menuItem.removePropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, propertyChangeListener ); + propertyChangeListener = null; + menuItem.getModel ().removeChangeListener ( buttonModelChangeListener ); + buttonModelChangeListener = null; // Restoring basic settings menuItem.setOpaque ( true ); @@ -168,6 +176,247 @@ protected void updateBorder () } } + /** + * Returns menu item margin. + * + * @return menu item margin + */ + public Insets getMargin () + { + return margin; + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + public void setMargin ( final Insets margin ) + { + this.margin = margin; + updateBorder (); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return disabledFg; + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + this.disabledFg = foreground; + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return selectedTopBg; + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + this.selectedTopBg = background; + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return selectedBottomBg; + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + this.selectedBottomBg = background; + } + + /** + * Returns accelerator text background. + * + * @return accelerator text background + */ + public Color getAcceleratorBg () + { + return acceleratorBg; + } + + /** + * Sets accelerator text background. + * + * @param background new accelerator text background + */ + public void setAcceleratorBg ( final Color background ) + { + this.acceleratorBg = background; + } + + /** + * Returns accelerator foreground. + * + * @return accelerator foreground + */ + public Color getAcceleratorFg () + { + return acceleratorFg; + } + + /** + * Sets accelerator foreground. + * + * @param foreground new accelerator foreground + */ + public void setAcceleratorFg ( final Color foreground ) + { + this.acceleratorFg = foreground; + } + + /** + * Returns disabled accelerator foreground. + * + * @return disabled accelerator foreground + */ + public Color getAcceleratorDisabledFg () + { + return acceleratorDisabledFg; + } + + /** + * Sets disabled accelerator foreground. + * + * @param foreground new disabled accelerator foreground + */ + public void setAcceleratorDisabledFg ( final Color foreground ) + { + this.acceleratorDisabledFg = foreground; + } + + /** + * Returns gap between menu item icon/text and accelerator. + * + * @return gap between menu item icon/text and accelerator + */ + public int getAcceleratorGap () + { + return acceleratorGap; + } + + /** + * Sets gap between menu icon/text and accelerator. + * + * @param gap new gap between menu icon/text and accelerator + */ + public void setAcceleratorGap ( final int gap ) + { + this.acceleratorGap = gap; + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return alignTextToMenuIcons; + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + this.alignTextToMenuIcons = align; + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return iconAlignment; + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + this.iconAlignment = alignment; + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return painter; + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + this.painter = painter; + } + + /** + * Returns paint used to fill north popup menu corner when this component is first in the menu. + * + * @return paint used to fill north popup menu corner when this component is first in the menu + */ + public Paint getNorthCornerFill () + { + return selectedTopBg; + } + + /** + * Returns paint used to fill south popup menu corner when this component is last in the menu. + * + * @return paint used to fill south popup menu corner when this component is last in the menu + */ + public Paint getSouthCornerFill () + { + return selectedTopBg; + } + /** * Paints menu item decoration. * @@ -180,8 +429,6 @@ public void paint ( final Graphics g, final JComponent c ) final Graphics2D g2d = ( Graphics2D ) g; final Object aa = LafUtils.setupAntialias ( g2d ); - // todo RTL painting - final JMenuItem menuItem = ( JMenuItem ) c; final boolean ltr = menuItem.getComponentOrientation ().isLeftToRight (); final int w = menuItem.getWidth (); @@ -189,16 +436,14 @@ public void paint ( final Graphics g, final JComponent c ) final Insets bi = menuItem.getInsets (); final int y = bi.top; final int ih = h - bi.top - bi.bottom; - - // Painting background final ButtonModel model = menuItem.getModel (); - final boolean selected = menuItem.isEnabled () && ( model.isArmed () || ( menuItem instanceof JMenu && model.isSelected () ) ); - paintBackground ( g2d, menuItem, selected, ltr ); + final boolean selected = menuItem.isEnabled () && model.isArmed (); - // Painting icon + // Painting background and icon final int iconPlaceholderWidth = MenuUtils.getIconPlaceholderWidth ( menuItem, alignTextToMenuIcons ); final int gap = iconPlaceholderWidth > 0 ? menuItem.getIconTextGap () : 0; int x = ltr ? bi.left : w - bi.right - iconPlaceholderWidth; + paintBackground ( g2d, menuItem, x, y, iconPlaceholderWidth, ih, selected, ltr ); paintIcon ( g2d, menuItem, x, y, iconPlaceholderWidth, ih, selected, ltr ); x += ltr ? ( iconPlaceholderWidth + gap ) : -gap; @@ -245,11 +490,16 @@ public void paint ( final Graphics g, final JComponent c ) * * @param g2d graphics context * @param menuItem menu item + * @param x icon placeholder X coordinate + * @param y icon placeholder Y coordinate + * @param w icon placeholder width + * @param h icon placeholder height * @param selected whether menu item is selected or not * @param ltr whether menu item has left-to-right orientation or not */ @SuppressWarnings ( "UnusedParameters" ) - protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, final boolean selected, final boolean ltr ) + protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, final int x, final int y, final int w, final int h, + final boolean selected, final boolean ltr ) { if ( painter != null ) { @@ -259,7 +509,7 @@ protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, { if ( selected ) { - g2d.setPaint ( new GradientPaint ( 0, 0, topBg, 0, menuItem.getHeight (), bottomBg ) ); + g2d.setPaint ( new GradientPaint ( 0, 0, selectedTopBg, 0, menuItem.getHeight (), selectedBottomBg ) ); g2d.fillRect ( 0, 0, menuItem.getWidth (), menuItem.getHeight () ); } } @@ -400,240 +650,4 @@ public Dimension getPreferredSize ( final JComponent c ) return new Dimension ( bi.left + iconPlaceholderWidth + gap + textWidth + accWidth + bi.right, bi.top + contentHeight + bi.bottom ); } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // @Override - // protected Dimension getPreferredMenuItemSize ( final JComponent c, final Icon checkIcon, final Icon arrowIcon, - // final int defaultTextIconGap ) - // { - // final JMenuItem mi = ( JMenuItem ) c; - // final MenuItemLayoutHelper lh = - // new MenuItemLayoutHelper ( mi, checkIcon, arrowIcon, MenuItemLayoutHelper.createMaxRect (), defaultTextIconGap, - // getAccelerationDelimeter (), mi.getComponentOrientation ().isLeftToRight (), mi.getFont (), acceleratorFont, - // MenuItemLayoutHelper.useCheckAndArrow ( menuItem ), getPropertyPrefix () ); - // - // final Dimension result = new Dimension (); - // - // // Calculate the result width - // result.width = lh.getLeadingGap (); - // MenuItemLayoutHelper.addMaxWidth ( lh.getCheckSize (), lh.getAfterCheckIconGap (), result ); - // // Take into account mimimal text offset. - // if ( ( !lh.isTopLevelMenu () ) && ( lh.getMinTextOffset () > 0 ) && - // ( result.width < lh.getMinTextOffset () ) ) - // { - // result.width = lh.getMinTextOffset (); - // } - // MenuItemLayoutHelper.addMaxWidth ( lh.getLabelSize (), lh.getGap (), result ); - // MenuItemLayoutHelper.addMaxWidth ( lh.getAccSize (), lh.getGap (), result ); - // MenuItemLayoutHelper.addMaxWidth ( lh.getArrowSize (), lh.getGap (), result ); - // - // // Calculate the result height - // result.height = MenuItemLayoutHelper - // .max ( lh.getCheckSize ().getHeight (), lh.getLabelSize ().getHeight (), lh.getAccSize ().getHeight (), - // lh.getArrowSize ().getHeight () ); - // - // // Take into account menu item insets - // final Insets insets = lh.getMenuItem ().getInsets (); - // if ( insets != null ) - // { - // result.width += insets.left + insets.right; - // result.height += insets.top + insets.bottom; - // } - // - // return result; - // } - // - // @Override - // protected void paintMenuItem ( final Graphics g, final JComponent c, final Icon checkIcon, final Icon arrowIcon, final Color background, - // final Color foreground, final int defaultTextIconGap ) - // { - // // Saving original settings - // final Font holdf = g.getFont (); - // final Color holdc = g.getColor (); - // - // // Setting font - // final JMenuItem mi = ( JMenuItem ) c; - // g.setFont ( mi.getFont () ); - // - // // creating helper class - // final Rectangle viewRect = new Rectangle ( 0, 0, mi.getWidth (), mi.getHeight () ); - // applyInsets ( viewRect, mi.getInsets () ); - // final MenuItemLayoutHelper lh = - // new MenuItemLayoutHelper ( mi, checkIcon, arrowIcon, viewRect, defaultTextIconGap, getAccelerationDelimeter (), - // mi.getComponentOrientation ().isLeftToRight (), mi.getFont (), acceleratorFont, - // MenuItemLayoutHelper.useCheckAndArrow ( menuItem ), getPropertyPrefix () ); - // final MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem (); - // - // // Painting all parts - // paintBackground ( g, mi ); - // paintCheckIcon ( g, lh ); - // paintIcon ( g, lh ); - // paintArrowIcon ( g, lh, lr ); - // - // // Painting text parts - // final Map hints = SwingUtils.setupTextAntialias ( g ); - // paintText ( g, lh, lr ); - // paintAccText ( g, lh, lr ); - // SwingUtils.restoreTextAntialias ( g, hints ); - // - // // Restoring original settings - // g.setColor ( holdc ); - // g.setFont ( holdf ); - // } - // - // protected void paintBackground ( final Graphics g, final JMenuItem menuItem ) - // { - // if ( menuItem.isEnabled () ) - // { - // final ButtonModel model = menuItem.getModel (); - // if ( mouseover || model.isArmed () || - // ( menuItem instanceof JMenu && model.isSelected () ) ) - // { - // Graphics2D g2d = ( Graphics2D ) g; - // g2d.setPaint ( new GradientPaint ( 0, 0, topBg, 0, menuItem.getHeight (), bottomBg ) ); - // g2d.fillRect ( 0, 0, menuItem.getWidth (), menuItem.getHeight () ); - // } - // } - // } - // - // protected void applyInsets ( final Rectangle rect, final Insets insets ) - // { - // if ( insets != null ) - // { - // rect.x += insets.left; - // rect.y += insets.top; - // rect.width -= ( insets.right + rect.x ); - // rect.height -= ( insets.bottom + rect.y ); - // } - // } - // - // protected void paintIcon ( final Graphics g, final MenuItemLayoutHelper lh ) - // { - // final boolean checkOrRadio = lh.getMenuItem () instanceof JCheckBoxMenuItem || lh.getMenuItem () instanceof JRadioButtonMenuItem; - // final boolean selected = checkOrRadio && lh.getMenuItem ().getModel ().isSelected (); - // if ( lh.getMenuItem () instanceof JCheckBoxMenuItem && selected ) - // { - // final List checkStates = SimpleCheckIcon.CHECK_STATES; - // final ImageIcon enabled = checkStates.get ( checkStates.size () - 1 ); - // final ImageIcon disabled = SimpleCheckIcon.DISABLED_CHECK_STATES.get ( 3 ); - // final ImageIcon check = lh.getMenuItem ().isEnabled () ? enabled : disabled; - // check.paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // else if ( lh.getMenuItem () instanceof JRadioButtonMenuItem && selected ) - // { - // final List checkStates = WebRadioButtonUI.CHECK_STATES; - // final ImageIcon enabled = checkStates.get ( checkStates.size () - 1 ); - // final ImageIcon disabled = WebRadioButtonUI.DISABLED_CHECK; - // final ImageIcon check = lh.getMenuItem ().isEnabled () ? enabled : disabled; - // check.paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // else if ( lh.getIcon () != null && !checkOrRadio ) - // { - // // if ( selected ) - // // { - // // Graphics2D g2d = ( Graphics2D ) g; - // // Object aa = g2d.getRenderingHint ( RenderingHints.KEY_ANTIALIASING ); - // // g2d.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, - // // RenderingHints.VALUE_ANTIALIAS_ON ); - // // - // // g2d.setPaint ( new GradientPaint ( 0, 2, StyleConstants.topBgColor, 0, 24, - // // StyleConstants.bottomBgColor ) ); - // // g.fillRoundRect ( 2, 2, 21, 21, 4, 4 ); - // // g.setColor ( StyleConstants.darkBorderColor ); - // // g.drawRoundRect ( 2, 2, 21, 21, 4, 4 ); - // // } - // - // Icon icon; - // final ButtonModel model = lh.getMenuItem ().getModel (); - // if ( !model.isEnabled () ) - // { - // icon = lh.getMenuItem ().getDisabledIcon (); - // } - // else if ( model.isPressed () && model.isArmed () ) - // { - // icon = lh.getMenuItem ().getPressedIcon (); - // if ( icon == null ) - // { - // icon = lh.getMenuItem ().getIcon (); - // } - // } - // else - // { - // icon = lh.getMenuItem ().getIcon (); - // } - // if ( icon != null && icon != StyleConstants.EMPTY_ICON ) - // { - // icon.paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // } - // } - // - // protected void paintCheckIcon ( final Graphics g, final MenuItemLayoutHelper lh ) - // { - // if ( lh.useCheckAndArrow () && lh.getCheckIcon () != null ) - // { - // lh.getCheckIcon ().paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // } - // - // protected void paintArrowIcon ( final Graphics g, final MenuItemLayoutHelper lh, final MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( lh.useCheckAndArrow () && lh.getArrowIcon () != null ) - // { - // lh.getArrowIcon ().paintIcon ( lh.getMenuItem (), g, lr.getArrowRect ().x, lr.getArrowRect ().y ); - // } - // } - // - // protected void paintText ( final Graphics g, final MenuItemLayoutHelper lh, final MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( !lh.getText ().equals ( "" ) ) - // { - // final Rectangle rect = lr.getTextRect (); - // if ( lh.getHtmlView () != null ) - // { - // // Text is HTML - // lh.getHtmlView ().paint ( g, rect ); - // } - // else - // { - // // Text isn't HTML - // paintText ( g, lh.getMenuItem (), rect, lh.getText () ); - // } - // } - // } - // - // - // @Override - // protected void paintText ( final Graphics g, final JMenuItem menuItem, final Rectangle textRect, final String text ) - // { - // final int mnemIndex = WebLookAndFeel.isMnemonicHidden () ? -1 : menuItem.getDisplayedMnemonicIndex (); - // g.setColor ( menuItem.isEnabled () ? menuItem.getForeground () : UIManager.getColor ( "MenuItem.disabledForeground" ) ); - // SwingUtils.drawStringUnderlineCharAt ( g, text, mnemIndex, 32, - // menuItem.getHeight () / 2 + LafUtils.getTextCenterShearY ( SwingUtils.getFontMetrics ( menuItem, g ) ) ); - // } - // - // protected void paintAccText ( final Graphics g, final MenuItemLayoutHelper lh, final MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( !lh.getAccText ().equals ( "" ) ) - // { - // final ButtonModel model = lh.getMenuItem ().getModel (); - // - // g.setFont ( lh.getAccFontMetrics ().getFont () ); - // g.setColor ( model.isEnabled () ? StyleConstants.infoTextColor : StyleConstants.disabledInfoTextColor ); - // - // final Rectangle rect = lr.getAccRect (); - // rect.x = lh.getMenuItem ().getWidth () - 7 - lh.getAccFontMetrics ().stringWidth ( lh.getAccText () ); - // SwingUtils.drawString ( g, lh.getAccText (), rect.x, - // lh.getMenuItem ().getHeight () / 2 + LafUtils.getTextCenterShearY ( lh.getAccFontMetrics () ) ); - // } - // } -} +} \ No newline at end of file diff --git a/src/com/alee/laf/menu/WebMenuUI.java b/src/com/alee/laf/menu/WebMenuUI.java index e26774c59..47a9c2201 100644 --- a/src/com/alee/laf/menu/WebMenuUI.java +++ b/src/com/alee/laf/menu/WebMenuUI.java @@ -18,7 +18,9 @@ package com.alee.laf.menu; import com.alee.extended.painter.Painter; +import com.alee.laf.StyleConstants; import com.alee.laf.WebLookAndFeel; +import com.alee.utils.ImageUtils; import com.alee.utils.LafUtils; import com.alee.utils.MathUtils; import com.alee.utils.SwingUtils; @@ -30,40 +32,58 @@ import javax.swing.plaf.basic.BasicMenuUI; import javax.swing.text.View; import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Map; /** - * User: mgarin Date: 15.08.11 Time: 19:47 + * Custom UI for JMenu component. + * + * @author Mikle Garin */ public class WebMenuUI extends BasicMenuUI { + /** + * Used icons. + */ + public static final ImageIcon arrowRightIcon = new ImageIcon ( WebMenuUI.class.getResource ( "icons/arrowRight.png" ) ); + public static final ImageIcon arrowLeftIcon = new ImageIcon ( WebMenuUI.class.getResource ( "icons/arrowLeft.png" ) ); + /** * Style settings. */ + protected int round = WebMenuItemStyle.round; + protected int shadeWidth = WebMenuItemStyle.shadeWidth; protected Insets margin = WebMenuItemStyle.margin; protected Color disabledFg = WebMenuItemStyle.disabledFg; - protected Color topBg = WebMenuItemStyle.topBg; - protected Color bottomBg = WebMenuItemStyle.bottomBg; - protected int iconTextGap = WebMenuItemStyle.iconTextGap; + protected Color selectedTopBg = WebMenuItemStyle.selectedTopBg; + protected Color selectedBottomBg = WebMenuItemStyle.selectedBottomBg; protected int arrowGap = WebMenuItemStyle.itemSidesGap; protected boolean alignTextToMenuIcons = WebMenuItemStyle.alignTextToMenuIcons; protected int iconAlignment = WebMenuItemStyle.iconAlignment; protected Painter painter = WebMenuItemStyle.painter; /** - * Menu item listeners. + * Menu listeners. */ protected PropertyChangeListener propertyChangeListener; + protected MouseAdapter mouseAdapter; + protected MenuItemChangeListener buttonModelChangeListener; + + /** + * Runtime variables. + */ + protected boolean mouseover = false; /** - * Returns an instance of the WebMenuItemUI for the specified component. + * Returns an instance of the WebMenuUI for the specified component. * This tricky method is used by UIManager to create component UIs when needed. * * @param c component that will use UI instance - * @return instance of the WebMenuItemUI + * @return instance of the WebMenuUI */ @SuppressWarnings ( "UnusedParameters" ) public static ComponentUI createUI ( final JComponent c ) @@ -84,19 +104,43 @@ public void installUI ( final JComponent c ) // Default settings SwingUtils.setOrientation ( menuItem ); menuItem.setOpaque ( false ); - menuItem.setIconTextGap ( iconTextGap ); + menuItem.setBackground ( selectedBottomBg ); + menuItem.setIconTextGap ( WebMenuItemStyle.iconTextGap ); updateBorder (); // Orientation change listener propertyChangeListener = new PropertyChangeListener () { @Override - public void propertyChange ( PropertyChangeEvent evt ) + public void propertyChange ( final PropertyChangeEvent evt ) { updateBorder (); } }; menuItem.addPropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, propertyChangeListener ); + + // Rollover listener + mouseAdapter = new MouseAdapter () + { + @Override + public void mouseEntered ( final MouseEvent e ) + { + mouseover = true; + menuItem.repaint (); + } + + @Override + public void mouseExited ( final MouseEvent e ) + { + mouseover = false; + menuItem.repaint (); + } + }; + menuItem.addMouseListener ( mouseAdapter ); + + // Button model change listener + buttonModelChangeListener = new MenuItemChangeListener ( menuItem ); + menuItem.getModel ().addChangeListener ( buttonModelChangeListener ); } /** @@ -109,6 +153,11 @@ public void uninstallUI ( final JComponent c ) { // Removing listeners menuItem.removePropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, propertyChangeListener ); + propertyChangeListener = null; + menuItem.removeMouseListener ( mouseAdapter ); + mouseAdapter = null; + menuItem.getModel ().removeChangeListener ( buttonModelChangeListener ); + buttonModelChangeListener = null; // Restoring basic settings menuItem.setOpaque ( true ); @@ -139,23 +188,31 @@ protected void updateBorder () } else { - // Retrieving popup menu rounding - int round = 0; + // Styling borders final Container parent = menuItem.getParent (); if ( parent != null && parent instanceof JPopupMenu ) { + // Retrieving popup menu rounding + int round = 0; final PopupMenuUI ui = ( ( JPopupMenu ) parent ).getUI (); if ( ui instanceof WebPopupMenuUI ) { round = ( ( WebPopupMenuUI ) ui ).getRound (); } - } - // Styling borders - m.top += 5; - m.left += ( ltr ? 4 : 7 ) + round; - m.bottom += 5; - m.right += ( ltr ? 7 : 4 ) + round; + // Combining margin + m.top += 5; + m.left += ( ltr ? 4 : 7 ) + round; + m.bottom += 5; + m.right += ( ltr ? 7 : 4 ) + round; + } + else + { + m.top += shadeWidth + 3; + m.left += shadeWidth + 3 + StyleConstants.contentSpacing; + m.bottom += shadeWidth + 3; + m.right += shadeWidth + 3 + StyleConstants.contentSpacing; + } } // Installing border @@ -164,10 +221,231 @@ protected void updateBorder () } /** - * Paints menu item decoration. + * Returns top-level menu border rounding. + * + * @return top-level menu border rounding + */ + public int getRound () + { + return round; + } + + /** + * Sets top-level menu border rounding. + * + * @param round new top-level menu border rounding + */ + public void setRound ( final int round ) + { + this.round = round; + } + + /** + * Returns top-level menu shade width. + * + * @return top-level menu shade width + */ + public int getShadeWidth () + { + return shadeWidth; + } + + /** + * Sets top-level menu shade width. + * + * @param shadeWidth new top-level menu shade width + */ + public void setShadeWidth ( final int shadeWidth ) + { + this.shadeWidth = shadeWidth; + } + + /** + * Returns menu item margin. + * + * @return menu item margin + */ + public Insets getMargin () + { + return margin; + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + public void setMargin ( final Insets margin ) + { + this.margin = margin; + updateBorder (); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return disabledFg; + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + this.disabledFg = foreground; + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return selectedTopBg; + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + this.selectedTopBg = background; + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return selectedBottomBg; + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + this.selectedBottomBg = background; + } + + /** + * Returns gap between menu icon/text and submenu arrow. + * + * @return gap between menu icon/text and submenu arrow + */ + public int getArrowGap () + { + return arrowGap; + } + + /** + * Sets gap between menu icon/text and submenu arrow. + * + * @param gap new gap between menu icon/text and submenu arrow + */ + public void setArrowGap ( final int gap ) + { + this.arrowGap = gap; + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return alignTextToMenuIcons; + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + this.alignTextToMenuIcons = align; + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return iconAlignment; + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + this.iconAlignment = alignment; + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return painter; + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + this.painter = painter; + } + + /** + * Returns paint used to fill north popup menu corner when this component is first in the menu. + * + * @return paint used to fill north popup menu corner when this component is first in the menu + */ + public Paint getNorthCornerFill () + { + return selectedTopBg; + } + + /** + * Returns paint used to fill south popup menu corner when this component is last in the menu. + * + * @return paint used to fill south popup menu corner when this component is last in the menu + */ + public Paint getSouthCornerFill () + { + return selectedTopBg; + } + + /** + * Paints menu decoration. * * @param g graphics context - * @param c menu item component + * @param c menu component */ @Override public void paint ( final Graphics g, final JComponent c ) @@ -175,52 +453,50 @@ public void paint ( final Graphics g, final JComponent c ) final Graphics2D g2d = ( Graphics2D ) g; final Object aa = LafUtils.setupAntialias ( g2d ); - // todo RTL painting - - final JMenuItem menuItem = ( JMenuItem ) c; - final boolean ltr = menuItem.getComponentOrientation ().isLeftToRight (); - final int w = menuItem.getWidth (); - final int h = menuItem.getHeight (); - final Insets bi = menuItem.getInsets (); + final JMenu menu = ( JMenu ) c; + final boolean ltr = menu.getComponentOrientation ().isLeftToRight (); + final int w = menu.getWidth (); + final int h = menu.getHeight (); + final Insets bi = menu.getInsets (); final int y = bi.top; final int ih = h - bi.top - bi.bottom; // Painting background - final ButtonModel model = menuItem.getModel (); - final boolean selected = menuItem.isEnabled () && ( model.isArmed () || ( menuItem instanceof JMenu && model.isSelected () ) ); - paintBackground ( g2d, menuItem, selected, ltr ); + final ButtonModel model = menu.getModel (); + final boolean selected = menu.isEnabled () && ( model.isArmed () || model.isSelected () ); + paintBackground ( g2d, menu, selected, ltr ); // Painting icon - final int iconPlaceholderWidth = MenuUtils.getIconPlaceholderWidth ( menuItem, alignTextToMenuIcons ); - final int gap = iconPlaceholderWidth > 0 ? menuItem.getIconTextGap () : 0; + final int iconPlaceholderWidth = MenuUtils.getIconPlaceholderWidth ( menu, alignTextToMenuIcons ); + final int gap = iconPlaceholderWidth > 0 ? menu.getIconTextGap () : 0; int x = ltr ? bi.left : w - bi.right - iconPlaceholderWidth; - paintIcon ( g2d, menuItem, x, y, iconPlaceholderWidth, ih, selected, ltr ); + paintIcon ( g2d, menu, x, y, iconPlaceholderWidth, ih, selected, ltr ); x += ltr ? ( iconPlaceholderWidth + gap ) : -gap; // Painting text - final String text = menuItem.getText (); + final String text = menu.getText (); if ( text != null && text.length () > 0 ) { final Map hints = SwingUtils.setupTextAntialias ( g2d ); - final Font oldFont = LafUtils.setupFont ( g, menuItem.getFont () ); + final Font oldFont = LafUtils.setupFont ( g, menu.getFont () ); - final FontMetrics fm = menuItem.getFontMetrics ( menuItem.getFont () ); - final View html = ( View ) menuItem.getClientProperty ( BasicHTML.propertyKey ); + final FontMetrics fm = menu.getFontMetrics ( menu.getFont () ); + final View html = ( View ) menu.getClientProperty ( BasicHTML.propertyKey ); final int tw = html != null ? ( int ) html.getPreferredSpan ( View.X_AXIS ) : fm.stringWidth ( text ); x -= ltr ? 0 : tw; - paintText ( g2d, menuItem, fm, x, y, tw, ih, selected, ltr ); + paintText ( g2d, menu, fm, x, y, tw, ih, selected, ltr ); LafUtils.restoreFont ( g, oldFont ); SwingUtils.restoreTextAntialias ( g2d, hints ); } // Painting sub-menu arrow icon - final Icon arrowIcon = getArrowIcon ( menuItem ); + final Icon arrowIcon = getArrowIcon ( menu ); if ( arrowIcon != null ) { - final Composite oc = LafUtils.setupAlphaComposite ( g2d, 0.5f, selected ); - arrowIcon.paintIcon ( menuItem, g2d, ltr ? w - bi.right - arrowIcon.getIconWidth () : bi.left, + final Composite oc = LafUtils.setupAlphaComposite ( g2d, 0.4f, selected ); + arrowIcon.paintIcon ( menu, g2d, ltr ? w - bi.right - arrowIcon.getIconWidth () : bi.left, y + ih / 2 - arrowIcon.getIconHeight () / 2 ); LafUtils.restoreComposite ( g2d, oc, selected ); } @@ -232,23 +508,34 @@ public void paint ( final Graphics g, final JComponent c ) * Paints menu item background. * * @param g2d graphics context - * @param menuItem menu item + * @param menu menu * @param selected whether menu item is selected or not * @param ltr whether menu item has left-to-right orientation or not */ @SuppressWarnings ( "UnusedParameters" ) - protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, final boolean selected, final boolean ltr ) + protected void paintBackground ( final Graphics2D g2d, final JMenu menu, final boolean selected, final boolean ltr ) { if ( painter != null ) { - painter.paint ( g2d, SwingUtils.size ( menuItem ), menuItem ); + painter.paint ( g2d, SwingUtils.size ( menu ), menu ); } else { - if ( selected ) + if ( menu.getParent () instanceof JPopupMenu ) { - g2d.setPaint ( new GradientPaint ( 0, 0, topBg, 0, menuItem.getHeight (), bottomBg ) ); - g2d.fillRect ( 0, 0, menuItem.getWidth (), menuItem.getHeight () ); + if ( selected ) + { + g2d.setPaint ( new GradientPaint ( 0, 0, selectedTopBg, 0, menu.getHeight (), selectedBottomBg ) ); + g2d.fillRect ( 0, 0, menu.getWidth (), menu.getHeight () ); + } + } + else + { + if ( menu.isEnabled () && ( selected || mouseover ) ) + { + LafUtils.drawWebStyle ( g2d, menu, StyleConstants.shadeColor, shadeWidth, round, menu.isEnabled (), + !selected && mouseover, selected ? StyleConstants.averageBorderColor : StyleConstants.borderColor ); + } } } } @@ -257,7 +544,7 @@ protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, * Paints menu item icon. * * @param g2d graphics context - * @param menuItem menu item + * @param menu menu * @param x icon placeholder X coordinate * @param y icon placeholder Y coordinate * @param w icon placeholder width @@ -266,17 +553,17 @@ protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, * @param ltr whether menu item has left-to-right orientation or not */ @SuppressWarnings ( "UnusedParameters" ) - protected void paintIcon ( final Graphics2D g2d, final JMenuItem menuItem, final int x, final int y, final int w, final int h, + protected void paintIcon ( final Graphics2D g2d, final JMenu menu, final int x, final int y, final int w, final int h, final boolean selected, final boolean ltr ) { - final Icon icon = menuItem.isEnabled () ? menuItem.getIcon () : menuItem.getDisabledIcon (); + final Icon icon = menu.isEnabled () ? menu.getIcon () : menu.getDisabledIcon (); if ( icon != null ) { final boolean left = ltr ? ( iconAlignment == SwingConstants.LEFT || iconAlignment == SwingConstants.LEADING ) : ( iconAlignment == SwingConstants.RIGHT || iconAlignment == SwingConstants.TRAILING ); final boolean center = iconAlignment == SwingConstants.CENTER; final int iconX = left ? x : center ? x + w / 2 - icon.getIconWidth () / 2 : x + w - icon.getIconWidth (); - icon.paintIcon ( menuItem, g2d, iconX, y + h / 2 - icon.getIconHeight () / 2 ); + icon.paintIcon ( menu, g2d, iconX, y + h / 2 - icon.getIconHeight () / 2 ); } } @@ -284,7 +571,7 @@ protected void paintIcon ( final Graphics2D g2d, final JMenuItem menuItem, final * Paints menu item text. * * @param g2d graphics context - * @param menuItem menu item + * @param menu menu * @param fm text font metrics * @param x text X coordinate * @param y text rectangle Y coordinate @@ -294,20 +581,20 @@ protected void paintIcon ( final Graphics2D g2d, final JMenuItem menuItem, final * @param ltr whether menu item has left-to-right orientation or not */ @SuppressWarnings ( "UnusedParameters" ) - protected void paintText ( final Graphics2D g2d, final JMenuItem menuItem, final FontMetrics fm, final int x, final int y, final int w, + protected void paintText ( final Graphics2D g2d, final JMenu menu, final FontMetrics fm, final int x, final int y, final int w, final int h, final boolean selected, final boolean ltr ) { - g2d.setPaint ( menuItem.isEnabled () ? menuItem.getForeground () : disabledFg ); + g2d.setPaint ( menu.isEnabled () ? menu.getForeground () : disabledFg ); - final View html = ( View ) menuItem.getClientProperty ( BasicHTML.propertyKey ); + final View html = ( View ) menu.getClientProperty ( BasicHTML.propertyKey ); if ( html != null ) { html.paint ( g2d, new Rectangle ( x, y, w, h ) ); } else { - final int mnem = WebLookAndFeel.isMnemonicHidden () ? -1 : menuItem.getDisplayedMnemonicIndex (); - SwingUtils.drawStringUnderlineCharAt ( g2d, menuItem.getText (), mnem, x, y + h / 2 + LafUtils.getTextCenterShearY ( fm ) ); + final int mnem = WebLookAndFeel.isMnemonicHidden () ? -1 : menu.getDisplayedMnemonicIndex (); + SwingUtils.drawStringUnderlineCharAt ( g2d, menu.getText (), mnem, x, y + h / 2 + LafUtils.getTextCenterShearY ( fm ) ); } } @@ -316,9 +603,25 @@ protected void paintText ( final Graphics2D g2d, final JMenuItem menuItem, final * * @return arrow icon displayed when sub-menu is available */ - protected Icon getArrowIcon ( final JMenuItem menuItem ) + protected Icon getArrowIcon ( final JMenu menu ) { - return menuItem.getParent () instanceof JPopupMenu ? UIManager.getIcon ( getPropertyPrefix () + ".arrowIcon" ) : null; + if ( menu.getParent () instanceof JPopupMenu ) + { + final boolean ltr = menu.getComponentOrientation ().isLeftToRight (); + if ( menu.isEnabled () ) + { + return ltr ? arrowRightIcon : arrowLeftIcon; + } + else + { + return ltr ? ImageUtils.getDisabledCopy ( "Menu.arrowRightIcon", arrowRightIcon ) : + ImageUtils.getDisabledCopy ( "Menu.arrowLeftIcon", arrowLeftIcon ); + } + } + else + { + return null; + } } /** @@ -330,16 +633,16 @@ protected Icon getArrowIcon ( final JMenuItem menuItem ) @Override public Dimension getPreferredSize ( final JComponent c ) { - final JMenuItem menuItem = ( JMenuItem ) c; - final Insets bi = menuItem.getInsets (); - final FontMetrics fm = menuItem.getFontMetrics ( menuItem.getFont () ); - final FontMetrics afm = menuItem.getFontMetrics ( acceleratorFont ); + final JMenu menu = ( JMenu ) c; + final Insets bi = menu.getInsets (); + final FontMetrics fm = menu.getFontMetrics ( menu.getFont () ); + final FontMetrics afm = menu.getFontMetrics ( acceleratorFont ); // Icon - final int iconPlaceholderWidth = MenuUtils.getIconPlaceholderWidth ( menuItem, alignTextToMenuIcons ); + final int iconPlaceholderWidth = MenuUtils.getIconPlaceholderWidth ( menu, alignTextToMenuIcons ); // Text - final View html = ( View ) menuItem.getClientProperty ( BasicHTML.propertyKey ); + final View html = ( View ) menu.getClientProperty ( BasicHTML.propertyKey ); final int textWidth; final int textHeight; if ( html != null ) @@ -351,318 +654,23 @@ public Dimension getPreferredSize ( final JComponent c ) else { // Text isn't HTML - final String text = menuItem.getText (); + final String text = menu.getText (); textWidth = text != null && text.length () > 0 ? fm.stringWidth ( text ) : 0; textHeight = fm.getHeight (); } // Icon-Text gap - final int gap = textWidth > 0 && iconPlaceholderWidth > 0 ? menuItem.getIconTextGap () : 0; + final int gap = textWidth > 0 && iconPlaceholderWidth > 0 ? menu.getIconTextGap () : 0; // Sub-menu arrow icon - final Icon subMenuArrowIcon = getArrowIcon ( menuItem ); + final Icon subMenuArrowIcon = getArrowIcon ( menu ); final int arrowWidth = subMenuArrowIcon != null ? arrowGap + subMenuArrowIcon.getIconWidth () : 0; // Content height - final int iconHeight = menuItem.getIcon () != null ? menuItem.getIcon ().getIconHeight () : 0; + final int iconHeight = menu.getIcon () != null ? menu.getIcon ().getIconHeight () : 0; final int contentHeight = MathUtils.max ( iconHeight, textHeight, afm.getHeight () ); return new Dimension ( bi.left + iconPlaceholderWidth + gap + textWidth + arrowWidth + bi.right, bi.top + contentHeight + bi.bottom ); } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // private static final Point iconLocation = new Point ( 6, 5 ); - // - // private boolean mouseover = false; - // - // private MouseAdapter mouseAdapter = null; - // - // @SuppressWarnings ("UnusedParameters") - // public static ComponentUI createUI ( JComponent c ) - // { - // return new WebMenuUI (); - // } - // - // @Override - // public void installUI ( JComponent c ) - // { - // super.installUI ( c ); - // - // // Default settings - // SwingUtils.setOrientation ( menuItem ); - // menuItem.setOpaque ( false ); - // menuItem.setBorder ( BorderFactory.createEmptyBorder ( 5, 2, 5, 2 ) ); - // menuItem.setBackground ( StyleConstants.menuSelectionColor ); - // - // // Rollover listener - // mouseAdapter = new MouseAdapter () - // { - // @Override - // public void mouseEntered ( MouseEvent e ) - // { - // mouseover = true; - // menuItem.repaint (); - // } - // - // @Override - // public void mouseExited ( MouseEvent e ) - // { - // mouseover = false; - // menuItem.repaint (); - // } - // }; - // menuItem.addMouseListener ( mouseAdapter ); - // } - // - // @Override - // public void uninstallUI ( JComponent c ) - // { - // menuItem.removeMouseListener ( mouseAdapter ); - // - // super.uninstallUI ( c ); - // } - // - // @Override - // protected Dimension getPreferredMenuItemSize ( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) - // { - // JMenuItem mi = ( JMenuItem ) c; - // MenuItemLayoutHelper lh = - // new MenuItemLayoutHelper ( mi, checkIcon, arrowIcon, MenuItemLayoutHelper.createMaxRect (), defaultTextIconGap, - // getAccelerationDelimeter (), mi.getComponentOrientation ().isLeftToRight (), mi.getFont (), acceleratorFont, - // MenuItemLayoutHelper.useCheckAndArrow ( menuItem ), getPropertyPrefix () ); - // - // Dimension result = new Dimension (); - // - // // Calculate the result width - // result.width = lh.getLeadingGap (); - // MenuItemLayoutHelper.addMaxWidth ( lh.getCheckSize (), lh.getAfterCheckIconGap (), result ); - // // Take into account mimimal text offset. - // if ( ( !lh.isTopLevelMenu () ) && ( lh.getMinTextOffset () > 0 ) && - // ( result.width < lh.getMinTextOffset () ) ) - // { - // result.width = lh.getMinTextOffset (); - // } - // MenuItemLayoutHelper.addMaxWidth ( lh.getLabelSize (), lh.getGap (), result ); - // MenuItemLayoutHelper.addMaxWidth ( lh.getAccSize (), lh.getGap (), result ); - // MenuItemLayoutHelper.addMaxWidth ( lh.getArrowSize (), lh.getGap (), result ); - // - // // Calculate the result height - // result.height = MenuItemLayoutHelper - // .max ( lh.getCheckSize ().getHeight (), lh.getLabelSize ().getHeight (), lh.getAccSize ().getHeight (), - // lh.getArrowSize ().getHeight () ); - // - // // Take into account menu item insets - // Insets insets = lh.getMenuItem ().getInsets (); - // if ( insets != null ) - // { - // result.width += insets.left + insets.right; - // result.height += insets.top + insets.bottom; - // } - // - // return result; - // } - // - // @Override - // protected void paintMenuItem ( Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, - // int defaultTextIconGap ) - // { - // // Saving original paint settings - // Font holdf = g.getFont (); - // Color holdc = g.getColor (); - // - // // Setting font - // JMenuItem mi = ( JMenuItem ) c; - // g.setFont ( mi.getFont () ); - // - // // Creating helper class - // Rectangle viewRect = new Rectangle ( 0, 0, mi.getWidth (), mi.getHeight () ); - // applyInsets ( viewRect, mi.getInsets () ); - // MenuItemLayoutHelper lh = - // new MenuItemLayoutHelper ( mi, checkIcon, arrowIcon, viewRect, defaultTextIconGap, getAccelerationDelimeter (), - // mi.getComponentOrientation ().isLeftToRight (), mi.getFont (), acceleratorFont, - // MenuItemLayoutHelper.useCheckAndArrow ( menuItem ), getPropertyPrefix () ); - // MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem (); - // - // // Painting menu parts - // paintBackground ( g, mi, lh ); - // paintCheckIcon ( g, lh ); - // paintIcon ( g, lh ); - // paintArrowIcon ( g, lh, lr ); - // - // // Painting text parts - // Map hints = SwingUtils.setupTextAntialias ( g ); - // paintText ( g, lh, lr ); - // paintAccText ( g, lh, lr ); - // SwingUtils.restoreTextAntialias ( g, hints ); - // - // // Retoring original settings - // g.setColor ( holdc ); - // g.setFont ( holdf ); - // } - // - // protected void paintBackground ( Graphics g, JMenuItem menuItem, MenuItemLayoutHelper lh ) - // { - // if ( menuItem.isEnabled () ) - // { - // ButtonModel model = menuItem.getModel (); - // if ( mouseover || model.isArmed () || model.isSelected () ) - // { - // boolean onPopup = lh.getMenuItemParent () instanceof JPopupMenu; - // int shadeWidth = onPopup ? 0 : StyleConstants.shadeWidth; - // LafUtils.drawWebStyle ( ( Graphics2D ) g, menuItem, StyleConstants.shadeColor, shadeWidth, StyleConstants.smallRound, - // menuItem.isEnabled (), !model.isSelected () || onPopup, - // model.isSelected () ? StyleConstants.averageBorderColor : StyleConstants.borderColor ); - // - // // if ( menuItem.isEnabled () ) - // // { - // // if ( model.isSelected () ) - // // { - // // LafUtils.drawWebFocus ( g2d, menuItem, StyleConstants.focusType, - // // StyleConstants.shadeWidth, StyleConstants.smallRound, null, true ); - // // } - // // else - // // { - // // LafUtils.drawWebFocus ( g2d, menuItem, StyleConstants.focusType, - // // StyleConstants.shadeWidth, StyleConstants.smallRound, null, true, - // // StyleConstants.rolloverMenuBorderColor ); - // // } - // // } - // - // if ( menuItem.isEnabled () && onPopup ) - // { - // LafUtils.drawWebFocus ( ( Graphics2D ) g, menuItem, FocusType.fieldFocus, shadeWidth, StyleConstants.smallRound, null, - // true, StyleConstants.darkBorderColor ); - // } - // } - // } - // } - // - // protected void applyInsets ( Rectangle rect, Insets insets ) - // { - // if ( insets != null ) - // { - // rect.x += insets.left; - // rect.y += insets.top; - // rect.width -= ( insets.right + rect.x ); - // rect.height -= ( insets.bottom + rect.y ); - // } - // } - // - // protected String getAccelerationDelimeter () - // { - // String delim = UIManager.getString ( "MenuItem.acceleratorDelimiter" ); - // return delim != null ? delim : "+"; - // } - // - // protected void paintIcon ( Graphics g, MenuItemLayoutHelper lh ) - // { - // if ( lh.getIcon () != null ) - // { - // Icon icon; - // ButtonModel model = lh.getMenuItem ().getModel (); - // if ( !model.isEnabled () ) - // { - // icon = lh.getMenuItem ().getDisabledIcon (); - // } - // else if ( model.isPressed () && model.isArmed () ) - // { - // icon = lh.getMenuItem ().getPressedIcon (); - // if ( icon == null ) - // { - // // Use default icon - // icon = lh.getMenuItem ().getIcon (); - // } - // } - // else - // { - // icon = lh.getMenuItem ().getIcon (); - // } - // - // if ( icon != null ) - // { - // icon.paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // } - // } - // - // protected void paintCheckIcon ( Graphics g, MenuItemLayoutHelper lh ) - // { - // if ( lh.useCheckAndArrow () && lh.getCheckIcon () != null ) - // { - // lh.getCheckIcon ().paintIcon ( lh.getMenuItem (), g, iconLocation.x, iconLocation.y ); - // } - // } - // - // protected void paintArrowIcon ( Graphics g, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( lh.useCheckAndArrow () && lh.getArrowIcon () != null ) - // { - // lh.getArrowIcon ().paintIcon ( lh.getMenuItem (), g, lr.getArrowRect ().x, lr.getArrowRect ().y ); - // } - // } - // - // protected void paintText ( Graphics g, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( !lh.getText ().equals ( "" ) ) - // { - // Rectangle rect = lr.getTextRect (); - // - // Font font = menuItem.getFont (); - // FontRenderContext renderContext = menuItem.getFontMetrics ( font ).getFontRenderContext (); - // GlyphVector glyphVector = font.createGlyphVector ( renderContext, menuItem.getText () ); - // Rectangle visualBounds = glyphVector.getVisualBounds ().getBounds (); - // rect.y = menuItem.getHeight () / 2 - visualBounds.height / 2; - // rect.height = visualBounds.height; - // - // if ( lh.getMenuItemParent () instanceof JPopupMenu ) - // { - // rect.x -= lh.getMenuItem ().getIconTextGap () * 2 - 1; - // } - // if ( lh.getHtmlView () != null ) - // { - // // Text is HTML - // lh.getHtmlView ().paint ( g, rect ); - // } - // else - // { - // // Text isn't HTML - // paintText ( g, lh.getMenuItem (), rect, lh.getText () ); - // } - // } - // } - // - // @Override - // protected void paintText ( Graphics g, JMenuItem menuItem, Rectangle rect, String text ) - // { - // // todo Proper placement with RTL orientation - // final int mnemIndex = WebLookAndFeel.isMnemonicHidden () ? -1 : menuItem.getDisplayedMnemonicIndex (); - // g.setColor ( menuItem.isEnabled () ? menuItem.getForeground () : UIManager.getColor ( "MenuItem.disabledForeground" ) ); - // SwingUtils.drawStringUnderlineCharAt ( g, text, mnemIndex, rect.x, rect.y + rect.height ); - // } - // - // protected void paintAccText ( Graphics g, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr ) - // { - // if ( !lh.getAccText ().equals ( "" ) ) - // { - // final ButtonModel model = lh.getMenuItem ().getModel (); - // - // g.setFont ( lh.getAccFontMetrics ().getFont () ); - // g.setColor ( model.isEnabled () ? StyleConstants.infoTextColor : StyleConstants.disabledInfoTextColor ); - // - // final Rectangle rect = lr.getAccRect (); - // rect.x = lh.getMenuItem ().getWidth () - 7 - lh.getAccFontMetrics ().stringWidth ( lh.getAccText () ); - // SwingUtils.drawString ( g, lh.getAccText (), rect.x, - // lh.getMenuItem ().getHeight () / 2 + LafUtils.getTextCenterShearY ( lh.getAccFontMetrics () ) ); - // } - // } -} +} \ No newline at end of file diff --git a/src/com/alee/laf/menu/WebPopupMenu.java b/src/com/alee/laf/menu/WebPopupMenu.java index 86f71a470..735a9a712 100644 --- a/src/com/alee/laf/menu/WebPopupMenu.java +++ b/src/com/alee/laf/menu/WebPopupMenu.java @@ -17,6 +17,7 @@ package com.alee.laf.menu; +import com.alee.extended.painter.Painter; import com.alee.laf.WebLookAndFeel; import com.alee.utils.ReflectUtils; import com.alee.utils.laf.ShapeProvider; @@ -26,7 +27,7 @@ /** * This JPopupMenu extension class provides a direct access to WebPopupMenuUI methods. - * It also has a few additional methods for easy popup positioning on display. + * It also has a few additional methods to simplify popup window positioning. * * @author Mikle Garin */ @@ -52,28 +53,326 @@ public WebPopupMenu ( final String label ) } /** - * Displays popup menu under the invoker component. - * This method also takes into account component orientation. + * Adds separator into menu. + */ + @Override + public void addSeparator () + { + add ( new WebPopupMenu.Separator () ); + } + + /** + * Adds separator into menu at the specified Z-index. + * + * @param index separator Z-index + */ + public void addSeparator ( int index ) + { + add ( new WebPopupMenu.Separator (), index ); + } + + /** + * Displays popup menu above the invoker component starting at its leading side. + * This method takes into account component orientation. + * + * @param invoker invoker component + */ + public void showAbove ( final Component invoker ) + { + showAboveStart ( invoker ); + } + + /** + * Displays popup menu above the invoker component starting at its leading side. + * This method takes into account component orientation. + * + * @param invoker invoker component + */ + public void showAboveStart ( Component invoker ) + { + setPopupMenuWay ( PopupMenuWay.aboveStart ); + show ( invoker, 0, 0 ); + } + + /** + * Displays popup menu above the invoker component at its middle. + * + * @param invoker invoker component + */ + public void showAboveMiddle ( Component invoker ) + { + setPopupMenuWay ( PopupMenuWay.aboveMiddle ); + show ( invoker, 0, 0 ); + } + + /** + * Displays popup menu above the invoker component starting at its trailing side. + * This method takes into account component orientation. * * @param invoker invoker component */ - public void showUnder ( final Component invoker ) + public void showAboveEnd ( Component invoker ) { - final boolean ltr = invoker.getComponentOrientation ().isLeftToRight (); - show ( invoker, ltr ? 0 : invoker.getWidth () - getPreferredSize ().width, invoker.getHeight () ); + setPopupMenuWay ( PopupMenuWay.aboveEnd ); + show ( invoker, 0, 0 ); } /** - * Displays popup menu above the invoker component. + * Displays popup menu under the invoker component starting at its leading side. * This method also takes into account component orientation. * * @param invoker invoker component */ - public void showAbove ( final Component invoker ) + public void showBelow ( final Component invoker ) + { + showBelowStart ( invoker ); + } + + /** + * Displays popup menu under the invoker component starting at its leading side. + * This method takes into account component orientation. + * + * @param invoker invoker component + */ + public void showBelowStart ( final Component invoker ) + { + setPopupMenuWay ( PopupMenuWay.belowStart ); + show ( invoker, 0, 0 ); + } + + /** + * Displays popup menu under the invoker component at its middle. + * + * @param invoker invoker component + */ + public void showBelowMiddle ( final Component invoker ) + { + setPopupMenuWay ( PopupMenuWay.belowMiddle ); + show ( invoker, 0, 0 ); + } + + /** + * Displays popup menu under the invoker component starting at its trailing side. + * This method takes into account component orientation. + * + * @param invoker invoker component + */ + public void showBelowEnd ( final Component invoker ) + { + setPopupMenuWay ( PopupMenuWay.belowEnd ); + show ( invoker, 0, 0 ); + } + + /** + * Returns popup menu style. + * + * @return popup menu style + */ + public PopupMenuStyle getPopupMenuStyle () + { + return getWebUI ().getPopupMenuStyle (); + } + + /** + * Sets popup menu style. + * + * @param style new popup menu style + */ + public void setPopupMenuStyle ( final PopupMenuStyle style ) + { + getWebUI ().setPopupMenuStyle ( style ); + } + + /** + * Returns popup menu border color. + * + * @return popup menu border color + */ + public Color getBorderColor () + { + return getWebUI ().getBorderColor (); + } + + /** + * Sets popup menu border color. + * + * @param color new popup menu border color + */ + public void setBorderColor ( final Color color ) + { + getWebUI ().setBorderColor ( color ); + } + + /** + * Returns popup menu border corners rounding. + * + * @return popup menu border corners rounding + */ + public int getRound () + { + return getWebUI ().getRound (); + } + + /** + * Sets popup menu border corners rounding. + * + * @param round new popup menu border corners rounding + */ + public void setRound ( final int round ) + { + getWebUI ().setRound ( round ); + } + + /** + * Returns popup menu shade width. + * + * @return popup menu shade width + */ + public int getShadeWidth () + { + return getWebUI ().getShadeWidth (); + } + + /** + * Sets popup menu shade width. + * + * @param width new popup menu shade width + */ + public void setShadeWidth ( final int width ) + { + getWebUI ().setShadeWidth ( width ); + } + + /** + * Returns popup menu shade opacity. + * + * @return popup menu shade opacity + */ + public float getShadeOpacity () + { + return getWebUI ().getShadeOpacity (); + } + + /** + * Sets popup menu shade opacity. + * + * @param opacity new popup menu shade opacity + */ + public void setShadeOpacity ( final float opacity ) + { + getWebUI ().setShadeOpacity ( opacity ); + } + + /** + * Returns popup menu dropdown style corner width. + * + * @return popup menu dropdown style corner width + */ + public int getCornerWidth () + { + return getWebUI ().getCornerWidth (); + } + + /** + * Sets popup menu dropdown style corner width. + * + * @param width popup menu dropdown style corner width + */ + public void setCornerWidth ( final int width ) + { + getWebUI ().setCornerWidth ( width ); + } + + /** + * Returns popup menu content margin. + * + * @return popup menu content margin + */ + @Override + public Insets getMargin () + { + return getWebUI ().getMargin (); + } + + /** + * Sets popup menu content margin. + * + * @param margin new popup menu content margin + */ + public void setMargin ( final Insets margin ) + { + getWebUI ().setMargin ( margin ); + } + + /** + * Returns popup menu painter. + * + * @return popup menu painter + */ + public Painter getPainter () + { + return getWebUI ().getPainter (); + } + + /** + * Sets popup menu painter. + * + * @param painter new popup menu painter + */ + public void setPainter ( final Painter painter ) + { + getWebUI ().setPainter ( painter ); + } + + /** + * Returns spacing between menubar popup menus. + * + * @return spacing between menubar popup menus + */ + public int getMenuSpacing () + { + return getWebUI ().getMenuSpacing (); + } + + /** + * Sets spacing between menubar popup menus. + * + * @param spacing new spacing between menubar popup menus + */ + public void setMenuSpacing ( final int spacing ) + { + getWebUI ().setMenuSpacing ( spacing ); + } + + /** + * Returns whether popup menu should try to fix its initial location when displayed or not. + * + * @return true if popup menu should try to fix its initial location when displayed, false otherwise + */ + public boolean isFixLocation () + { + return getWebUI ().isFixLocation (); + } + + /** + * Sets whether popup menu should try to fix its initial location when displayed or not. + * + * @param fixLocation whether popup menu should try to fix its initial location when displayed or not + */ + public void setFixLocation ( final boolean fixLocation ) + { + getWebUI ().setFixLocation ( fixLocation ); + } + + /** + * Assists popup menu to allow it choose the best position relative to invoker. + * Its value nullified right after first usage to avoid popup menu display issues in future. + * + * @param way approximate popup menu display way + */ + public void setPopupMenuWay ( final PopupMenuWay way ) { - final boolean ltr = invoker.getComponentOrientation ().isLeftToRight (); - final Dimension ps = getPreferredSize (); - show ( invoker, ltr ? 0 : invoker.getWidth () - ps.width, -ps.height ); + getWebUI ().setPopupMenuWay ( way ); } /** diff --git a/src/com/alee/laf/menu/WebPopupMenuStyle.java b/src/com/alee/laf/menu/WebPopupMenuStyle.java index b517712c3..593169b93 100644 --- a/src/com/alee/laf/menu/WebPopupMenuStyle.java +++ b/src/com/alee/laf/menu/WebPopupMenuStyle.java @@ -59,14 +59,15 @@ public final class WebPopupMenuStyle /** * Popup menu shade width. + * Be aware that this value should always be greater or equal to cornerWidth due to Swing menu processing limitations. * This value might vary depending on available underlying system features. */ - public static int shadeWidth = ProprietaryUtils.isWindowTransparencyAllowed () ? 14 : 0; + public static int shadeWidth = ProprietaryUtils.isWindowTransparencyAllowed () ? 12 : 0; /** * Popup menu shade opacity. */ - public static float shadeOpacity = 0.7f; + public static float shadeOpacity = 0.75f; /** * Popup menu dropdown style corner width diff --git a/src/com/alee/laf/menu/WebPopupMenuUI.java b/src/com/alee/laf/menu/WebPopupMenuUI.java index 6e06e47f1..e8eb0c3d4 100644 --- a/src/com/alee/laf/menu/WebPopupMenuUI.java +++ b/src/com/alee/laf/menu/WebPopupMenuUI.java @@ -18,15 +18,8 @@ package com.alee.laf.menu; import com.alee.extended.painter.Painter; -import com.alee.extended.window.TestFrame; import com.alee.laf.StyleConstants; import com.alee.laf.WebLookAndFeel; -import com.alee.laf.button.WebButton; -import com.alee.laf.colorchooser.WebColorChooserPanel; -import com.alee.managers.hotkey.Hotkey; -import com.alee.managers.hotkey.HotkeyManager; -import com.alee.managers.hotkey.HotkeyRunnable; -import com.alee.managers.language.LanguageManager; import com.alee.utils.*; import com.alee.utils.laf.ShapeProvider; import com.alee.utils.ninepatch.NinePatchIcon; @@ -36,9 +29,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicPopupMenuUI; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; import java.awt.geom.GeneralPath; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -49,13 +39,18 @@ * @author Mikle Garin */ -public class WebPopupMenuUI extends BasicPopupMenuUI implements ShapeProvider +public class WebPopupMenuUI extends BasicPopupMenuUI implements SwingConstants, ShapeProvider { + /** + * todo 1. Left/Right corner + * todo 2. Proper painter styling + * todo 3. When using popupMenuWay take invoker shade into account (if its UI has one -> add new ~Shadeable interface) + */ + /** * Style settings. */ protected PopupMenuStyle popupMenuStyle = WebPopupMenuStyle.popupMenuStyle; - protected Color backgroundColor = WebPopupMenuStyle.backgroundColor; protected Color borderColor = WebPopupMenuStyle.borderColor; protected int round = WebPopupMenuStyle.round; protected int shadeWidth = WebPopupMenuStyle.shadeWidth; @@ -69,6 +64,7 @@ public class WebPopupMenuUI extends BasicPopupMenuUI implements ShapeProvider /** * Menu listeners. */ + protected PropertyChangeListener orientationChangeListener; protected PropertyChangeListener visibilityChangeListener; protected PropertyChangeListener jdkSevenFixListener; @@ -77,7 +73,8 @@ public class WebPopupMenuUI extends BasicPopupMenuUI implements ShapeProvider */ protected boolean transparent = false; protected int relativeCorner = 0; - protected int cornerSide = SwingConstants.NORTH; + protected int cornerSide = NORTH; + protected PopupMenuWay popupMenuWay = null; /** * Returns an instance of the WebPopupMenuUI for the specified component. @@ -107,9 +104,21 @@ public void installUI ( final JComponent c ) // Default settings SwingUtils.setOrientation ( popupMenu ); popupMenu.setOpaque ( false ); - popupMenu.setBackground ( Color.WHITE ); + popupMenu.setBackground ( WebPopupMenuStyle.backgroundColor ); updateBorder (); + // Popup orientation change listener + orientationChangeListener = new PropertyChangeListener () + { + @Override + public void propertyChange ( PropertyChangeEvent evt ) + { + popupMenu.setVisible ( false ); + } + }; + popupMenu.addPropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, orientationChangeListener ); + + // Special listeners which set proper popup window opacity when needed if ( transparent ) { visibilityChangeListener = new PropertyChangeListener () @@ -128,18 +137,23 @@ public void propertyChange ( final PropertyChangeEvent evt ) setPopupMenuStyle ( PopupMenuStyle.simple ); } - // Update menu opacity state ancestor = SwingUtils.getWindowAncestor ( popupMenu ); + if ( ancestor instanceof JWindow ) + { + // Workaround to remove Mac OS X shade around the menu window + ( ( JWindow ) ancestor ).getRootPane ().putClientProperty ( "Window.shadow", Boolean.FALSE ); + } if ( ancestor != null && ancestor.getClass ().getCanonicalName ().endsWith ( "HeavyWeightWindow" ) ) { + // Updating menu opacity state ProprietaryUtils.setWindowOpaque ( ancestor, false ); } } else { - // Update menu opacity state if ( ancestor != null && ancestor.getClass ().getCanonicalName ().endsWith ( "HeavyWeightWindow" ) ) { + // Restoring menu opacity state ProprietaryUtils.setWindowOpaque ( ancestor, true ); } } @@ -184,9 +198,12 @@ public void propertyChange ( final PropertyChangeEvent evt ) @Override public void uninstallUI ( final JComponent c ) { + // Removing listeners + popupMenu.removePropertyChangeListener ( WebLookAndFeel.COMPONENT_ORIENTATION_PROPERTY, orientationChangeListener ); if ( transparent ) { popupMenu.removePropertyChangeListener ( WebLookAndFeel.VISIBLE_PROPERTY, visibilityChangeListener ); + visibilityChangeListener = null; } else { @@ -194,6 +211,7 @@ public void uninstallUI ( final JComponent c ) if ( SystemUtils.isJava7orAbove () ) { popupMenu.removePropertyChangeListener ( WebLookAndFeel.VISIBLE_PROPERTY, jdkSevenFixListener ); + jdkSevenFixListener = null; } } @@ -225,21 +243,10 @@ protected void updateBorder () { if ( transparent ) { - if ( popupMenuStyle == PopupMenuStyle.simple ) - { - m.top += shadeWidth + 1 + round; - m.left += shadeWidth + 1; - m.bottom += shadeWidth + 1 + round; - m.right += shadeWidth + 1; - } - else - { - // todo left/bottom/right corner - m.top += ( cornerSide == SwingConstants.NORTH ? cornerWidth : shadeWidth ) + 1 + round; - m.left += shadeWidth + 1; - m.bottom += ( cornerSide == SwingConstants.SOUTH ? cornerWidth : shadeWidth ) + 1 + round; - m.right += shadeWidth + 1; - } + m.top += shadeWidth + 1 + round; + m.left += shadeWidth + 1; + m.bottom += shadeWidth + 1 + round; + m.right += shadeWidth + 1; } else { @@ -252,10 +259,6 @@ protected void updateBorder () // Installing border popupMenu.setBorder ( LafUtils.createWebBorder ( m ) ); - - // Old - // popupMenu.setBorder ( popupMenu instanceof BasicComboPopup ? BorderFactory.createEmptyBorder ( 1, 1, 1, 1 ) : - // BorderFactory.createEmptyBorder ( 0, 0, 0, 0 ) ); } } @@ -283,36 +286,230 @@ public PopupMenuStyle getPopupMenuStyle () * * @param style new popup menu style */ - public void setPopupMenuStyle ( PopupMenuStyle style ) + public void setPopupMenuStyle ( final PopupMenuStyle style ) { this.popupMenuStyle = style; updateBorder (); } + /** + * Returns popup menu border color. + * + * @return popup menu border color + */ + public Color getBorderColor () + { + return borderColor; + } + + /** + * Sets popup menu border color. + * + * @param color new popup menu border color + */ + public void setBorderColor ( final Color color ) + { + this.borderColor = color; + } + + /** + * Returns popup menu border corners rounding. + * + * @return popup menu border corners rounding + */ public int getRound () { return round; } - public void setRound ( int round ) + /** + * Sets popup menu border corners rounding. + * + * @param round new popup menu border corners rounding + */ + public void setRound ( final int round ) { - // todo this.round = round; + updateBorder (); + } + + /** + * Returns popup menu shade width. + * + * @return popup menu shade width + */ + public int getShadeWidth () + { + return shadeWidth; + } + + /** + * Sets popup menu shade width. + * + * @param width new popup menu shade width + */ + public void setShadeWidth ( final int width ) + { + this.shadeWidth = width; + updateBorder (); + } + + /** + * Returns popup menu shade opacity. + * + * @return popup menu shade opacity + */ + public float getShadeOpacity () + { + return shadeOpacity; + } + + /** + * Sets popup menu shade opacity. + * + * @param opacity new popup menu shade opacity + */ + public void setShadeOpacity ( final float opacity ) + { + this.shadeOpacity = opacity; + } + + /** + * Returns popup menu dropdown style corner width. + * + * @return popup menu dropdown style corner width + */ + public int getCornerWidth () + { + return cornerWidth; + } + + /** + * Sets popup menu dropdown style corner width. + * + * @param width popup menu dropdown style corner width + */ + public void setCornerWidth ( final int width ) + { + this.cornerWidth = width; + } + + /** + * Returns popup menu content margin. + * + * @return popup menu content margin + */ + public Insets getMargin () + { + return margin; + } + + /** + * Sets popup menu content margin. + * + * @param margin new popup menu content margin + */ + public void setMargin ( final Insets margin ) + { + this.margin = margin; + } + + /** + * Returns popup menu painter. + * + * @return popup menu painter + */ + public Painter getPainter () + { + return painter; + } + + /** + * Sets popup menu painter. + * + * @param painter new popup menu painter + */ + public void setPainter ( final Painter painter ) + { + this.painter = painter; + } + + /** + * Returns spacing between menubar popup menus. + * + * @return spacing between menubar popup menus + */ + public int getMenuSpacing () + { + return menuSpacing; + } + + /** + * Sets spacing between menubar popup menus. + * + * @param spacing new spacing between menubar popup menus + */ + public void setMenuSpacing ( final int spacing ) + { + this.menuSpacing = spacing; + } + + /** + * Returns whether popup menu should try to fix its initial location when displayed or not. + * + * @return true if popup menu should try to fix its initial location when displayed, false otherwise + */ + public boolean isFixLocation () + { + return fixLocation; + } + + /** + * Sets whether popup menu should try to fix its initial location when displayed or not. + * + * @param fixLocation whether popup menu should try to fix its initial location when displayed or not + */ + public void setFixLocation ( final boolean fixLocation ) + { + this.fixLocation = fixLocation; + } + + /** + * Assists popup menu to allow it choose the best position relative to invoker. + * Its value nullified right after first usage to avoid popup menu display issues in future. + * + * @param way approximate popup menu display way + */ + public void setPopupMenuWay ( final PopupMenuWay way ) + { + this.popupMenuWay = way; + } + + /** + * Returns side where corner is currently displayed. + * + * @return side where corner is currently displayed + */ + public int getCornerSide () + { + return cornerSide; } /** * {@inheritDoc} */ @Override - public Popup getPopup ( JPopupMenu popup, int x, int y ) + public Popup getPopup ( final JPopupMenu popup, int x, int y ) { // Updating menu elements + // Be aware because at this point menu size changes + // todo Use static style so that i don't need to update menu elements from here for ( int i = 0; i < popup.getComponentCount (); i++ ) { - Component component = popup.getComponent ( i ); + final Component component = popup.getComponent ( i ); if ( component instanceof JMenu ) { - ButtonUI ui = ( ( JMenu ) component ).getUI (); + final ButtonUI ui = ( ( JMenu ) component ).getUI (); if ( ui instanceof WebMenuUI ) { ( ( WebMenuUI ) ui ).updateBorder (); @@ -320,7 +517,7 @@ public Popup getPopup ( JPopupMenu popup, int x, int y ) } else if ( component instanceof JMenuItem ) { - ButtonUI ui = ( ( JMenuItem ) component ).getUI (); + final ButtonUI ui = ( ( JMenuItem ) component ).getUI (); if ( ui instanceof WebMenuItemUI ) { ( ( WebMenuItemUI ) ui ).updateBorder (); @@ -328,51 +525,140 @@ else if ( component instanceof JMenuItem ) } } + // Updating popup location according to popup menu UI settings final Component invoker = popup.getInvoker (); - final Point los = invoker.getLocationOnScreen (); - if ( invoker instanceof JMenu ) + final Point los = invoker.isShowing () ? invoker.getLocationOnScreen () : null; + final boolean fixLocation = this.fixLocation && invoker.isShowing (); + final boolean ltr = invoker.getComponentOrientation ().isLeftToRight (); + if ( invoker != null ) { - if ( invoker.getParent () instanceof JPopupMenu ) + if ( invoker instanceof JMenu ) { - // Displaying simple-styled sub-menu - setPopupMenuStyle ( PopupMenuStyle.simple ); - if ( fixLocation ) + if ( invoker.getParent () instanceof JPopupMenu ) { - x += ( los.getX () < x ? -1 : 1 ) * ( transparent ? shadeWidth - menuSpacing : 0 ); - y -= transparent ? shadeWidth + round + 1 : round; + // Displaying simple-styled sub-menu + // It is displayed to left or right of the menu item + setPopupMenuStyle ( PopupMenuStyle.simple ); + if ( fixLocation ) + { + // Invoker X-location on screen also works as orientation indicator, so we don't need to check it here + x += ( los.x <= x ? -1 : 1 ) * ( transparent ? shadeWidth - menuSpacing : -menuSpacing ); + y += ( los.y <= y ? -1 : 1 ) * ( transparent ? shadeWidth + 1 + round : round ); + } } - } - else if ( !WebPopupMenuStyle.dropdownStyleForMenuBar ) - { - // Displaying simple-styled top-level menu - setPopupMenuStyle ( PopupMenuStyle.simple ); - if ( fixLocation ) + else if ( !WebPopupMenuStyle.dropdownStyleForMenuBar ) + { + // Displaying simple-styled top-level menu + // It is displayed below or above the menu bar + setPopupMenuStyle ( PopupMenuStyle.simple ); + if ( fixLocation ) + { + // Invoker X-location on screen also works as orientation indicator, so we don't need to check it here + x += ( los.x <= x ? -1 : 1 ) * ( transparent ? shadeWidth - menuSpacing : -menuSpacing ); + y -= transparent ? shadeWidth + round + 1 : round; + } + } + else { - x += ( los.getX () <= x ? -1 : 1 ) * ( transparent ? shadeWidth - menuSpacing : 0 ); - y -= transparent ? shadeWidth + round + 1 : round; + // Displaying dropdown-styled top-level menu + // It is displayed below or above the menu bar + setPopupMenuStyle ( PopupMenuStyle.dropdown ); + cornerSide = los.y <= y ? NORTH : SOUTH; + if ( fixLocation ) + { + // Invoker X-location on screen also works as orientation indicator, so we don't need to check it here + x += ( los.x <= x ? -1 : 1 ) * ( transparent ? shadeWidth : 0 ); + y += ( los.y <= y ? -1 : 1 ) * ( transparent ? shadeWidth - cornerWidth : 0 ); + } + relativeCorner = los.x + invoker.getWidth () / 2 - x; } } else { - // Displaying dropdown-styled top-level menu - setPopupMenuStyle ( PopupMenuStyle.dropdown ); - if ( fixLocation ) + final boolean dropdown = popupMenuStyle == PopupMenuStyle.dropdown; + if ( invoker instanceof JComboBox && popup.getName ().equals ( "ComboPopup.popup" ) ) + { + cornerSide = los.y <= y ? NORTH : SOUTH; + if ( fixLocation ) + { + x += transparent ? -shadeWidth : 0; + if ( cornerSide == NORTH ) + { + y -= transparent ? ( shadeWidth - ( dropdown ? cornerWidth : 0 ) ) : 0; + } + else + { + y -= invoker.getHeight () + ( transparent ? ( shadeWidth - ( dropdown ? cornerWidth : 0 ) ) : 0 ); + } + } + relativeCorner = los.x + invoker.getWidth () / 2 - x; + } + else { - x += ( los.getX () <= x ? -1 : 1 ) * ( transparent ? shadeWidth : 0 ); + if ( fixLocation ) + { + // Applying new location according to specified popup menu way + if ( popupMenuWay != null ) + { + final Dimension ps = popupMenu.getPreferredSize (); + final Dimension is = invoker.getSize (); + final int cornerShear = dropdown ? shadeWidth - cornerWidth : 0; + switch ( popupMenuWay ) + { + case aboveStart: + { + x = ( ltr ? los.x : los.x + is.width - ps.width ) + + ( transparent ? ( ltr ? -shadeWidth : shadeWidth ) : 0 ); + y = los.y - ps.height + cornerShear; + relativeCorner = ltr ? 0 : Integer.MAX_VALUE; + break; + } + case aboveMiddle: + { + x = los.x + is.width / 2 - ps.width / 2; + y = los.y - ps.height + cornerShear; + relativeCorner = los.x + invoker.getWidth () / 2 - x; + break; + } + case aboveEnd: + { + x = ( ltr ? los.x + is.width - ps.width : los.x ) + + ( transparent ? ( ltr ? shadeWidth : -shadeWidth ) : 0 ); + y = los.y - ps.height + cornerShear; + relativeCorner = ltr ? Integer.MAX_VALUE : 0; + break; + } + case belowStart: + { + x = ( ltr ? los.x : los.x + is.width - ps.width ) + + ( transparent ? ( ltr ? -shadeWidth : shadeWidth ) : 0 ); + y = los.y + is.height - cornerShear; + relativeCorner = ltr ? 0 : Integer.MAX_VALUE; + break; + } + case belowMiddle: + { + x = los.x + is.width / 2 - ps.width / 2; + y = los.y + is.height - cornerShear; + relativeCorner = los.x + invoker.getWidth () / 2 - x; + break; + } + case belowEnd: + { + x = ( ltr ? los.x + is.width - ps.width : los.x ) + + ( transparent ? ( ltr ? shadeWidth : -shadeWidth ) : 0 ); + y = los.y + is.height - cornerShear; + relativeCorner = ltr ? Integer.MAX_VALUE : 0; + break; + } + } + cornerSide = popupMenuWay.getCornerSide (); + popupMenuWay = null; + } + } } - relativeCorner = los.x + invoker.getWidth () / 2 - x; - cornerSide = los.y <= y ? SwingConstants.NORTH : SwingConstants.SOUTH; } } - else - { - // todo Update corner location - // todo Update corner side - // relativeCorner = ... - relativeCorner = los.x + invoker.getWidth () / 2 - x; - } - - updateBorder (); return super.getPopup ( popup, x, y ); } @@ -399,27 +685,15 @@ public void paint ( final Graphics g, final JComponent c ) shade.paintIcon ( g2d, getShadeBounds ( mb ) ); // Menu direction from component: -> down -> right - final Shape border = getComplexShape ( mb, false ); - final Shape fill = getComplexShape ( mb, true ); + final Shape border = getBorderShape ( mb, false ); + final Shape fill = getBorderShape ( mb, true ); // Background - g2d.setColor ( backgroundColor ); + g2d.setColor ( popupMenu.getBackground () ); g2d.fill ( fill ); - if ( popupMenuStyle == PopupMenuStyle.dropdown && round == 0 ) - { - Component component = popupMenu.getComponent ( 0 ); - if ( component instanceof JMenuItem ) - { - JMenuItem menuItem = ( JMenuItem ) component; - if ( menuItem.getModel ().isArmed () ) - { - final Shape dropdown = createDropdownCornerShape ( mb, true ); - g2d.setColor ( WebMenuItemStyle.topBg ); - g2d.fill ( dropdown ); - } - } - } + // Corner fill + fillDropdownCorner ( g2d, mb ); // Border g2d.setPaint ( borderColor ); @@ -428,30 +702,69 @@ public void paint ( final Graphics g, final JComponent c ) else { // Background - g2d.setColor ( backgroundColor ); - g2d.fillRoundRect ( 1, 1, c.getWidth () - 2, c.getHeight () - 2, round * 2, round * 2 ); + g2d.setColor ( popupMenu.getBackground () ); + g2d.fillRoundRect ( 1, 1, popupMenu.getWidth () - 2, popupMenu.getHeight () - 2, round * 2, round * 2 ); // Border g2d.setColor ( borderColor ); - g2d.drawRoundRect ( 0, 0, c.getWidth () - 1, c.getHeight () - 1, round * 2, round * 2 ); + g2d.drawRoundRect ( 0, 0, popupMenu.getWidth () - 1, popupMenu.getHeight () - 1, round * 2, round * 2 ); } LafUtils.restoreAntialias ( g2d, aa ); } + /** + * Fills dropdown-styled popup menu corner if menu item near it is selected. + * + * @param g2d graphics context + * @param mb menu bounds on screen + */ + protected void fillDropdownCorner ( Graphics2D g2d, Rectangle mb ) + { + if ( popupMenuStyle == PopupMenuStyle.dropdown && round == 0 ) + { + // Checking whether corner should be filled or not + final boolean north = cornerSide == NORTH; + final int zIndex = north ? 0 : popupMenu.getComponentCount () - 1; + final Component component = popupMenu.getComponent ( zIndex ); + if ( component instanceof JMenuItem ) + { + final JMenuItem menuItem = ( JMenuItem ) component; + final ButtonModel model = menuItem.getModel (); + if ( model.isArmed () || model.isSelected () ) + { + // Filling corner properly + if ( menuItem.getUI () instanceof WebMenuUI ) + { + final WebMenuUI ui = ( WebMenuUI ) menuItem.getUI (); + g2d.setPaint ( north ? ui.getNorthCornerFill () : ui.getSouthCornerFill () ); + g2d.fill ( createDropdownCornerShape ( mb, true ) ); + } + else if ( menuItem.getUI () instanceof WebMenuItemUI ) + { + final WebMenuItemUI ui = ( WebMenuItemUI ) menuItem.getUI (); + g2d.setPaint ( north ? ui.getNorthCornerFill () : ui.getSouthCornerFill () ); + g2d.fill ( createDropdownCornerShape ( mb, true ) ); + } + } + } + } + } + + /** + * Returns popup menu shade bounds. + * + * @param mb menu bounds on screen + * @return popup menu shade bounds + */ protected Rectangle getShadeBounds ( final Rectangle mb ) { switch ( popupMenuStyle ) { case simple: - { - return new Rectangle ( 0, 0, mb.width, mb.height ); - } case dropdown: { - // todo Change depending on popup menu position - final int shear = Math.max ( 0, cornerWidth - shadeWidth ); - return new Rectangle ( 0, shear, mb.width, mb.height - shear ); + return new Rectangle ( 0, 0, mb.width, mb.height ); } default: { @@ -460,7 +773,14 @@ protected Rectangle getShadeBounds ( final Rectangle mb ) } } - protected Shape getComplexShape ( final Rectangle mb, final boolean fill ) + /** + * Returns popup menu border shape. + * + * @param mb menu bounds on screen + * @param fill whether it is a fill shape or not + * @return popup menu border shape + */ + protected Shape getBorderShape ( final Rectangle mb, final boolean fill ) { switch ( popupMenuStyle ) { @@ -470,7 +790,6 @@ protected Shape getComplexShape ( final Rectangle mb, final boolean fill ) } case dropdown: { - // todo Change depending on popup menu position return createDropdownShape ( mb, fill ); } default: @@ -480,6 +799,13 @@ protected Shape getComplexShape ( final Rectangle mb, final boolean fill ) } } + /** + * Creates and returns simple menu shape. + * + * @param mb menu bounds on screen + * @param fill whether it is a fill shape or not + * @return simple menu shape + */ protected GeneralPath createSimpleShape ( final Rectangle mb, final boolean fill ) { final int shear = fill ? 1 : 0; @@ -500,10 +826,17 @@ protected GeneralPath createSimpleShape ( final Rectangle mb, final boolean fill return shape; } - protected GeneralPath createDropdownCornerShape ( final Rectangle mb, final boolean fill ) + /** + * Creates and returns dropdown style shape. + * + * @param mb menu bounds on screen + * @param fill whether it is a fill shape or not + * @return dropdown style shape + */ + protected GeneralPath createDropdownShape ( final Rectangle mb, final boolean fill ) { - final boolean north = cornerSide == SwingConstants.NORTH; - final boolean south = cornerSide == SwingConstants.SOUTH; + final boolean north = cornerSide == NORTH; + final boolean south = cornerSide == SOUTH; // Painting shear final int shear = fill ? 1 : 0; @@ -513,37 +846,52 @@ protected GeneralPath createDropdownCornerShape ( final Rectangle mb, final bool final int spacing = relativeCorner < shadeWidth + round + cornerWidth ? 0 : Math.min ( relativeCorner - ds, mb.width - ds * 2 ); // Side spacings - final int top = north ? cornerWidth + shear : shadeWidth + shear; - final int botom = south ? mb.height - 1 - cornerWidth : mb.height - 1 - shadeWidth; + final int top = shadeWidth + shear; final int left = shadeWidth + shear; - // final int right = mb.width - 1 - shadeWidth; + final int botom = mb.height - 1 - shadeWidth; + final int right = mb.width - 1 - shadeWidth; final GeneralPath shape = new GeneralPath ( GeneralPath.WIND_EVEN_ODD ); + shape.moveTo ( left, top + round ); + shape.quadTo ( left, top, left + round, top ); if ( north ) { // Top corner - shape.moveTo ( left + round + spacing + cornerWidth, top ); + shape.lineTo ( left + round + spacing + cornerWidth, top ); shape.lineTo ( left + round + spacing + cornerWidth * 2, top - cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 2 + 1, top - cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 3 + 1, top ); - shape.closePath (); } + shape.lineTo ( right - round, top ); + shape.quadTo ( right, top, right, top + round ); + shape.lineTo ( right, botom - round ); + shape.quadTo ( right, botom, right - round, botom ); if ( south ) { // Bottom corner - shape.moveTo ( left + round + spacing + cornerWidth * 3 + 1, botom ); + shape.lineTo ( left + round + spacing + cornerWidth * 3 + 1, botom ); shape.lineTo ( left + round + spacing + cornerWidth * 2 + 1, botom + cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 2, botom + cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth, botom ); - shape.closePath (); } + shape.lineTo ( left + round, botom ); + shape.quadTo ( left, botom, shadeWidth, botom - round ); + shape.closePath (); return shape; } - protected GeneralPath createDropdownShape ( final Rectangle mb, final boolean fill ) + /** + * Creates and returns dropdown style corner shape. + * It is used to paint corner fill when menu item at the same as corner side of popup menu is selected. + * + * @param mb menu bounds on screen + * @param fill whether it is a fill shape or not + * @return dropdown style corner shape + */ + protected GeneralPath createDropdownCornerShape ( final Rectangle mb, final boolean fill ) { - final boolean north = cornerSide == SwingConstants.NORTH; - final boolean south = cornerSide == SwingConstants.SOUTH; + final boolean north = cornerSide == NORTH; + final boolean south = cornerSide == SOUTH; // Painting shear final int shear = fill ? 1 : 0; @@ -553,141 +901,29 @@ protected GeneralPath createDropdownShape ( final Rectangle mb, final boolean fi final int spacing = relativeCorner < shadeWidth + round + cornerWidth ? 0 : Math.min ( relativeCorner - ds, mb.width - ds * 2 ); // Side spacings - final int top = north ? cornerWidth + shear : shadeWidth + shear; - final int botom = south ? mb.height - 1 - cornerWidth : mb.height - 1 - shadeWidth; + final int top = shadeWidth + shear; final int left = shadeWidth + shear; - final int right = mb.width - 1 - shadeWidth; + final int botom = mb.height - 1 - shadeWidth; final GeneralPath shape = new GeneralPath ( GeneralPath.WIND_EVEN_ODD ); - shape.moveTo ( left, top + round ); - shape.quadTo ( left, top, left + round, top ); if ( north ) { // Top corner - shape.lineTo ( left + round + spacing + cornerWidth, top ); + shape.moveTo ( left + round + spacing + cornerWidth, top ); shape.lineTo ( left + round + spacing + cornerWidth * 2, top - cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 2 + 1, top - cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 3 + 1, top ); + shape.closePath (); } - shape.lineTo ( right - round, top ); - shape.quadTo ( right, top, right, top + round ); - shape.lineTo ( right, botom - round ); - shape.quadTo ( right, botom, right - round, botom ); if ( south ) { // Bottom corner - shape.lineTo ( left + round + spacing + cornerWidth * 3 + 1, botom ); + shape.moveTo ( left + round + spacing + cornerWidth * 3 + 1, botom ); shape.lineTo ( left + round + spacing + cornerWidth * 2 + 1, botom + cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth * 2, botom + cornerWidth ); shape.lineTo ( left + round + spacing + cornerWidth, botom ); + shape.closePath (); } - shape.lineTo ( left + round, botom ); - shape.quadTo ( left, botom, shadeWidth, botom - round ); - shape.closePath (); return shape; } - - public static void main ( String[] args ) - { - WebLookAndFeel.install (); - // WebLookAndFeel.setDecorateAllWindows ( true ); - - // StyleConstants.smallRound = 0; - // StyleConstants.mediumRound = 0; - // StyleConstants.bigRound = 0; - // StyleConstants.largeRound = 0; - - final WebPopupMenu menu = new WebPopupMenu (); - menu.add ( new WebColorChooserPanel ( false ).setMargin ( 0, 7, 0, 7 ) ); - - TestFrame tf = new TestFrame ( new WebButton ( "Simple menu", WebLookAndFeel.getIcon ( 16 ), new ActionListener () - { - @Override - public void actionPerformed ( ActionEvent e ) - { - menu.showUnder ( ( Component ) e.getSource () ); - } - } ), 250 ); - - WebMenuBar menuBar = new WebMenuBar (); - menuBar.setUndecorated ( true ); - menuBar.add ( fillMenu ( new WebMenu ( "File" ) ) ); - menuBar.add ( fillMenu ( new WebMenu ( "Edit" ) ) ); - menuBar.add ( fillMenu ( new WebMenu ( "Help" ) ) ); - menuBar.add ( fillMenu ( new WebMenu ( "About" ) ) ); - tf.setJMenuBar ( menuBar ); - - tf.packAndCenter (); - tf.displayFrame (); - - HotkeyManager.registerHotkey ( Hotkey.ALT_R, new HotkeyRunnable () - { - @Override - public void run ( KeyEvent e ) - { - LanguageManager.changeOrientation (); - } - } ); - } - - private static WebMenu fillMenu ( WebMenu menu ) - { - final ImageIcon icon = WebLookAndFeel.getIcon ( 16 ); - // ImageUtils.combineIcons ( icon, icon ) - - menu.add ( new WebMenuItem ( "Test item", icon ) - { - { - setAccelerator ( Hotkey.CTRL_X.getKeyStroke () ); - } - } ); - menu.add ( new WebMenuItem ( "Some html content", icon ) ); - menu.addSeparator (); - menu.add ( new WebMenuItem ( "1234567890", icon ) - { - { - setAccelerator ( Hotkey.SPACE.getKeyStroke () ); - } - } ); - menu.add ( new WebMenu ( "Sub menu", icon ) - { - { - add ( new WebMenuItem ( "Sub 1" ) ); - add ( new WebMenuItem ( "Sub 2" ) ); - add ( new WebMenuItem ( "Sub 3" ) ); - add ( new WebMenu ( "Sub menu" ) - { - { - add ( new WebMenuItem ( "Sub 1" ) ); - add ( new WebMenuItem ( "Sub 2" ) ); - add ( new WebMenuItem ( "Sub 3" ) ); - } - } ); - } - } ); - menu.add ( new WebMenuItem ( "!@%#$^%*^%#", icon ) ); - menu.add ( new WebMenuItem ( "Something else", icon ) - { - { - setEnabled ( false ); - } - } ); - menu.add ( new WebMenu ( "Disabled menu", icon ) - { - { - setEnabled ( false ); - add ( new WebMenuItem ( "Sub 1" ) ); - } - } ); - menu.addSeparator (); - menu.add ( new WebMenuItem ( "QWERTYSDASZXO", icon ) - { - { - setEnabled ( false ); - setAccelerator ( Hotkey.ALT_F4.getKeyStroke () ); - } - } ); - menu.add ( new WebMenuItem ( "Last element", icon ) ); - return menu; - } } \ No newline at end of file diff --git a/src/com/alee/laf/menu/WebRadioButtonMenuItem.java b/src/com/alee/laf/menu/WebRadioButtonMenuItem.java index 1db2e7c36..d3d75c924 100644 --- a/src/com/alee/laf/menu/WebRadioButtonMenuItem.java +++ b/src/com/alee/laf/menu/WebRadioButtonMenuItem.java @@ -17,6 +17,7 @@ package com.alee.laf.menu; +import com.alee.extended.painter.Painter; import com.alee.laf.WebLookAndFeel; import com.alee.managers.hotkey.HotkeyData; import com.alee.managers.language.LanguageManager; @@ -31,64 +32,365 @@ import com.alee.utils.swing.FontMethods; import javax.swing.*; +import java.awt.*; /** - * User: mgarin Date: 19.09.11 Time: 18:42 + * This JRadioButtonMenuItem extension class provides a direct access to WebRadioButtonMenuItemUI methods. + * + * @author Mikle Garin */ public class WebRadioButtonMenuItem extends JRadioButtonMenuItem implements LanguageMethods, SettingsMethods, FontMethods { + /** + * Constructs new radiobutton menu item. + */ public WebRadioButtonMenuItem () { super (); } - public WebRadioButtonMenuItem ( Action a ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param a menu item action + */ + public WebRadioButtonMenuItem ( final Action a ) { super ( a ); } - public WebRadioButtonMenuItem ( Icon icon ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param icon menu item icon + */ + public WebRadioButtonMenuItem ( final Icon icon ) { super ( icon ); } - public WebRadioButtonMenuItem ( Icon icon, boolean selected ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param icon menu item icon + * @param selected whether this radiobutton item is selected or not + */ + public WebRadioButtonMenuItem ( final Icon icon, final boolean selected ) { super ( icon, selected ); } - public WebRadioButtonMenuItem ( String text ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param text menu item text + */ + public WebRadioButtonMenuItem ( final String text ) { super ( text ); } - public WebRadioButtonMenuItem ( String text, Icon icon ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param text menu item text + * @param icon menu item icon + */ + public WebRadioButtonMenuItem ( final String text, final Icon icon ) { super ( text, icon ); } - public WebRadioButtonMenuItem ( String text, Icon icon, boolean selected ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param text menu item text + * @param icon menu item icon + * @param selected whether this radiobutton item is selected or not + */ + public WebRadioButtonMenuItem ( final String text, final Icon icon, final boolean selected ) { super ( text, icon, selected ); } - public WebRadioButtonMenuItem ( String text, boolean selected ) + /** + * Constructs new radiobutton menu item using the specified settings. + * + * @param text + * @param selected + */ + public WebRadioButtonMenuItem ( final String text, final boolean selected ) { super ( text, selected ); } - public void setHotkey ( HotkeyData hotkey ) + /** + * Sets the key combination which invokes the menu item's action listeners without navigating the menu hierarchy. + * + * @param hotkey hotkey data + */ + public void setAccelerator ( final HotkeyData hotkey ) { SwingUtils.setAccelerator ( this, hotkey ); } + /** + * Returns menu item margin. + * + * @return menu item margin + */ + @Override + public Insets getMargin () + { + return getWebUI ().getMargin (); + } + + /** + * Sets menu item margin. + * + * @param margin new menu item margin + */ + @Override + public void setMargin ( final Insets margin ) + { + getWebUI ().setMargin ( margin ); + } + + /** + * Returns disabled menu item foreground. + * + * @return disabled menu item foreground + */ + public Color getDisabledFg () + { + return getWebUI ().getDisabledFg (); + } + + /** + * Sets disabled menu item foreground. + * + * @param foreground new disabled menu item foreground + */ + public void setDisabledFg ( final Color foreground ) + { + getWebUI ().setDisabledFg ( foreground ); + } + + /** + * Returns top background color for selected item. + * + * @return top background color for selected item + */ + public Color getSelectedTopBg () + { + return getWebUI ().getSelectedTopBg (); + } + + /** + * Sets top background color for selected item. + * + * @param background new top background color for selected item + */ + public void setSelectedTopBg ( final Color background ) + { + getWebUI ().setSelectedTopBg ( background ); + } + + /** + * Returns bottom background color for selected item. + * + * @return bottom background color for selected item + */ + public Color getSelectedBottomBg () + { + return getWebUI ().getSelectedBottomBg (); + } + + /** + * Sets bottom background color for selected item. + * + * @param background new bottom background color for selected item + */ + public void setSelectedBottomBg ( final Color background ) + { + getWebUI ().setSelectedBottomBg ( background ); + } + + /** + * Returns accelerator text background. + * + * @return accelerator text background + */ + public Color getAcceleratorBg () + { + return getWebUI ().getAcceleratorBg (); + } + + /** + * Sets accelerator text background. + * + * @param background new accelerator text background + */ + public void setAcceleratorBg ( final Color background ) + { + getWebUI ().setAcceleratorBg ( background ); + } + + /** + * Returns accelerator foreground. + * + * @return accelerator foreground + */ + public Color getAcceleratorFg () + { + return getWebUI ().getAcceleratorFg (); + } + + /** + * Sets accelerator foreground. + * + * @param foreground new accelerator foreground + */ + public void setAcceleratorFg ( final Color foreground ) + { + getWebUI ().setAcceleratorFg ( foreground ); + } + + /** + * Returns disabled accelerator foreground. + * + * @return disabled accelerator foreground + */ + public Color getAcceleratorDisabledFg () + { + return getWebUI ().getAcceleratorDisabledFg (); + } + + /** + * Sets disabled accelerator foreground. + * + * @param foreground new disabled accelerator foreground + */ + public void setAcceleratorDisabledFg ( final Color foreground ) + { + getWebUI ().setAcceleratorDisabledFg ( foreground ); + } + + /** + * Returns gap between menu item icon/text and accelerator. + * + * @return gap between menu item icon/text and accelerator + */ + public int getAcceleratorGap () + { + return getWebUI ().getAcceleratorGap (); + } + + /** + * Sets gap between menu icon/text and accelerator. + * + * @param gap new gap between menu icon/text and accelerator + */ + public void setAcceleratorGap ( final int gap ) + { + getWebUI ().setAcceleratorGap ( gap ); + } + + /** + * Returns whether should align all item texts to a single vertical line within single popup menu or not. + * + * @return true if should align all item texts to a single vertical line within single popup menu, false otherwise + */ + public boolean isAlignTextToMenuIcons () + { + return getWebUI ().isAlignTextToMenuIcons (); + } + + /** + * Sets whether should align all item texts to a single vertical line within single popup menu or not. + * + * @param align whether should align all item texts to a single vertical line within single popup menu or not + */ + public void setAlignTextToMenuIcons ( final boolean align ) + { + getWebUI ().setAlignTextToMenuIcons ( align ); + } + + /** + * Returns icon alignment. + * + * @return icon alignment + */ + public int getIconAlignment () + { + return getWebUI ().getIconAlignment (); + } + + /** + * Sets icon alignment + * + * @param alignment new icon alignment + */ + public void setIconAlignment ( final int alignment ) + { + getWebUI ().setIconAlignment ( alignment ); + } + + /** + * Returns menu item painter. + * + * @return menu item painter + */ + public Painter getPainter () + { + return getWebUI ().getPainter (); + } + + /** + * Sets menu item painter. + * + * @param painter new menu item painter + */ + public void setPainter ( final Painter painter ) + { + getWebUI ().setPainter ( painter ); + } + + /** + * Returns checkbox menu item check color. + * + * @return checkbox menu item check color + */ + public Color getCheckColor () + { + return getWebUI ().getCheckColor (); + } + + /** + * Sets checkbox menu item check color. + * + * @param color checkbox menu item check color + */ + public void setCheckColor ( final Color color ) + { + getWebUI ().setCheckColor ( color ); + } + + /** + * Returns Web-UI applied to this class. + * + * @return Web-UI applied to this class + */ public WebRadioButtonMenuItemUI getWebUI () { return ( WebRadioButtonMenuItemUI ) getUI (); } + /** + * Installs a Web-UI into this component. + */ @Override public void updateUI () { @@ -110,15 +412,11 @@ public void updateUI () } } - /** - * Language methods - */ - /** * {@inheritDoc} */ @Override - public void setLanguage ( String key, Object... data ) + public void setLanguage ( final String key, final Object... data ) { LanguageManager.registerComponent ( this, key, data ); } @@ -127,7 +425,7 @@ public void setLanguage ( String key, Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( Object... data ) + public void updateLanguage ( final Object... data ) { LanguageManager.updateComponent ( this, data ); } @@ -136,7 +434,7 @@ public void updateLanguage ( Object... data ) * {@inheritDoc} */ @Override - public void updateLanguage ( String key, Object... data ) + public void updateLanguage ( final String key, final Object... data ) { LanguageManager.updateComponent ( this, key, data ); } @@ -163,7 +461,7 @@ public boolean isLanguageSet () * {@inheritDoc} */ @Override - public void setLanguageUpdater ( LanguageUpdater updater ) + public void setLanguageUpdater ( final LanguageUpdater updater ) { LanguageManager.registerLanguageUpdater ( this, updater ); } @@ -177,15 +475,11 @@ public void removeLanguageUpdater () LanguageManager.unregisterLanguageUpdater ( this ); } - /** - * Settings methods - */ - /** * {@inheritDoc} */ @Override - public void registerSettings ( String key ) + public void registerSettings ( final String key ) { SettingsManager.registerComponent ( this, key ); } @@ -194,7 +488,7 @@ public void registerSettings ( String key ) * {@inheritDoc} */ @Override - public void registerSettings ( String key, Class defaultValueClass ) + public void registerSettings ( final String key, final Class defaultValueClass ) { SettingsManager.registerComponent ( this, key, defaultValueClass ); } @@ -203,7 +497,7 @@ public void registerSettings ( String key, Class def * {@inheritDoc} */ @Override - public void registerSettings ( String key, Object defaultValue ) + public void registerSettings ( final String key, final Object defaultValue ) { SettingsManager.registerComponent ( this, key, defaultValue ); } @@ -212,7 +506,7 @@ public void registerSettings ( String key, Object defaultValue ) * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key ) + public void registerSettings ( final String group, final String key ) { SettingsManager.registerComponent ( this, group, key ); } @@ -221,7 +515,7 @@ public void registerSettings ( String group, String key ) * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Class defaultValueClass ) + public void registerSettings ( final String group, final String key, final Class defaultValueClass ) { SettingsManager.registerComponent ( this, group, key, defaultValueClass ); } @@ -230,7 +524,7 @@ public void registerSettings ( String group, String key * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Object defaultValue ) + public void registerSettings ( final String group, final String key, final Object defaultValue ) { SettingsManager.registerComponent ( this, group, key, defaultValue ); } @@ -239,7 +533,7 @@ public void registerSettings ( String group, String key, Object defaultValue ) * {@inheritDoc} */ @Override - public void registerSettings ( String key, boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String key, final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, loadInitialSettings, applySettingsChanges ); } @@ -248,8 +542,8 @@ public void registerSettings ( String key, boolean loadInitialSettings, boolean * {@inheritDoc} */ @Override - public void registerSettings ( String key, Class defaultValueClass, boolean loadInitialSettings, - boolean applySettingsChanges ) + public void registerSettings ( final String key, final Class defaultValueClass, + final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, defaultValueClass, loadInitialSettings, applySettingsChanges ); } @@ -258,7 +552,8 @@ public void registerSettings ( String key, Class def * {@inheritDoc} */ @Override - public void registerSettings ( String key, Object defaultValue, boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String key, final Object defaultValue, final boolean loadInitialSettings, + final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, key, defaultValue, loadInitialSettings, applySettingsChanges ); } @@ -267,8 +562,8 @@ public void registerSettings ( String key, Object defaultValue, boolean loadInit * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Class defaultValueClass, - boolean loadInitialSettings, boolean applySettingsChanges ) + public void registerSettings ( final String group, final String key, final Class defaultValueClass, + final boolean loadInitialSettings, final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, group, key, defaultValueClass, loadInitialSettings, applySettingsChanges ); } @@ -277,8 +572,8 @@ public void registerSettings ( String group, String key * {@inheritDoc} */ @Override - public void registerSettings ( String group, String key, Object defaultValue, boolean loadInitialSettings, - boolean applySettingsChanges ) + public void registerSettings ( final String group, final String key, final Object defaultValue, final boolean loadInitialSettings, + final boolean applySettingsChanges ) { SettingsManager.registerComponent ( this, group, key, defaultValue, loadInitialSettings, applySettingsChanges ); } @@ -287,7 +582,7 @@ public void registerSettings ( String group, String key, Object defaultValue, bo * {@inheritDoc} */ @Override - public void registerSettings ( SettingsProcessor settingsProcessor ) + public void registerSettings ( final SettingsProcessor settingsProcessor ) { SettingsManager.registerComponent ( this, settingsProcessor ); } @@ -319,10 +614,6 @@ public void saveSettings () SettingsManager.saveComponentSettings ( this ); } - /** - * Font methods - */ - /** * {@inheritDoc} */ @@ -336,7 +627,7 @@ public WebRadioButtonMenuItem setPlainFont () * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setPlainFont ( boolean apply ) + public WebRadioButtonMenuItem setPlainFont ( final boolean apply ) { return SwingUtils.setPlainFont ( this, apply ); } @@ -363,7 +654,7 @@ public WebRadioButtonMenuItem setBoldFont () * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setBoldFont ( boolean apply ) + public WebRadioButtonMenuItem setBoldFont ( final boolean apply ) { return SwingUtils.setBoldFont ( this, apply ); } @@ -390,7 +681,7 @@ public WebRadioButtonMenuItem setItalicFont () * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setItalicFont ( boolean apply ) + public WebRadioButtonMenuItem setItalicFont ( final boolean apply ) { return SwingUtils.setItalicFont ( this, apply ); } @@ -408,7 +699,7 @@ public boolean isItalicFont () * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontStyle ( boolean bold, boolean italic ) + public WebRadioButtonMenuItem setFontStyle ( final boolean bold, final boolean italic ) { return SwingUtils.setFontStyle ( this, bold, italic ); } @@ -417,7 +708,7 @@ public WebRadioButtonMenuItem setFontStyle ( boolean bold, boolean italic ) * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontStyle ( int style ) + public WebRadioButtonMenuItem setFontStyle ( final int style ) { return SwingUtils.setFontStyle ( this, style ); } @@ -426,7 +717,7 @@ public WebRadioButtonMenuItem setFontStyle ( int style ) * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontSize ( int fontSize ) + public WebRadioButtonMenuItem setFontSize ( final int fontSize ) { return SwingUtils.setFontSize ( this, fontSize ); } @@ -435,7 +726,7 @@ public WebRadioButtonMenuItem setFontSize ( int fontSize ) * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem changeFontSize ( int change ) + public WebRadioButtonMenuItem changeFontSize ( final int change ) { return SwingUtils.changeFontSize ( this, change ); } @@ -453,7 +744,7 @@ public int getFontSize () * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontSizeAndStyle ( int fontSize, boolean bold, boolean italic ) + public WebRadioButtonMenuItem setFontSizeAndStyle ( final int fontSize, final boolean bold, final boolean italic ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, bold, italic ); } @@ -462,7 +753,7 @@ public WebRadioButtonMenuItem setFontSizeAndStyle ( int fontSize, boolean bold, * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontSizeAndStyle ( int fontSize, int style ) + public WebRadioButtonMenuItem setFontSizeAndStyle ( final int fontSize, final int style ) { return SwingUtils.setFontSizeAndStyle ( this, fontSize, style ); } @@ -471,7 +762,7 @@ public WebRadioButtonMenuItem setFontSizeAndStyle ( int fontSize, int style ) * {@inheritDoc} */ @Override - public WebRadioButtonMenuItem setFontName ( String fontName ) + public WebRadioButtonMenuItem setFontName ( final String fontName ) { return SwingUtils.setFontName ( this, fontName ); } diff --git a/src/com/alee/laf/menu/WebRadioButtonMenuItemUI.java b/src/com/alee/laf/menu/WebRadioButtonMenuItemUI.java index 2c99b1f03..6c611fb27 100644 --- a/src/com/alee/laf/menu/WebRadioButtonMenuItemUI.java +++ b/src/com/alee/laf/menu/WebRadioButtonMenuItemUI.java @@ -19,6 +19,7 @@ import javax.swing.*; import javax.swing.plaf.ComponentUI; +import java.awt.*; /** * Custom UI for JRadioButtonMenuItem component. @@ -28,6 +29,11 @@ public class WebRadioButtonMenuItemUI extends WebMenuItemUI { + /** + * Style settings. + */ + protected Color checkColor = WebMenuItemStyle.checkColor; + /** * Returns an instance of the WebRadioButtonMenuItemUI for the specified component. * This tricky method is used by UIManager to create component UIs when needed. @@ -35,8 +41,8 @@ public class WebRadioButtonMenuItemUI extends WebMenuItemUI * @param c component that will use UI instance * @return instance of the WebRadioButtonMenuItemUI */ - @SuppressWarnings ( "UnusedParameters" ) - public static ComponentUI createUI ( JComponent c ) + @SuppressWarnings ("UnusedParameters") + public static ComponentUI createUI ( final JComponent c ) { return new WebRadioButtonMenuItemUI (); } @@ -51,4 +57,41 @@ protected String getPropertyPrefix () { return "RadioButtonMenuItem"; } -} + + /** + * Returns radiobutton menu item check color. + * + * @return radiobutton menu item check color + */ + public Color getCheckColor () + { + return checkColor; + } + + /** + * Sets radiobutton menu item check color. + * + * @param color radiobutton menu item check color + */ + public void setCheckColor ( final Color color ) + { + this.checkColor = color; + } + + /** + * {@inheritDoc} + */ + @Override + protected void paintBackground ( final Graphics2D g2d, final JMenuItem menuItem, final int x, final int y, final int w, final int h, + final boolean selected, final boolean ltr ) + { + super.paintBackground ( g2d, menuItem, x, y, w, h, selected, ltr ); + + // Painting check selection + if ( painter == null && !selected && menuItem.isSelected () ) + { + g2d.setPaint ( checkColor ); + g2d.fillRect ( 0, 0, menuItem.getWidth (), menuItem.getHeight () ); + } + } +} \ No newline at end of file diff --git a/src/com/alee/laf/menu/icons/arrowLeft.png b/src/com/alee/laf/menu/icons/arrowLeft.png new file mode 100644 index 000000000..30f0f449f Binary files /dev/null and b/src/com/alee/laf/menu/icons/arrowLeft.png differ diff --git a/src/com/alee/laf/menu/icons/arrowRight.png b/src/com/alee/laf/menu/icons/arrowRight.png new file mode 100644 index 000000000..dfcbf36f3 Binary files /dev/null and b/src/com/alee/laf/menu/icons/arrowRight.png differ diff --git a/src/com/alee/managers/hotkey/Hotkey.java b/src/com/alee/managers/hotkey/Hotkey.java index e8e5b0004..4f68a851e 100644 --- a/src/com/alee/managers/hotkey/Hotkey.java +++ b/src/com/alee/managers/hotkey/Hotkey.java @@ -82,6 +82,20 @@ public final class Hotkey public static final HotkeyData Y = new HotkeyData ( KeyEvent.VK_Y ); public static final HotkeyData Z = new HotkeyData ( KeyEvent.VK_Z ); + /** + * Number hotkeys. + */ + public static final HotkeyData NUMBER_0 = new HotkeyData ( KeyEvent.VK_0 ); + public static final HotkeyData NUMBER_1 = new HotkeyData ( KeyEvent.VK_1 ); + public static final HotkeyData NUMBER_2 = new HotkeyData ( KeyEvent.VK_2 ); + public static final HotkeyData NUMBER_3 = new HotkeyData ( KeyEvent.VK_3 ); + public static final HotkeyData NUMBER_4 = new HotkeyData ( KeyEvent.VK_4 ); + public static final HotkeyData NUMBER_5 = new HotkeyData ( KeyEvent.VK_5 ); + public static final HotkeyData NUMBER_6 = new HotkeyData ( KeyEvent.VK_6 ); + public static final HotkeyData NUMBER_7 = new HotkeyData ( KeyEvent.VK_7 ); + public static final HotkeyData NUMBER_8 = new HotkeyData ( KeyEvent.VK_8 ); + public static final HotkeyData NUMBER_9 = new HotkeyData ( KeyEvent.VK_9 ); + /** * Specific hotkeys. */ diff --git a/src/com/alee/managers/tooltip/HotkeyTipLabel.java b/src/com/alee/managers/tooltip/HotkeyTipLabel.java index 35f2ee117..b70c9cac7 100644 --- a/src/com/alee/managers/tooltip/HotkeyTipLabel.java +++ b/src/com/alee/managers/tooltip/HotkeyTipLabel.java @@ -21,11 +21,16 @@ import com.alee.utils.SwingUtils; /** - * User: mgarin Date: 24.09.12 Time: 16:11 + * Custom label used to display hotkey within WebCustomTooltip component. + * + * @author Mikle Garin */ public class HotkeyTipLabel extends WebLabel { + /** + * Constructs new hotkey tip label. + */ public HotkeyTipLabel () { super (); diff --git a/src/com/alee/managers/tooltip/HotkeyTipPainter.java b/src/com/alee/managers/tooltip/HotkeyTipPainter.java index 4624663ad..85bc5ae83 100644 --- a/src/com/alee/managers/tooltip/HotkeyTipPainter.java +++ b/src/com/alee/managers/tooltip/HotkeyTipPainter.java @@ -18,32 +18,43 @@ package com.alee.managers.tooltip; import com.alee.extended.painter.DefaultPainter; +import com.alee.laf.StyleConstants; import com.alee.utils.LafUtils; import java.awt.*; /** - * User: mgarin Date: 24.09.12 Time: 16:02 + * Custom painter for HotkeyTipLabel component. + * + * @author Mikle Garin */ public class HotkeyTipPainter extends DefaultPainter { - private static Color bg = new Color ( 255, 255, 255, 178 ); - private static int round = 4; - private static Insets margin = new Insets ( 0, 3, 1, 3 ); + /** + * Style constants. + */ + protected static Color bg = new Color ( 255, 255, 255, 178 ); + protected static int round = StyleConstants.smallRound; + /** + * Constructs new hotkey tip painter. + */ public HotkeyTipPainter () { super (); - setMargin ( margin ); + setMargin ( new Insets ( 0, 3, 1, 3 ) ); } + /** + * {@inheritDoc} + */ @Override public void paint ( Graphics2D g2d, Rectangle bounds, HotkeyTipLabel c ) { Object aa = LafUtils.setupAntialias ( g2d ); g2d.setColor ( bg ); - g2d.fillRoundRect ( bounds.x, bounds.y, bounds.width, bounds.height, round, round ); + g2d.fillRoundRect ( bounds.x, bounds.y, bounds.width, bounds.height, round * 2, round * 2 ); LafUtils.restoreAntialias ( g2d, aa ); } } \ No newline at end of file diff --git a/src/com/alee/managers/tooltip/WebCustomTooltipStyle.java b/src/com/alee/managers/tooltip/WebCustomTooltipStyle.java index d68cde0e2..d74d9e579 100644 --- a/src/com/alee/managers/tooltip/WebCustomTooltipStyle.java +++ b/src/com/alee/managers/tooltip/WebCustomTooltipStyle.java @@ -44,7 +44,7 @@ public final class WebCustomTooltipStyle /** * Tooltip "corner" element length. */ - public static int cornerLength = 10; + public static int cornerLength = 8; /** * Tooltip "corner" element side width.