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