001package jmri.jmrit.display; 002 003import java.awt.Color; 004import java.awt.Font; 005import java.awt.GraphicsEnvironment; 006import java.awt.event.ActionEvent; 007import java.util.ArrayList; 008import javax.swing.AbstractAction; 009import javax.swing.BorderFactory; 010import javax.swing.ButtonGroup; 011import javax.swing.JCheckBoxMenuItem; 012import javax.swing.JComponent; 013import javax.swing.JLabel; 014import javax.swing.JMenu; 015import javax.swing.JMenuItem; 016import javax.swing.JPopupMenu; 017import javax.swing.JRadioButtonMenuItem; 018import javax.swing.JTextField; 019import javax.swing.border.Border; 020import javax.swing.border.CompoundBorder; 021import javax.swing.border.LineBorder; 022import jmri.util.MenuScroller; 023import jmri.util.swing.JmriColorChooser; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027/** 028 * This class handles text attributes for Positionables. Font, size, style and 029 * color. Margin size and color, Border size and color, Fixed sizes. 030 * Justification. 031 * <p> 032 * moved from PositionableLabel 033 * 034 * @author Pete Cressman copyright (C) 2010 035 */ 036public class PositionablePopupUtil { 037 038 protected JComponent _textComponent; // closest ancestor for JLabel and JTextField 039 protected int _textType; // JComponent does not have text, used for casting 040 protected Positionable _parent; 041 protected PositionablePopupUtil _self; 042 protected PositionablePropertiesUtil _propertiesUtil; 043 044 private final Color defaultBorderColor; 045 private boolean _suppressRecentColor = false; 046 047 protected final int LABEL = 1; 048 protected final int TEXTFIELD = 2; 049 protected final int JCOMPONENT = 3; 050 051 public PositionablePopupUtil(Positionable parent, JComponent textComp) { 052 _parent = parent; 053 if (textComp instanceof JLabel) { 054 _textType = LABEL; 055 } else if (textComp instanceof JTextField) { 056 _textType = TEXTFIELD; 057 } else { 058 _textType = JCOMPONENT; 059 } 060 _textComponent = textComp; 061 _self = this; 062 063 defaultBorderColor = _parent.getBackground(); 064 _propertiesUtil = new PositionablePropertiesUtil(_parent); 065 } 066 067 public PositionablePopupUtil clone(Positionable parent, JComponent textComp) { 068 PositionablePopupUtil util = new PositionablePopupUtil(parent, textComp); 069 util.setJustification(getJustification()); 070 util.setHorizontalAlignment(getJustification()); 071 util.setFixedWidth(getFixedWidth()); 072 util.setFixedHeight(getFixedHeight()); 073 util.setMargin(getMargin()); 074 util.setBorderSize(getBorderSize()); 075 util.setBorderColor(getBorderColor()); 076 util.setFont(getFont().deriveFont(getFontStyle())); 077 util.setFontSize(getFontSize()); 078 util.setFontStyle(getFontStyle()); 079 util.setOrientation(getOrientation()); 080 util.setBackgroundColor(getBackground()); 081 util.setForeground(getForeground()); 082 util.setHasBackground(hasBackground()); // must do this AFTER setBackgroundColor 083 return util; 084 } 085 086 @Override 087 public String toString() { 088 return _parent.getNameString() + ": fixedWidth= " + fixedWidth + ", fixedHeight= " + fixedHeight 089 + ", margin= " + margin + ", borderSize= " + borderSize; 090 } 091 092 /** 093 * ************************************************************************************* 094 */ 095 static final public int FONT_COLOR = 0x00; 096 static final public int BACKGROUND_COLOR = 0x01; 097 static final public int BORDER_COLOR = 0x02; 098 static final public int MIN_SIZE = 5; 099 100 private int fixedWidth = 0; 101 private int fixedHeight = 0; 102 private int margin = 0; 103 private int borderSize = 0; 104 private Color borderColor = null; 105 private Border borderMargin = BorderFactory.createEmptyBorder(0, 0, 0, 0); 106 private Border outlineBorder = BorderFactory.createEmptyBorder(0, 0, 0, 0); 107 private boolean _hasBackground; // Should background be painted or clear 108 109 JMenuItem italic = null; 110 JMenuItem bold = null; 111 112 public void propertyUtil(JPopupMenu popup) { 113 JMenuItem edit = new JMenuItem(Bundle.getMessage("MenuItemProperties") + "..."); 114 edit.addActionListener((ActionEvent e) -> _propertiesUtil.display()); 115 popup.add(edit); 116 } 117 118 public void setFixedTextMenu(JPopupMenu popup) { 119 JMenu edit = new JMenu(Bundle.getMessage("EditFixed")); 120 JMenuItem jmi; 121 if (getFixedWidth() == 0) { 122 jmi = edit.add("Width = Auto"); 123 } else { 124 jmi = edit.add("Width = " + _parent.maxWidth()); 125 } 126 jmi.setEnabled(false); 127 128 if (getFixedHeight() == 0) { 129 jmi = edit.add("Height = Auto"); 130 } else { 131 jmi = edit.add("Height = " + _parent.maxHeight()); 132 } 133 jmi.setEnabled(false); 134 135 edit.add(CoordinateEdit.getFixedSizeEditAction(_parent)); 136 137 popup.add(edit); 138 } 139 140 public void setTextMarginMenu(JPopupMenu popup) { 141 JMenu edit = new JMenu(Bundle.getMessage("EditMargin")); 142 if ((fixedHeight == 0) || (fixedWidth == 0)) { 143 JMenuItem jmi = edit.add("Margin = " + getMargin()); 144 jmi.setEnabled(false); 145 edit.add(CoordinateEdit.getMarginEditAction(_parent)); 146 } 147 popup.add(edit); 148 } 149 150 public void setBackgroundMenu(JPopupMenu popup) { 151 JMenuItem edit = new JMenuItem(Bundle.getMessage("FontBackgroundColor")); 152 edit.addActionListener((ActionEvent event) -> { 153 Color desiredColor = JmriColorChooser.showDialog(_textComponent, 154 Bundle.getMessage("FontBackgroundColor"), 155 getBackground()); 156 if (desiredColor!=null ) { 157 setBackgroundColor(desiredColor); 158 } 159 }); 160 161 popup.add(edit); 162 163 } 164 165 public void setTextBorderMenu(JPopupMenu popup) { 166 JMenu edit = new JMenu(Bundle.getMessage("EditBorder")); 167 JMenuItem jmi = edit.add("Border Size = " + borderSize); 168 jmi.setEnabled(false); 169 edit.add(CoordinateEdit.getBorderEditAction(_parent)); 170 JMenuItem colorMenu = new JMenuItem(Bundle.getMessage("BorderColorMenu")); 171 colorMenu.addActionListener((ActionEvent event) -> { 172 Color desiredColor = JmriColorChooser.showDialog(_textComponent, 173 Bundle.getMessage("BorderColorMenu"), 174 defaultBorderColor); 175 if (desiredColor!=null ) { 176 setBorderColor(desiredColor); 177 } 178 }); 179 edit.add(colorMenu); 180 popup.add(edit); 181 } 182 183 public void setTextFontMenu(JPopupMenu popup) { 184 JMenu edit = new JMenu(Bundle.getMessage("EditFont")); 185 edit.add(makeFontMenu()); 186 edit.add(makeFontSizeMenu()); 187 edit.add(makeFontStyleMenu()); 188 JMenuItem colorMenu = new JMenuItem(Bundle.getMessage("FontColor")); 189 colorMenu.addActionListener((ActionEvent event) -> { 190 Color desiredColor = JmriColorChooser.showDialog(_textComponent, 191 Bundle.getMessage("FontColor"), 192 _textComponent.getForeground()); 193 if (desiredColor!=null ) { 194 _textComponent.setForeground(desiredColor); 195 } 196 }); 197 edit.add(colorMenu); 198 popup.add(edit); 199 } 200 201 public int getMargin() { 202 return margin; 203 } 204 205 public void setMargin(int m) { 206 margin = m; 207 if (_parent.isOpaque()) { 208 borderMargin = new LineBorder(getBackground(), m); 209 } else { 210 borderMargin = BorderFactory.createEmptyBorder(m, m, m, m); 211 } 212 if (_showBorder) { 213 _parent.setBorder(new CompoundBorder(outlineBorder, borderMargin)); 214 } 215 _parent.updateSize(); 216 } 217 218 public int getFixedWidth() { 219 return fixedWidth; 220 } 221 222 public void setFixedWidth(int w) { 223 fixedWidth = w; 224 if (log.isDebugEnabled()) { 225 log.debug("setFixedWidth()={}", getFixedWidth()); 226 } 227 _parent.updateSize(); 228 } 229 230 public int getFixedHeight() { 231 return fixedHeight; 232 } 233 234 public void setFixedHeight(int h) { 235 fixedHeight = h; 236 log.debug("setFixedHeight()={}", getFixedHeight()); 237 _parent.updateSize(); 238 } 239 240 public void setFixedSize(int w, int h) { 241 fixedWidth = w; 242 fixedHeight = h; 243 log.debug("setFixedSize()=({},{})", getFixedWidth(), getFixedHeight()); 244 _parent.updateSize(); 245 } 246 247 public void setBorderSize(int border) { 248 borderSize = border; 249 250 if (borderColor != null) { 251 outlineBorder = new LineBorder(borderColor, borderSize); 252 _parent.setBorder(new CompoundBorder(outlineBorder, borderMargin)); 253 //setHorizontalAlignment(CENTRE); 254 } 255 _parent.updateSize(); 256 } 257 258 private boolean _showBorder = true; 259 260 public void setBorder(boolean set) { 261 _showBorder = set; 262 if (set) { 263 if (borderColor != null ) { 264 outlineBorder = new LineBorder(borderColor, borderSize); 265 _parent.setBorder(new CompoundBorder(outlineBorder, borderMargin)); 266 } 267 } else { 268 _parent.setBorder(null); 269 } 270 } 271 272 public int getBorderSize() { 273 return borderSize; 274 } 275 276 public void setBorderColor(Color border) { 277 borderColor = border; 278 if (borderColor != null && _showBorder) { 279 outlineBorder = new LineBorder(borderColor, borderSize); 280 _parent.setBorder(new CompoundBorder(outlineBorder, borderMargin)); 281 } 282 if (!_suppressRecentColor) { 283 JmriColorChooser.addRecentColor(border); 284 } 285 } 286 287 public Color getBorderColor() { 288 if (borderColor == null) { 289 borderColor = _parent.getBackground(); 290 } 291 return borderColor; 292 } 293 294 public void setForeground(Color c) { 295 _textComponent.setForeground(c); 296 _parent.updateSize(); 297 if (!_suppressRecentColor) { 298 JmriColorChooser.addRecentColor(c); 299 } 300 } 301 302 public Color getForeground() { 303 return _textComponent.getForeground(); 304 } 305 306 public void setBackgroundColor(Color color) { 307 if (color == null || color.getAlpha() == 0) { 308 setHasBackground(false); 309 _textComponent.setBackground(color); // retain the passed color 310 // which may not be null 311 } else { 312 setHasBackground(true); 313 _textComponent.setBackground(color); 314 _parent.setBackground(color); 315 _parent.setOpaque(true); 316 if (!_suppressRecentColor) { 317 JmriColorChooser.addRecentColor(color); 318 } 319 } 320 if (hasBackground()) { 321 setMargin(margin); //This rebuilds margin and sets it colour. 322 } 323 _parent.updateSize(); 324 } 325 326 public void setSuppressRecentColor(boolean b) { 327 _suppressRecentColor = b; 328 } 329 330 public void setHasBackground(boolean set) { 331 _hasBackground = set; 332 if (_textComponent instanceof PositionableJPanel) { 333 _textComponent.setOpaque(_hasBackground); 334 } 335 if (!_hasBackground) { 336 _parent.setOpaque(false); 337 _textComponent.setOpaque(false); 338 } 339 } 340 341 public boolean hasBackground() { 342 return _hasBackground; 343 } 344 345 public Color getBackground() { 346 Color c = _textComponent.getBackground(); 347 if (c==null) { 348 c = Color.WHITE; 349 } 350 if (!_hasBackground) { 351 // make sure the alpha value is set to 0 352 c = jmri.util.ColorUtil.setAlpha(c,0); 353 } 354 return c; 355 } 356 357 protected JMenu makeFontMenu() { 358 JMenu fontMenu = new JMenu("Font"); // create font menu 359 //fontMenu.setMnemonic('n'); // set mnemonic to n 360 361 // get the current font family name 362 String defaultFontFamilyName = _textComponent.getFont().getFamily(); 363 364 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 365 String[] fontFamilyNames = ge.getAvailableFontFamilyNames(); 366 367 // create radiobutton menu items for font names 368 ButtonGroup fontButtonGroup = new ButtonGroup(); // manages font names 369 370 // create Font radio button menu items 371 for (String fontFamilyName : fontFamilyNames) { 372 // create its menu item 373 JCheckBoxMenuItem fontMenuItem = new JCheckBoxMenuItem(fontFamilyName); 374 Font menuFont = fontMenuItem.getFont(); 375 menuFont = new Font(fontFamilyName, menuFont.getStyle(), menuFont.getSize()); 376 fontMenuItem.setFont(menuFont); 377 378 // set its action listener 379 fontMenuItem.addActionListener((ActionEvent e) -> { 380 Font oldFont = _textComponent.getFont(); 381 Font newFont = new Font(fontFamilyName, oldFont.getStyle(), oldFont.getSize()); 382 if (!oldFont.equals(newFont)) { 383 setFont(newFont); 384 } 385 }); 386 387 // add to button group 388 fontButtonGroup.add(fontMenuItem); 389 // set (de)selected 390 fontMenuItem.setSelected(defaultFontFamilyName.equals(fontFamilyName)); 391 // add to font menu 392 fontMenu.add(fontMenuItem); 393 } 394 395 MenuScroller.setScrollerFor(fontMenu, 36); 396 397 return fontMenu; 398 } 399 400 protected JMenu makeFontSizeMenu() { 401 JMenu sizeMenu = new JMenu("Font Size"); 402 ButtonGroup buttonGrp = new ButtonGroup(); 403 addFontSizeMenuEntry(sizeMenu, buttonGrp, 6); 404 addFontSizeMenuEntry(sizeMenu, buttonGrp, 8); 405 addFontSizeMenuEntry(sizeMenu, buttonGrp, 10); 406 addFontSizeMenuEntry(sizeMenu, buttonGrp, 11); 407 addFontSizeMenuEntry(sizeMenu, buttonGrp, 12); 408 addFontSizeMenuEntry(sizeMenu, buttonGrp, 14); 409 addFontSizeMenuEntry(sizeMenu, buttonGrp, 16); 410 addFontSizeMenuEntry(sizeMenu, buttonGrp, 18); 411 addFontSizeMenuEntry(sizeMenu, buttonGrp, 20); 412 addFontSizeMenuEntry(sizeMenu, buttonGrp, 24); 413 addFontSizeMenuEntry(sizeMenu, buttonGrp, 28); 414 addFontSizeMenuEntry(sizeMenu, buttonGrp, 32); 415 addFontSizeMenuEntry(sizeMenu, buttonGrp, 36); 416 return sizeMenu; 417 } 418 419 void addFontSizeMenuEntry(JMenu menu, ButtonGroup fontButtonGroup, final int size) { 420 JRadioButtonMenuItem r = new JRadioButtonMenuItem("" + size); 421 r.addActionListener((ActionEvent e) -> setFontSize(size)); 422 fontButtonGroup.add(r); 423 r.setSelected(_textComponent.getFont().getSize() == size); 424 menu.add(r); 425 } 426 427 public void setFont(Font font) { 428 Font oldFont = _textComponent.getFont(); 429 Font newFont = new Font(font.getFamily(), oldFont.getStyle(), oldFont.getSize()); 430 if (!oldFont.equals(newFont)) { 431 _textComponent.setFont(newFont); 432 _parent.updateSize(); 433 _parent.getEditor().setAttributes(_self, _parent); 434 } 435 } 436 437 public Font getFont() { 438 return _textComponent.getFont(); 439 } 440 441 public void setFontSize(float newSize) { 442 _textComponent.setFont(_textComponent.getFont().deriveFont(newSize)); 443 _parent.updateSize(); 444 ///_parent.getEditor().setAttributes(_self, _parent); 445 } 446 447 public int getFontSize() { 448 return _textComponent.getFont().getSize(); 449 } 450 451 void setItalic() { 452 log.debug("When style item selected italic state is {}", italic.isSelected()); 453 if (italic.isSelected()) { 454 setFontStyle(Font.ITALIC, 0); 455 } else { 456 setFontStyle(0, Font.ITALIC); 457 } 458 } 459 460 void setBold() { 461 log.debug("When style item selected bold state is {}", bold.isSelected()); 462 if (bold.isSelected()) { 463 setFontStyle(Font.BOLD, 0); 464 } else { 465 setFontStyle(0, Font.BOLD); 466 } 467 } 468 469 protected JMenu makeFontStyleMenu() { 470 JMenu styleMenu = new JMenu(Bundle.getMessage("FontStyle")); 471 styleMenu.add(italic = newStyleMenuItem(new AbstractAction(Bundle.getMessage("Italic")) { 472 @Override 473 public void actionPerformed(ActionEvent e) { 474 if (log.isDebugEnabled()) { // Avoid action lookup unless needed 475 log.debug("When style item selected {} italic state is {}", getValue(NAME), italic.isSelected()); 476 } 477 if (italic.isSelected()) { 478 setFontStyle(Font.ITALIC, 0); 479 } else { 480 setFontStyle(0, Font.ITALIC); 481 } 482 } 483 }, Font.ITALIC)); 484 485 styleMenu.add(bold = newStyleMenuItem(new AbstractAction(Bundle.getMessage("Bold")) { 486 @Override 487 public void actionPerformed(ActionEvent e) { 488 if (log.isDebugEnabled()) { // Avoid action lookup unless needed 489 log.debug("When style item selected {} bold state is {}", 490 getValue(NAME), bold.isSelected()); 491 } 492 if (bold.isSelected()) { 493 setFontStyle(Font.BOLD, 0); 494 } else { 495 setFontStyle(0, Font.BOLD); 496 } 497 } 498 }, Font.BOLD)); 499 return styleMenu; 500 } 501 502 public void setFontStyle(int style) { 503 _textComponent.setFont(_textComponent.getFont().deriveFont(style)); 504 _parent.updateSize(); 505 } 506 507 public void setFontStyle(int addStyle, int dropStyle) { 508 int styleValue = (getFontStyle() & ~dropStyle) | addStyle; 509 log.debug("setFontStyle: addStyle={}, dropStyle={}, net styleValue is {}", addStyle, dropStyle, styleValue); 510 if (bold != null) { 511 bold.setSelected((styleValue & Font.BOLD) != 0); 512 } 513 if (italic != null) { 514 italic.setSelected((styleValue & Font.ITALIC) != 0); 515 } 516 _textComponent.setFont(_textComponent.getFont().deriveFont(styleValue)); 517 518 //setSize(getPreferredSize().width, getPreferredSize().height); 519 _parent.updateSize(); 520 } 521 522 public int getFontStyle() { 523 return _textComponent.getFont().getStyle(); 524 } 525 526 protected JMenuItem newStyleMenuItem(AbstractAction a, int mask) { 527 // next two lines needed because JCheckBoxMenuItem(AbstractAction) not in 1.1.8 528 JCheckBoxMenuItem c = new JCheckBoxMenuItem((String) a.getValue(AbstractAction.NAME)); 529 c.addActionListener(a); 530 if (log.isDebugEnabled()) { // Avoid action lookup unless needed 531 log.debug("When creating style item {} mask was {} state was {}", 532 a.getValue(AbstractAction.NAME), mask, getFontStyle()); 533 } 534 if ((mask & getFontStyle()) == mask) { 535 c.setSelected(true); 536 } 537 return c; 538 } 539 540 public void copyItem(JPopupMenu popup) { 541 JMenuItem edit = new JMenuItem("Copy"); 542 edit.addActionListener((ActionEvent e) -> _parent.getEditor().copyItem(_parent)); 543 popup.add(edit); 544 } 545 546 /* 547 * ************* Justification *********************** 548 */ 549 public void setTextJustificationMenu(JPopupMenu popup) { 550 JMenu justMenu = new JMenu(Bundle.getMessage("Justification")); 551 addJustificationMenuEntry(justMenu, LEFT); 552 addJustificationMenuEntry(justMenu, RIGHT); 553 addJustificationMenuEntry(justMenu, CENTRE); 554 popup.add(justMenu); 555 } 556 557 static public final int LEFT = 0x00; 558 static public final int RIGHT = 0x02; 559 static public final int CENTRE = 0x04; 560 561 private int justification = CENTRE; //Default is always Centre 562 563 public void setJustification(int just) { 564 log.debug("setJustification: justification={}", just); 565 justification = just; 566 setHorizontalAlignment(justification); 567 _parent.updateSize(); 568 } 569 570 public void setJustification(String just) { 571 log.debug("setJustification: justification ={}", just); 572 switch (just) { 573 case "right": 574 justification = RIGHT; 575 break; 576 case "center": 577 case "centre": 578 // allow US or UK spellings 579 justification = CENTRE; 580 break; 581 default: 582 justification = LEFT; 583 break; 584 } 585 setHorizontalAlignment(justification); 586 _parent.updateSize(); 587 } 588 589 public int getJustification() { 590 log.debug("getJustification: justification ={}", justification); 591 return justification; 592 } 593 594 void addJustificationMenuEntry(JMenu menu, final int just) { 595 ButtonGroup justButtonGroup = new ButtonGroup(); 596 JRadioButtonMenuItem r; 597 switch (just) { 598 case RIGHT: 599 r = new JRadioButtonMenuItem(Bundle.getMessage("right")); 600 break; 601 case CENTRE: 602 r = new JRadioButtonMenuItem(Bundle.getMessage("center")); 603 break; 604 case LEFT: 605 default: 606 r = new JRadioButtonMenuItem(Bundle.getMessage("left")); 607 } 608 r.addActionListener((ActionEvent e) -> setJustification(just) //final int justification = just; 609 ); 610 justButtonGroup.add(r); 611 if (justification == just) { 612 r.setSelected(true); 613 } else { 614 r.setSelected(false); 615 } 616 menu.add(r); 617 } 618 619 public void setHorizontalAlignment(int alignment) { 620 if (_textType == LABEL) { 621 switch (alignment) { 622 case LEFT: 623 ((JLabel) _textComponent).setHorizontalAlignment(JLabel.LEFT); 624 break; 625 case RIGHT: 626 ((JLabel) _textComponent).setHorizontalAlignment(JLabel.RIGHT); 627 break; 628 case CENTRE: 629 default: 630 ((JLabel) _textComponent).setHorizontalAlignment(JLabel.CENTER); 631 } 632 } else if (_textType == TEXTFIELD) { 633 switch (alignment) { 634 case LEFT: 635 ((JTextField) _textComponent).setHorizontalAlignment(JTextField.LEFT); 636 break; 637 case RIGHT: 638 ((JTextField) _textComponent).setHorizontalAlignment(JTextField.RIGHT); 639 break; 640 case CENTRE: 641 default: 642 ((JTextField) _textComponent).setHorizontalAlignment(JTextField.CENTER); 643 } 644 } 645 } 646 647 public String getText() { 648 if (_textType == LABEL) { 649 return ((JLabel) _textComponent).getText(); 650 } else if (_textType == TEXTFIELD) { 651 return ((JTextField) _textComponent).getText(); 652 } 653 return null; 654 } 655 656 public final static int HORIZONTAL = 0x00; 657 public final static int VERTICAL_UP = 0x01; 658 public final static int VERTICAL_DOWN = 0x02; 659 660 private int orientation = HORIZONTAL; 661 662 public int getOrientation() { 663 return orientation; 664 } 665 666 public void setOrientation(int ori) { 667 orientation = ori; 668 _parent.updateSize(); 669 } 670 671 public void setOrientation(String ori) { 672 switch (ori) { 673 case "vertical_up": 674 setOrientation(VERTICAL_UP); 675 break; 676 case "vertical_down": 677 setOrientation(VERTICAL_DOWN); 678 break; 679 default: 680 setOrientation(HORIZONTAL); 681 break; 682 } 683 } 684 685 public void setTextOrientationMenu(JPopupMenu popup) { 686 JMenu oriMenu = new JMenu(Bundle.getMessage("Orientation")); 687 addOrientationMenuEntry(oriMenu, HORIZONTAL); 688 addOrientationMenuEntry(oriMenu, VERTICAL_UP); 689 addOrientationMenuEntry(oriMenu, VERTICAL_DOWN); 690 popup.add(oriMenu); 691 } 692 693 void addOrientationMenuEntry(JMenu menu, final int ori) { 694 ButtonGroup justButtonGroup = new ButtonGroup(); 695 JRadioButtonMenuItem r; 696 switch (ori) { 697 default: 698 case HORIZONTAL: 699 r = new JRadioButtonMenuItem("Horizontal"); 700 break; 701 case VERTICAL_UP: 702 r = new JRadioButtonMenuItem("Vertical Up"); 703 break; 704 case VERTICAL_DOWN: 705 r = new JRadioButtonMenuItem("Vertical Down"); 706 break; 707 } 708 r.addActionListener((ActionEvent e) -> setOrientation(ori)); 709 justButtonGroup.add(r); 710 if (orientation == ori) { 711 r.setSelected(true); 712 } else { 713 r.setSelected(false); 714 } 715 menu.add(r); 716 } 717 718 ArrayList<JMenuItem> editAdditionalMenu = new ArrayList<>(0); 719 ArrayList<JMenuItem> viewAdditionalMenu = new ArrayList<>(0); 720 721 /** 722 * Add a menu item to be displayed when the popup menu is called for when in 723 * edit mode. 724 * 725 * @param menu the item to add 726 */ 727 public void addEditPopUpMenu(JMenuItem menu) { 728 if (!editAdditionalMenu.contains(menu)) { 729 editAdditionalMenu.add(menu); 730 } 731 } 732 733 /** 734 * Add a menu item to be displayed when the popup menu is called for when in 735 * view mode. 736 * 737 * @param menu menu item or submenu to add 738 */ 739 public void addViewPopUpMenu(JMenuItem menu) { 740 if (!viewAdditionalMenu.contains(menu)) { 741 viewAdditionalMenu.add(menu); 742 } 743 } 744 745 /** 746 * Add the menu items to the edit popup menu 747 * 748 * @param popup the menu to add items to 749 */ 750 public void setAdditionalEditPopUpMenu(JPopupMenu popup) { 751 if (editAdditionalMenu.isEmpty()) { 752 return; 753 } 754 popup.addSeparator(); 755 editAdditionalMenu.forEach(popup::add); 756 } 757 758 /** 759 * Add the menu items to the view popup menu. 760 * 761 * @param popup the menu to add items to 762 */ 763 public void setAdditionalViewPopUpMenu(JPopupMenu popup) { 764 if (viewAdditionalMenu.isEmpty()) { 765 return; 766 } 767 viewAdditionalMenu.forEach(popup::add); 768 } 769 770 private final static Logger log = LoggerFactory.getLogger(PositionablePopupUtil.class); 771}