2016-04-01 11 views
1

Ich muss den Weg finden, um mehrere Aktionen innerhalb einer anderen Aktion wie Netbeans mit Run Main Project Symbol zu zeigen.Aktionen innerhalb einer anderen Aktion wie Netbeans

Sie können sehen, es gibt eine Standardaktion Run Main Project und wenn Sie in den kleinen Pfeil neben dem grünen Play-Symbol klicken, können Sie eine bestimmte Aktion wie Run auswählen.

Ich habe den Code von Netbeans überprüft, aber ich kann den Code nicht finden, um dies in meiner Anwendung zu machen.

+0

Sie suchen nach einer Split-Taste – MadProgrammer

Antwort

1

Ah, (einer der) heiligen Grals von UI-Komponenten, eine Split-Taste. Über eine Reihe von Jahren habe ich versucht, eine zu finden, die unter vielfachen Looks gut funktioniert und sich kläglich verschlechtert.

Viele Gebraucht mehrere Schaltflächen oder einfach nur mit einem JComboBox Zuflucht

Wie viele Dinge, ich über stolperte, die ziemlich gut gemacht wurde, aber ich was ich meine Bedürfnisse ändern musste passen leider I don‘ Erinnere dich an die Originalversion oder den Autor. (Wenn Sie dieser Code glauben auf Sie basieren, bitte einen Kommentar mit einem Link zum Original verlassen, und ich werde bewerten und ein angemessenen Kredit)

SplitButton

Grundsätzlich, wenn Sie auf die Schaltfläche klicken, es läuft sonst die „default“ Aktion (Bananen) können Sie eines der Unterelemente auswählen und es wird es

public class SplitButton extends JButton { 

    private int separatorSpacing = 4; 
    private int splitWidth = 22; 
    private int arrowSize = 8; 
    private boolean onSplit; 
    private Rectangle splitRectangle; 
    private JFrame popupMenu; 
    private boolean alwaysDropDown; 
    private Color arrowColor = Color.BLACK; 
    private Color disabledArrowColor = Color.GRAY; 
    private Image image; 
    private MouseHandler mouseHandler; 
    private boolean toolBarButton; 

    private PopupWindowEventHandler popupWindowEventHandler; 

    /** 
    * Creates a button with initial text and an icon. 
    * 
    * @param text the text of the button 
    * @param icon the Icon image to display on the button 
    */ 
    public SplitButton() { 
     super(); 
     addMouseMotionListener(getMouseHandler()); 
     addMouseListener(getMouseHandler()); 
     // Default for no "default" action... 
     setAlwaysDropDown(true); 

     InputMap im = getInputMap(WHEN_FOCUSED); 
     ActionMap am = getActionMap(); 

     im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "PopupMenu.close"); 
     am.put("PopupMenu.close", new ClosePopupAction()); 

    } 

    public SplitButton(Action defaultAction, Action... actions) { 
     this(); 
     setAction(defaultAction); 
     for (Action action : actions) { 
      addAction(action); 
     } 
    } 

    public SplitButton(String text, Icon icon, Action... actions) { 
     this((Action) null, actions); 
     setText(text); 
     setIcon(icon); 
    } 

    public SplitButton(String text, Action... actions) { 
     this((Action) null, actions); 
     setText(text); 
    } 

    public JSplitButton(Icon icon, Action... actions) { 
     this((Action) null, actions); 
     setIcon(icon); 
    } 

    @Override 
    public void setAction(Action a) { 
     super.setAction(a); 
     if (a != null) { 
      setAlwaysDropDown(false); 
     } 
    } 

    /** 
    * Creates a pre-configured button suitable for being used on a JToolBar 
    * 
    * @param defaultAction 
    * @param actions 
    * @return 
    */ 
    public static SplitButton createToolBarButton(Action defaultAction, Action... actions) { 
     JSplitButton btn = new JSplitButton(defaultAction, actions); 
     btn.configureForToolBar(); 
     return btn; 
    } 

    /** 
    * Creates a pre-configured "options only" button suitable for being used on 
    * a JToolBar 
    * 
    * @param text 
    * @param icon 
    * @param actions 
    * @return 
    */ 
    public static SplitButton createToolBarButton(String text, Icon icon, Action... actions) { 
     JSplitButton btn = new JSplitButton(icon, actions); 
     btn.setToolTipText(text); 
     btn.configureForToolBar(); 
     return btn; 
    } 

    /** 
    * Used to determine if the button is begin configured for use on a tool bar 
    * 
    * @return 
    */ 
    public boolean isToolBarButton() { 
     return toolBarButton; 
    } 

    /** 
    * Configures this button for use on a tool bar... 
    */ 
    public void configureForToolBar() { 
     toolBarButton = true; 
     if (getIcon() != null) { 
      setHideActionText(true); 
     } 
     setHorizontalTextPosition(JButton.CENTER); 
     setVerticalTextPosition(JButton.BOTTOM); 
     setFocusable(false); 
    } 

    protected MouseHandler getMouseHandler() { 
     if (mouseHandler == null) { 
      mouseHandler = new MouseHandler(); 
     } 
     return mouseHandler; 
    } 

    protected AbstractButton getButtonFor(Action action) { 
     Container parent = ((JFrame) getPopupWindow()).getContentPane(); 
     AbstractButton btn = null; 
     for (Component comp : parent.getComponents()) { 
      if (comp instanceof AbstractButton) { 
       Action childAction = ((AbstractButton) comp).getAction(); 
       if (action.equals(childAction)) { 
        btn = (AbstractButton) comp; 
        break; 
       } 
      } 
     } 

     return btn; 
    } 

    /** 
    * Returns the index of the specified action within the popup window or -1 
    * of it does not exist 
    * 
    * @param action 
    * @return 
    */ 
    public int indexOfAction(Action action) { 
     Container parent = ((JFrame) getPopupWindow()).getContentPane(); 
     AbstractButton btn = getButtonFor(action); 

     return btn == null ? -1 : parent.getComponentZOrder(btn); 
    } 

    /** 
    * Adds the specified action to the popup menu... 
    * 
    * This simply calls getPopupWindow().add(action) 
    * 
    * @param action Add 
    */ 
    public void addAction(Action action) { 
     addActionAt(action, -1); 
    } 

    protected int getOptionsCount() { 
     return ((JFrame) getPopupWindow()).getContentPane().getComponentCount(); 
    } 

    protected void addActionAt(Action action, int index) { 
     if (index < 0 || index >= getOptionsCount()) { 
      getPopupWindow().add(createMenuItem(action)); 
     } else { 
      getPopupWindow().add(createMenuItem(action), index); 
     } 
    } 

    protected void removeAction(Action action) { 
     AbstractButton btn = getButtonFor(action); 
     if (btn != null) { 
      getPopupWindow().remove(btn); 
     } 
    } 

    /** 
    * Creates a new JMenuItem from the supplied Action. This is used to 
    * provided the ability for subclasses to either change the type of menu 
    * item used by the button or add additional functionality (like listeners) 
    * should they be required 
    * 
    * @param action 
    * @return 
    */ 
    protected JMenuItem createMenuItem(Action action) { 
     return new JMenuItem(action); 
    } 

    @Override 
    public Insets getInsets() { 
     Insets insets = (Insets) super.getInsets().clone(); 
     insets.right += splitWidth; 
     return insets; 
    } 

    @Override 
    public Insets getInsets(Insets insets) { 
     Insets insets1 = getInsets(); 
     insets.left = insets1.left; 
     insets.right = insets1.right; 
     insets.bottom = insets1.bottom; 
     insets.top = insets1.top; 
     return insets1; 
    } 

    /** 
    * Returns the window that acts as the buttons popup window 
    * 
    * @return 
    */ 
    public Window getPopupWindow() { 
     if (popupMenu == null) { 
      popupMenu = new JFrame(); 
      popupMenu.setFocusableWindowState(false); 
      popupMenu.setUndecorated(true); 
      popupMenu.setContentPane(createPopupWindowContentPane()); 
      popupMenu.setAlwaysOnTop(true); 
      DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(new PropertyChangeListener() { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) { 
        String name = evt.getPropertyName(); 
        if ("focusOwner".equalsIgnoreCase(name) 
          || "permanentFocusOwner".equalsIgnoreCase(name) 
          || "focusedWindow".equalsIgnoreCase(name) 
          || "activeWindow".equalsIgnoreCase(name)) { 
         Window focusedWindow = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); 
         if (!popupMenu.equals(focusedWindow)) { 
          closePopupWinodw(); 
         } 
        } 
       } 
      }); 
     } 
     return popupMenu; 
    } 

    protected Container createPopupWindowContentPane() { 
     return new DefaultMenuPane(); 
    } 

    protected void closePopupWinodw() { 
     getPopupWindow().setVisible(false); 
     if (popupWindowEventHandler != null) { 
      Toolkit.getDefaultToolkit().removeAWTEventListener(popupWindowEventHandler); 
     } 
    } 

    protected void showPopupWindow() { 
     Window popup = getPopupWindow(); 
     popup.pack(); 
     Point pos = getLocationOnScreen(); 
     popup.setLocation(pos.x + (getWidth() - popup.getWidth()), pos.y + getHeight()); 
     popup.setVisible(true); 

     if (popupWindowEventHandler == null) { 
      popupWindowEventHandler = new PopupWindowEventHandler(); 
     } 
     Toolkit.getDefaultToolkit().addAWTEventListener(popupWindowEventHandler, AWTEvent.MOUSE_EVENT_MASK); 
    } 

    /** 
    * Returns the separatorSpacing. Separator spacing is the space above and 
    * below the separator(the line drawn when you hover your mouse over the 
    * split part of the button). 
    * 
    * @return separatorSpacingimage = null; //to repaint the image with the new 
    * size 
    */ 
    public int getSeparatorSpacing() { 
     return separatorSpacing; 
    } 

    /** 
    * Sets the separatorSpacing.Separator spacing is the space above and below 
    * the separator(the line drawn when you hover your mouse over the split 
    * part of the button). 
    * 
    * @param spacing 
    */ 
    public void setSeparatorSpacing(int spacing) { 
     if (spacing != separatorSpacing && spacing >= 0) { 
      int old = separatorSpacing; 
      this.separatorSpacing = spacing; 
      image = null; 
      firePropertyChange("separatorSpacing", old, separatorSpacing); 
      revalidate(); 
      repaint(); 
     } 
    } 

    /** 
    * Show the dropdown menu, if attached, even if the button part is clicked. 
    * 
    * @return true if alwaysDropdown, false otherwise. 
    */ 
    public boolean isAlwaysDropDown() { 
     return alwaysDropDown; 
    } 

    /** 
    * Show the dropdown menu, if attached, even if the button part is clicked. 
    * 
    * If true, this will prevent the button from raising any actionPerformed 
    * events for itself 
    * 
    * @param value true to show the attached dropdown even if the button part 
    * is clicked, false otherwise 
    */ 
    public void setAlwaysDropDown(boolean value) { 
     if (alwaysDropDown != value) { 
      this.alwaysDropDown = value; 
      firePropertyChange("alwaysDropDown", !alwaysDropDown, alwaysDropDown); 
     } 
    } 

    /** 
    * Gets the color of the arrow. 
    * 
    * @return arrowColor 
    */ 
    public Color getArrowColor() { 
     return arrowColor; 
    } 

    /** 
    * Set the arrow color. 
    * 
    * @param color 
    */ 
    public void setArrowColor(Color color) { 
     if (arrowColor != color) { 
      Color old = arrowColor; 
      this.arrowColor = color; 
      image = null; 
      firePropertyChange("arrowColor", old, arrowColor); 
      repaint(); 
     } 
    } 

    /** 
    * gets the disabled arrow color 
    * 
    * @return disabledArrowColor color of the arrow if no popup attached. 
    */ 
    public Color getDisabledArrowColor() { 
     return disabledArrowColor; 
    } 

    /** 
    * sets the disabled arrow color 
    * 
    * @param color color of the arrow if no popup attached. 
    */ 
    public void setDisabledArrowColor(Color color) { 
     if (disabledArrowColor != color) { 
      Color old = disabledArrowColor; 
      this.disabledArrowColor = color; 
      image = null; //to repaint the image with the new color 
      firePropertyChange("disabledArrowColor", old, disabledArrowColor); 
     } 
    } 

    /** 
    * Splitwidth is the width of the split part of the button. 
    * 
    * @return splitWidth 
    */ 
    public int getSplitWidth() { 
     return splitWidth; 
    } 

    /** 
    * Splitwidth is the width of the split part of the button. 
    * 
    * @param width 
    */ 
    public void setSplitWidth(int width) { 
     if (splitWidth != width) { 
      int old = splitWidth; 
      this.splitWidth = width; 
      firePropertyChange("splitWidth", old, splitWidth); 
      revalidate(); 
      repaint(); 
     } 
    } 

    /** 
    * gets the size of the arrow. 
    * 
    * @return size of the arrow 
    */ 
    public int getArrowSize() { 
     return arrowSize; 
    } 

    /** 
    * sets the size of the arrow 
    * 
    * @param size 
    */ 
    public void setArrowSize(int size) { 
     if (arrowSize != size) { 
      int old = arrowSize; 
      this.arrowSize = size; 
      image = null; //to repaint the image with the new size 
      firePropertyChange("setArrowSize", old, arrowSize); 
      revalidate(); 
      repaint(); 
     } 
    } 

    /** 
    * Gets the image to be drawn in the split part. If no is set, a new image 
    * is created with the triangle. 
    * 
    * @return image 
    */ 
    public Image getImage() { 
     if (image == null) { 
      Graphics2D g = null; 
      BufferedImage img = new BufferedImage(arrowSize, arrowSize, BufferedImage.TYPE_INT_RGB); 
      g = (Graphics2D) img.createGraphics(); 
      g.setColor(Color.WHITE); 
      g.fillRect(0, 0, img.getWidth(), img.getHeight()); 
      g.setColor(popupMenu != null ? arrowColor : disabledArrowColor); 
      //this creates a triangle facing right > 
      g.fillPolygon(new int[]{0, 0, arrowSize/2}, new int[]{0, arrowSize, arrowSize/2}, 3); 
      g.dispose(); 
      //rotate it to face downwards 
      img = rotate(img, 90); 
      BufferedImage dimg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); 
      g = (Graphics2D) dimg.createGraphics(); 
      g.setComposite(AlphaComposite.Src); 
      g.drawImage(img, null, 0, 0); 
      g.dispose(); 
      for (int i = 0; i < dimg.getHeight(); i++) { 
       for (int j = 0; j < dimg.getWidth(); j++) { 
        if (dimg.getRGB(j, i) == Color.WHITE.getRGB()) { 
         dimg.setRGB(j, i, 0x8F1C1C); 
        } 
       } 
      } 

      image = Toolkit.getDefaultToolkit().createImage(dimg.getSource()); 
     } 
     return image; 
    } 

    /** 
    * 
    * @param g 
    */ 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     //Graphics gClone = g.create();//EDIT: Hervé Guillaume 
     Color oldColor = g.getColor(); 
     splitRectangle = new Rectangle(getWidth() - splitWidth, 0, splitWidth, getHeight()); 
     g.translate(splitRectangle.x, splitRectangle.y); 
     int mh = getHeight()/2; 
     int mw = splitWidth/2; 
     g.drawImage(getImage(), mw - arrowSize/2, mh + 2 - arrowSize/2, null); 
     if (!alwaysDropDown) { 
      if (getModel().isRollover() || isFocusable()) { 
       g.setColor(UIManager.getLookAndFeelDefaults().getColor("Button.background")); 
       g.drawLine(1, separatorSpacing + 2, 1, getHeight() - separatorSpacing - 2); 
       g.setColor(UIManager.getLookAndFeelDefaults().getColor("Button.shadow")); 
       g.drawLine(2, separatorSpacing + 2, 2, getHeight() - separatorSpacing - 2); 
      } 
     } 
     g.setColor(oldColor); 
     g.translate(-splitRectangle.x, -splitRectangle.y); 
    } 

    /** 
    * Rotates the given image with the specified angle. 
    * 
    * @param img image to rotate 
    * @param angle angle of rotation 
    * @return rotated image 
    */ 
    private BufferedImage rotate(BufferedImage img, int angle) { 
     int w = img.getWidth(); 
     int h = img.getHeight(); 
     BufferedImage dimg = dimg = new BufferedImage(w, h, img.getType()); 
     Graphics2D g = dimg.createGraphics(); 
     g.rotate(Math.toRadians(angle), w/2, h/2); 
     g.drawImage(img, null, 0, 0); 
     return dimg; 
    } 

    @Override 
    protected void fireActionPerformed(ActionEvent event) { 
     // This is a little bit of a nasty trick. Basically this is where 
     // we try and decide if the buttons "default" action should 
     // be fired or not. We don't want it firing if the button 
     // is in "options only" mode or the user clicked on 
     // on the "drop down arrow".... 
     if (onSplit || isAlwaysDropDown()) { 
      showPopupWindow(); 
     } else { 
      super.fireActionPerformed(event); 

     } 
    } 

    protected class MouseHandler extends MouseAdapter { 

     @Override 
     public void mouseExited(MouseEvent e) { 
      onSplit = false; 
      repaint(splitRectangle); 
     } 

     @Override 
     public void mouseMoved(MouseEvent e) { 
      if (splitRectangle.contains(e.getPoint())) { 
       onSplit = true; 
      } else { 
       onSplit = false; 
      } 
      repaint(splitRectangle); 
     } 
    } 

    protected class PopupWindowEventHandler implements AWTEventListener { 

     @Override 
     public void eventDispatched(AWTEvent event) { 
      if (popupMenu.isVisible()) { 
       switch (event.getID()) { 
        case MouseEvent.MOUSE_RELEASED: 
         Object source = event.getSource(); 
         if (source instanceof Component) { 
          Window win = SwingUtilities.getWindowAncestor((Component) source); 
          if (!popupMenu.equals(win)) { 
           closePopupWinodw(); 
          } 
         } 
         break; 
       } 
      } 
     } 

    } 

    protected class ClosePopupAction extends AbstractAction { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      closePopupWinodw(); 
     } 

    } 

    protected class DefaultMenuPane extends JPanel { 

     public DefaultMenuPane() { 
      setBorder(UIManager.getBorder("PopupMenu.border")); 
      setBackground(UIManager.getColor("PopupMenu.background")); 
      setLayout(new GridLayout(0, 1)); 
     } 

    } 

} 

ausführen es so etwas wie konfiguriert werden würde ...

Und als Referenz, die Frucht Aktion sieht aus wie ...

public class FruitAction extends AbstractAction { 

    public FruitAction(String text, Icon icon) { 

     putValue(NAME, text); 
     putValue(SMALL_ICON, icon); 
     putValue(SHORT_DESCRIPTION, text); 

    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     JOptionPane.showMessageDialog(null, "I am " + getValue(NAME), "Fruit", JOptionPane.INFORMATION_MESSAGE); 

    } 

} 

Dies ist eine benutzerdefinierte Vektor-basierte Icon-Bibliothek verwenden, so offensichtlich, ich will nicht, dass einschließlich, aber es gibt Ihnen ein Idee, wie man es konfiguriert

+0

Danke. Kannst du das als Aktionen benutzen? Ich arbeite mit einem Netbeans-Projekt und erstelle keinen neuen SplitButton. Ich erstelle nur neue AWT-Aktionen und richte alles nach Tags ein. –

+0

Wenn Sie ActionListener meinen, dann nein, es wurde entwickelt, Action's – MadProgrammer

+0

zu verwenden Es ist gut, danke für die Antwort. Ich verwende ActionListener, um Aktionen in meinem Netbeans-Projekt auszuführen. –

Verwandte Themen